Author: fireball
Date: Fri Jan 7 20:50:13 2011
New Revision: 50313
URL:
http://svn.reactos.org/svn/reactos?rev=50313&view=rev
Log:
- Move windowing code to window.c.
- Add proper code structure for creating client windows too, and fix other places so they
would be ready for a newer window manager interface.
- Slightly cleanup file headers, and state that some code is based on Wine.
- Add some experimental event code, which is #if0ed for now.
Added:
branches/arwinss/reactos/dll/win32/winent.drv/event.c (with props)
Modified:
branches/arwinss/reactos/dll/win32/winent.drv/font.c
branches/arwinss/reactos/dll/win32/winent.drv/graphics.c
branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
branches/arwinss/reactos/dll/win32/winent.drv/window.c
branches/arwinss/reactos/dll/win32/winent.drv/winent.h
branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild
Added: branches/arwinss/reactos/dll/win32/winent.drv/event.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/event.c (added)
+++ branches/arwinss/reactos/dll/win32/winent.drv/event.c [iso-8859-1] Fri Jan 7 20:50:13
2011
@@ -1,0 +1,272 @@
+/*
+ * PROJECT: ReactOS
+ * LICENSE: GNU LGPL by FSF v2.1 or any later
+ * FILE: dll/win32/winent.drv/event.c
+ * PURPOSE: Event handling routines
+ * PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
+ * Some parts inspired by Wine's winex11.drv
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include "winent.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(event);
+#if 0
+/* GLOBALS ****************************************************************/
+
+static void NTDRV_Expose( HWND hwnd, GR_EVENT *event );
+
+struct event_handler
+{
+ GR_EVENT_TYPE type; /* event type */
+ ntdrv_event_handler handler; /* corresponding handler function */
+};
+
+#define MAX_EVENT_HANDLERS 64
+
+static struct event_handler handlers[MAX_EVENT_HANDLERS] =
+{
+ /* list must be sorted by event type */
+ //{ KeyPress, X11DRV_KeyEvent },
+ //{ KeyRelease, X11DRV_KeyEvent },
+ //{ ButtonPress, X11DRV_ButtonPress },
+ //{ ButtonRelease, X11DRV_ButtonRelease },
+ //{ MotionNotify, X11DRV_MotionNotify },
+ //{ EnterNotify, X11DRV_EnterNotify },
+ /* LeaveNotify */
+ //{ FocusIn, X11DRV_FocusIn },
+ //{ FocusOut, X11DRV_FocusOut },
+ //{ KeymapNotify, X11DRV_KeymapNotify },
+ { GR_EVENT_TYPE_EXPOSURE, NTDRV_Expose },
+ /* GraphicsExpose */
+ /* NoExpose */
+ /* VisibilityNotify */
+ /* CreateNotify */
+ //{ DestroyNotify, X11DRV_DestroyNotify },
+ /* UnmapNotify */
+ //{ MapNotify, X11DRV_MapNotify },
+ /* MapRequest */
+ //{ ReparentNotify, X11DRV_ReparentNotify },
+ //{ ConfigureNotify, X11DRV_ConfigureNotify },
+ /* ConfigureRequest */
+ //{ GravityNotify, X11DRV_GravityNotify },
+ /* ResizeRequest */
+ /* CirculateNotify */
+ /* CirculateRequest */
+ //{ PropertyNotify, X11DRV_PropertyNotify },
+ //{ SelectionClear, X11DRV_SelectionClear },
+ //{ SelectionRequest, X11DRV_SelectionRequest },
+ /* SelectionNotify */
+ /* ColormapNotify */
+ //{ ClientMessage, X11DRV_ClientMessage },
+ //{ MappingNotify, X11DRV_MappingNotify },
+};
+
+static int nb_event_handlers = 1; /* change this if you add handlers above */
+
+/* FUNCTIONS **************************************************************/
+
+/***********************************************************************
+ * find_handler
+ *
+ * Find the handler for a given event type. Caller must hold the x11 lock.
+ */
+static inline ntdrv_event_handler find_handler( GR_EVENT_TYPE type )
+{
+ int min = 0, max = nb_event_handlers - 1;
+
+ while (min <= max)
+ {
+ int pos = (min + max) / 2;
+ if (handlers[pos].type == type) return handlers[pos].handler;
+ if (handlers[pos].type > type) max = pos - 1;
+ else min = pos + 1;
+ }
+ return NULL;
+}
+
+enum event_merge_action
+{
+ MERGE_DISCARD, /* discard the old event */
+ MERGE_HANDLE, /* handle the old event */
+ MERGE_KEEP /* keep the old event for future merging */
+};
+
+/***********************************************************************
+ * merge_events
+ *
+ * Try to merge 2 consecutive events.
+ */
+#if 0
+static enum event_merge_action merge_events( GR_EVENT *prev, GR_EVENT *next )
+{
+ switch (prev->type)
+ {
+ case GR_UPDATE_MOVE:
+ switch (next->type)
+ {
+ case GR_UPDATE_MOVE:
+ if (prev->wid == next->wid)
+ {
+ TRACE( "discarding duplicate ConfigureNotify for window %lx\n",
prev->wid );
+ return MERGE_DISCARD;
+ }
+ break;
+ case GR_EVENT_MASK_EXPOSURE:
+ //case PropertyNotify:
+ return MERGE_KEEP;
+ }
+ break;
+ case GR_EVENT_MASK_MOUSE_MOTION:
+ if (prev->wid == next->wid && next->type == MotionNotify)
+ {
+ TRACE( "discarding duplicate MotionNotify for window %lx\n",
prev->wid );
+ return MERGE_DISCARD;
+ }xch
+ break;
+ }
+
+ return MERGE_HANDLE;
+}
+#endif
+
+
+/***********************************************************************
+ * call_event_handler
+ */
+static inline void call_event_handler( GR_EVENT *event )
+{
+ HWND hwnd;
+ ntdrv_event_handler handler;
+ //GR_EVENT *prev;
+ //struct ntdrv_thread_data *thread_data;
+
+ if (!(handler = find_handler( event->type )))
+ {
+ TRACE( "%s for win %lx, ignoring\n", "event", -1 );
+ return; /* no handler, ignore it */
+ }
+
+ hwnd = GrGetHwnd( event->general.wid );
+ //if (!hwnd && event->xany.window == root_window) hwnd =
GetDesktopWindow();
+
+ //TRACE( "%lu %s for hwnd/window %p/%lx\n",
+ // event->xany.serial, dbgstr_event( event->type ), hwnd,
event->xany.window );
+ //wine_tsx11_unlock();
+ //thread_data = ntdrv_thread_data();
+ //prev = thread_data->current_event;
+ //thread_data->current_event = event;
+ handler( hwnd, event );
+ //thread_data->current_event = prev;
+ //wine_tsx11_lock();
+}
+
+/***********************************************************************
+ * process_events
+ */
+static int process_events( int mask )
+{
+ GR_EVENT event;//, prev_event;
+ int count = 0;
+ //enum event_merge_action action = MERGE_DISCARD;
+
+ //prev_event.type = 0;
+ //wine_tsx11_lock();
+ while (GrPeekEvent(&event))
+ {
+ GrGetNextEvent(&event);
+ ERR("Got event type %d\n", event.type);
+ count++;
+#if 0
+ if (prev_event.type) action = merge_events( &prev_event, &event );
+ switch( action )
+ {
+ case MERGE_DISCARD: /* discard prev, keep new */
+ prev_event = event;
+ break;
+ case MERGE_HANDLE: /* handle prev, keep new */
+ call_event_handler( display, &prev_event );
+ prev_event = event;
+ break;
+ case MERGE_KEEP: /* handle new, keep prev for future merging */
+ call_event_handler( display, &event );
+ break;
+ }
+#else
+ call_event_handler( &event );
+#endif
+ }
+ //if (prev_event.type) call_event_handler( &prev_event );
+ //XFlush( gdi_display );
+ //wine_tsx11_unlock();
+ if (count) TRACE( "processed %d events\n", count );
+ return count;
+}
+#endif
+
+/***********************************************************************
+ * MsgWaitForMultipleObjectsEx (NTDRV.@)
+ */
+DWORD CDECL RosDrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD
timeout,
+ DWORD mask, DWORD flags )
+{
+ //TRACE("WaitForMultipleObjectsEx(%d %p %d %x %x %x\n", count, handles,
timeout, mask, flags);
+
+ if (!count && !timeout) return WAIT_TIMEOUT;
+ return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
+ timeout, flags & MWMO_ALERTABLE );
+}
+
+#if 0
+/***********************************************************************
+ * X11DRV_Expose
+ */
+static void NTDRV_Expose( HWND hwnd, GR_EVENT *xev )
+{
+ GR_EVENT_EXPOSURE *event = &xev->exposure;
+ RECT rect;
+ struct ntdrv_win_data *data;
+ int flags = RDW_INVALIDATE | RDW_ERASE;
+
+ ERR( "win %p (%lx) %d,%d %dx%d\n",
+ hwnd, event->wid, event->x, event->y, event->width,
event->height );
+
+ if (!(data = NTDRV_get_win_data( hwnd ))) return;
+
+ rect.left = event->x;
+ rect.top = event->y;
+ rect.right = event->x + event->width;
+ rect.bottom = event->y + event->height;
+ if (event->wid == data->whole_window)
+ {
+ OffsetRect( &rect, data->whole_rect.left - data->client_rect.left,
+ data->whole_rect.top - data->client_rect.top );
+ flags |= RDW_FRAME;
+ }
+
+ //if (event->wid != root_window)
+ {
+ if (GetWindowLongW( data->hwnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL)
+ mirror_rect( &data->client_rect, &rect );
+
+ SERVER_START_REQ( update_window_zorder )
+ {
+ req->window = wine_server_user_handle( hwnd );
+ req->rect.left = rect.left;
+ req->rect.top = rect.top;
+ req->rect.right = rect.right;
+ req->rect.bottom = rect.bottom;
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ flags |= RDW_ALLCHILDREN;
+ }
+ //else OffsetRect( &rect, virtual_screen_rect.left, virtual_screen_rect.top );
+
+ RedrawWindow( hwnd, &rect, 0, flags );
+}
+#endif
+/* EOF */
Propchange: branches/arwinss/reactos/dll/win32/winent.drv/event.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/arwinss/reactos/dll/win32/winent.drv/font.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/font.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/font.c [iso-8859-1] Fri Jan 7 20:50:13
2011
@@ -4,6 +4,7 @@
* FILE: dll/win32/winent.drv/font.c
* PURPOSE: Font Engine support functions
* PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
+ * Some code is taken from winex11.drv (c) Wine project
*/
/* INCLUDES ***************************************************************/
Modified: branches/arwinss/reactos/dll/win32/winent.drv/graphics.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/graphics.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/graphics.c [iso-8859-1] Fri Jan 7
20:50:13 2011
@@ -4,6 +4,7 @@
* FILE: dll/win32/winent.drv/graphics.c
* PURPOSE: GDI high-level driver for ReactOS/Windows
* PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
+ * Some code is taken from winex11.drv (c) Wine project
*/
/* INCLUDES ***************************************************************/
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Fri Jan 7
20:50:13 2011
@@ -14,61 +14,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(rosuserdrv);
/* FUNCTIONS **************************************************************/
-
-/***********************************************************************
- * move_window_bits
- *
- * Move the window bits when a window is moved.
- */
-void move_window_bits( struct ntdrv_win_data *data, const RECT *old_rect, const RECT
*new_rect,
- const RECT *old_client_rect )
-{
- RECT src_rect = *old_rect;
- RECT dst_rect = *new_rect;
- HDC hdc_src, hdc_dst;
- HRGN rgn = 0;
- HWND parent = 0;
-
- if (!data->whole_window)
- {
- OffsetRect( &dst_rect, -data->window_rect.left, -data->window_rect.top
);
- parent = GetAncestor( data->hwnd, GA_PARENT );
- hdc_src = GetDCEx( parent, 0, DCX_CACHE );
- hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE | DCX_WINDOW );
- }
- else
- {
- OffsetRect( &dst_rect, -data->client_rect.left, -data->client_rect.top
);
- /* make src rect relative to the old position of the window */
- OffsetRect( &src_rect, -old_client_rect->left, -old_client_rect->top
);
- if (dst_rect.left == src_rect.left && dst_rect.top == src_rect.top)
return;
- hdc_src = hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE );
- }
-
- TRACE( "copying bits for win %p (parent %p)/ %s -> %s\n",
- data->hwnd, parent,
- wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) );
- BitBlt( hdc_dst, dst_rect.left, dst_rect.top,
- dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top,
- hdc_src, src_rect.left, src_rect.top, SRCCOPY );
-
- ReleaseDC( data->hwnd, hdc_dst );
- if (hdc_src != hdc_dst) ReleaseDC( parent, hdc_src );
-
- if (rgn)
- {
- if (!data->whole_window)
- {
- /* map region to client rect since we are using DCX_WINDOW */
- OffsetRgn( rgn, data->window_rect.left - data->client_rect.left,
- data->window_rect.top - data->client_rect.top );
- RedrawWindow( data->hwnd, NULL, rgn,
- RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN );
- }
- else RedrawWindow( data->hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE |
RDW_ALLCHILDREN );
- DeleteObject( rgn );
- }
-}
HKL CDECL RosDrv_ActivateKeyboardLayout( HKL layout, UINT flags )
{
@@ -283,180 +228,10 @@
return RosUserGetMonitorInfo(handle, info);
}
-BOOL CDECL RosDrv_CreateDesktopWindow( HWND hwnd )
-{
- unsigned int width, height;
-
- /* retrieve the real size of the desktop */
- SERVER_START_REQ( get_window_rectangles )
- {
- req->handle = wine_server_user_handle( hwnd );
- wine_server_call( req );
- width = reply->window.right - reply->window.left;
- height = reply->window.bottom - reply->window.top;
- }
- SERVER_END_REQ;
-
- TRACE("RosDrv_CreateDesktopWindow(%x), w %d h %d\n", hwnd, width, height);
-
- SwmAddDesktopWindow(hwnd, width, height);
-
- if (!width && !height) /* not initialized yet */
- {
- SERVER_START_REQ( set_window_pos )
- {
- req->handle = wine_server_user_handle( hwnd );
- req->previous = 0;
- req->flags = SWP_NOZORDER;
- req->window.left = 0;
- req->window.top = 0;
- req->window.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
- req->window.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
- req->client = req->window;
- wine_server_call( req );
- }
- SERVER_END_REQ;
- }
-
- return TRUE;
-}
-
-BOOL CDECL RosDrv_CreateWindow( HWND hwnd )
-{
- WARN("RosDrv_CreateWindow(%x)\n", hwnd);
-
- if (hwnd == GetDesktopWindow())
- {
- /* create desktop win data */
- if (!NTDRV_create_desktop_win_data( hwnd )) return FALSE;
- }
-
- return TRUE;
-}
-
void CDECL RosDrv_DestroyWindow( HWND hwnd )
{
/* Destroy its window data */
NTDRV_destroy_win_data( hwnd );
-}
-
-void CDECL RosDrv_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
- const RECT *top_rect, DWORD flags )
-{
- struct ntdrv_escape_set_drawable escape;
- struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
- //HWND parent;
-
- escape.code = NTDRV_SET_DRAWABLE;
- escape.clip_children = FALSE;
- escape.gl_copy = FALSE;
- escape.hwnd = 0;
- escape.release = FALSE;
-
- escape.dc_rect.left = win_rect->left - top_rect->left;
- escape.dc_rect.top = win_rect->top - top_rect->top;
- escape.dc_rect.right = win_rect->right - top_rect->left;
- escape.dc_rect.bottom = win_rect->bottom - top_rect->top;
- escape.drawable_rect.left = top_rect->left;
- escape.drawable_rect.top = top_rect->top;
- escape.drawable_rect.right = top_rect->right;
- escape.drawable_rect.bottom = top_rect->bottom;
-
- if (top == hwnd)
- {
- //if (flags & DCX_WINDOW)
- {
- if (data)
- {
- /* SWM window already exists */
- escape.hwnd = hwnd;
- }
- else
- {
- /* There is no SWM window for this hwnd.
- If this is desktop, it's fine otherwise reject any drawing
operations */
- if (hwnd == GetDesktopWindow())
- escape.hwnd = hwnd;
- else
- escape.hwnd = 0;
- }
- }
- }
- else
- {
-#if 0
- /* find the first ancestor that has a drawable */
- if (data) escape.hwnd = hwnd;
-
- for (parent = hwnd; parent && parent != top; parent = GetAncestor(
parent, GA_PARENT ))
- {
- data = NTDRV_get_win_data( parent );
- if (data)
- {
- escape.hwnd = parent;
- break;
- }
- }
-FIXME("Found hwnd %x backed by an SWM window\n", escape.hwnd);
- if (escape.hwnd)
- {
- POINT pt = { 0, 0 };
- MapWindowPoints( top, parent, &pt, 1 );
- //OffsetRect( &escape.dc_rect, pt.x, pt.y );
- //OffsetRect( &escape.drawable_rect, -pt.x, -pt.y );
-
- FIXME("Offset by (%d, %d)\n", pt.x, pt.y);
- }
- else
- {
- if (NTDRV_get_win_data(top) || (top == GetDesktopWindow()))
- {
- /* SWM window already exists */
- escape.hwnd = top;
- }
- }
-#else
- escape.hwnd = GetAncestor(hwnd, GA_ROOT);
-#endif
-
- if (flags & DCX_CLIPCHILDREN) escape.clip_children = TRUE;
- }
-
- TRACE("hdc %x, hwnd %x, top %x\n win_rect %s, top_rect %s\n", hdc, hwnd,
top,
- wine_dbgstr_rect(win_rect), wine_dbgstr_rect(top_rect));
-
- ExtEscape( hdc, NTDRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
-}
-
-DWORD CDECL RosDrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD
timeout,
- DWORD mask, DWORD flags )
-{
- //TRACE("WaitForMultipleObjectsEx(%d %p %d %x %x %x\n", count, handles,
timeout, mask, flags);
-
- if (!count && !timeout) return WAIT_TIMEOUT;
- return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
- timeout, flags & MWMO_ALERTABLE );
-}
-
-void CDECL RosDrv_ReleaseDC( HWND hwnd, HDC hdc )
-{
- struct ntdrv_escape_set_drawable escape;
-
- escape.code = NTDRV_SET_DRAWABLE;
- escape.gl_copy = FALSE;
- escape.hwnd = hwnd;
- escape.release = TRUE;
-
- escape.dc_rect.left = 0;
- escape.dc_rect.top = 0;
- escape.dc_rect.right = 0;
- escape.dc_rect.bottom = 0;
- escape.drawable_rect.left = 0;
- escape.drawable_rect.top = 0;
- escape.drawable_rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
- escape.drawable_rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
-
- ExtEscape( hdc, NTDRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
}
/*
@@ -597,21 +372,6 @@
return TRUE;
}
-void CDECL RosDrv_SetCapture( HWND hwnd, UINT flags )
-{
- if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
-
- if (hwnd)
- {
- /* Capturing */
- TRACE("Capture set for hwnd %x\n", hwnd);
- }
- else
- {
- TRACE("Capture released\n");
- }
-}
-
/*******************************************************************
* can_activate_window
*
@@ -628,48 +388,9 @@
return !(style & WS_DISABLED);
}*/
-void CDECL RosDrv_SetFocus( HWND hwnd )
-{
- struct ntdrv_win_data *data;
-
- if (!(hwnd = GetAncestor( hwnd, GA_ROOT ))) return;
- if (!(data = NTDRV_get_win_data( hwnd ))) return;
- if (!data->whole_window) return;
-
- TRACE("SetFocus %x, desk %x\n", hwnd, GetDesktopWindow());
-
- /* Bring this window to foreground */
- SwmSetForeground(hwnd);
-}
-
void CDECL RosDrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD
flags )
{
UNIMPLEMENTED;
-}
-
-void CDECL RosDrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
-{
- struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
-
- if (!data) return;
- if (parent == old_parent) return;
-
- if (parent != GetDesktopWindow()) /* a child window */
- {
- if (old_parent == GetDesktopWindow())
- {
- /* destroy the old windows */
- //destroy_whole_window( data, FALSE );
- //destroy_icon_window( data );
- FIXME("Should destroy hwnd %x\n", data->hwnd);
- }
- }
- else /* new top level window */
- {
- /* FIXME: we ignore errors since we can't really recover anyway */
- //create_whole_window( data );
- FIXME("Should create a new whole window for hwnd %x\n",
data->hwnd);
- }
}
int CDECL RosDrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
@@ -757,107 +478,4 @@
}
}
-void CDECL RosDrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
- const RECT *window_rect, const RECT
*client_rect,
- RECT *visible_rect )
-{
- DWORD style = GetWindowLongW( hwnd, GWL_STYLE );
- struct ntdrv_win_data *data = NTDRV_get_win_data(hwnd);
-
- if (!data)
- {
- /* create the win data if the window is being made visible */
- if (!(style & WS_VISIBLE) && !(swp_flags & SWP_SHOWWINDOW))
return;
- if (!(data = NTDRV_create_win_data( hwnd ))) return;
- }
-
- SwmPosChanging(hwnd, window_rect);
-
- //TRACE( "win %x pos is changing. vis rect %s, win rect %s\n",
- // hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(window_rect) );
-
- *visible_rect = *window_rect;
-}
-
-void CDECL RosDrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
- const RECT *window_rect, const RECT *rectClient,
- const RECT *visible_rect, const RECT *valid_rects )
-{
- RECT old_whole_rect, old_client_rect, old_window_rect;
- struct ntdrv_win_data *data = NTDRV_get_win_data(hwnd);
- DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
-
- if (!data) return;
-
- TRACE( "win %x pos changed. new vis rect %s, old whole rect %s, swp_flags %x
insert_after %x\n",
- hwnd, wine_dbgstr_rect(visible_rect),
wine_dbgstr_rect(&data->whole_rect), swp_flags, insert_after );
-
- old_window_rect = data->window_rect;
- old_whole_rect = data->whole_rect;
- old_client_rect = data->client_rect;
- data->window_rect = *window_rect;
- data->whole_rect = *visible_rect;
- data->client_rect = *rectClient;
-
- if (!IsRectEmpty( &valid_rects[0] ))
- {
- int x_offset = old_whole_rect.left - data->whole_rect.left;
- int y_offset = old_whole_rect.top - data->whole_rect.top;
-
- /* if all that happened is that the whole window moved, copy everything */
- if (!(swp_flags & SWP_FRAMECHANGED) &&
- old_whole_rect.right - data->whole_rect.right == x_offset &&
- old_whole_rect.bottom - data->whole_rect.bottom == y_offset &&
- old_client_rect.left - data->client_rect.left == x_offset &&
- old_client_rect.right - data->client_rect.right == x_offset &&
- old_client_rect.top - data->client_rect.top == y_offset &&
- old_client_rect.bottom - data->client_rect.bottom == y_offset &&
- !memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) ))
- {
- /* if we have an SWM window the bits will be moved by the SWM */
- if (!data->whole_window)
- move_window_bits( data, &old_whole_rect, &data->whole_rect,
&old_client_rect );
- }
- else
- {
- move_window_bits( data, &valid_rects[1], &valid_rects[0],
&old_client_rect );
- }
- }
-
- if (!data->whole_window) return;
-
- /* Sync window position with the SWM */
- sync_window_position( data, swp_flags,
- &old_window_rect, &old_whole_rect, &old_client_rect
);
-
- if (data->mapped)
- {
- if (((swp_flags & SWP_HIDEWINDOW) && !(new_style & WS_VISIBLE))
||
- (!is_window_rect_mapped( window_rect ) && is_window_rect_mapped(
&old_window_rect )))
- unmap_window( data );
- }
-
- /* Pass show/hide information to the window manager */
- if ((new_style & WS_VISIBLE) &&
- ((new_style & WS_MINIMIZE) || is_window_rect_mapped( window_rect )))
- {
- //if (!data->mapped || (swp_flags & (SWP_FRAMECHANGED|SWP_STATECHANGED)))
- //set_wm_hints( display, data );
-
- if (!data->mapped)
- {
- map_window( data, new_style );
- }
- else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic !=
!(new_style & WS_MINIMIZE)))
- {
- data->iconic = (new_style & WS_MINIMIZE) != 0;
- FIXME( "changing win %p iconic state to %u\n", data->hwnd,
data->iconic );
- //if (data->iconic)
- // XIconifyWindow( display, data->whole_window, DefaultScreen(display)
);
- //else if (is_window_rect_mapped( rectWindow ))
- // XMapWindow( display, data->whole_window );
- }
- }
-}
-
/* EOF */
Modified: branches/arwinss/reactos/dll/win32/winent.drv/window.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/window.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/window.c [iso-8859-1] Fri Jan 7
20:50:13 2011
@@ -4,6 +4,7 @@
* FILE: dll/win32/winent.drv/window.c
* PURPOSE: Windows related functions
* PROGRAMMERS: Aleksey Bragin (aleksey(a)reactos.org)
+ * Some code is taken from winex11.drv (c) Wine project
*/
/* INCLUDES ***************************************************************/
@@ -22,6 +23,11 @@
0, 0, { (DWORD_PTR)(__FILE__ ": wnd_data_cs") }
};
static CRITICAL_SECTION wnd_data_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+static const char whole_window_prop[] = "__arwin_nt_whole_window";
+static const char client_window_prop[]= "__arwin_nt_client_window";
+
+GR_WINDOW_ID root_window = 2;
/* FUNCTIONS **************************************************************/
@@ -89,6 +95,73 @@
return item;
}
+/**********************************************************************
+ * CreateDesktopWindow (NTDRV.@)
+ */
+BOOL CDECL RosDrv_CreateDesktopWindow( HWND hwnd )
+{
+ unsigned int width, height;
+
+ /* retrieve the real size of the desktop */
+ SERVER_START_REQ( get_window_rectangles )
+ {
+ req->handle = wine_server_user_handle( hwnd );
+ wine_server_call( req );
+ width = reply->window.right - reply->window.left;
+ height = reply->window.bottom - reply->window.top;
+ }
+ SERVER_END_REQ;
+
+ TRACE("RosDrv_CreateDesktopWindow(%x), w %d h %d\n", hwnd, width, height);
+
+ SwmAddDesktopWindow(hwnd, width, height);
+
+ if (!width && !height) /* not initialized yet */
+ {
+ SERVER_START_REQ( set_window_pos )
+ {
+ req->handle = wine_server_user_handle( hwnd );
+ req->previous = 0;
+ req->flags = SWP_NOZORDER;
+ req->window.left = 0;
+ req->window.top = 0;
+ req->window.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ req->window.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ req->client = req->window;
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ }
+ else
+ {
+ //GR_WINDOW_ID win = (GR_WINDOW_ID)GetPropA( hwnd, whole_window_prop );
+ //ERR("win %p, w %d h %d, hwnd %x\n", win, width, height, hwnd);
+
+ //if (win && win != root_window) NTDRV_init_desktop( win, width, height
);
+
+ // create a desktop window
+ //GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_EXPOSURE);
+ }
+
+ return TRUE;
+}
+
+/**********************************************************************
+ * CreateWindow (NTDRV.@)
+ */
+BOOL CDECL RosDrv_CreateWindow( HWND hwnd )
+{
+ WARN("RosDrv_CreateWindow(%x)\n", hwnd);
+
+ if (hwnd == GetDesktopWindow() /*&& root_window != GR_ROOT_WINDOW_ID*/)
+ {
+ /* create desktop win data */
+ if (!NTDRV_create_desktop_win_data( hwnd )) return FALSE;
+ }
+
+ return TRUE;
+}
+
/***********************************************************************
* NTDRV_get_win_data
*
@@ -114,7 +187,6 @@
struct ntdrv_win_data *NTDRV_create_win_data( HWND hwnd )
{
struct ntdrv_win_data *data;
- DWORD style, ex_style;
HWND parent;
if (!(parent = GetAncestor( hwnd, GA_PARENT ))) return NULL; /* desktop */
@@ -133,16 +205,14 @@
if (parent == GetDesktopWindow())
{
- TRACE( "win %p window %s whole %s client %s\n",
- hwnd, wine_dbgstr_rect( &data->window_rect ),
+ if (!create_whole_window( data ))
+ {
+ HeapFree( GetProcessHeap(), 0, data );
+ return NULL;
+ }
+ TRACE( "win %p/%lx/%lx window %s whole %s client %s\n",
+ hwnd, data->whole_window, data->client_window, wine_dbgstr_rect(
&data->window_rect ),
wine_dbgstr_rect( &data->whole_rect ), wine_dbgstr_rect(
&data->client_rect ));
-
- style = GetWindowLongW( data->hwnd, GWL_STYLE );
- ex_style = GetWindowLongW( data->hwnd, GWL_EXSTYLE );
-
- /* Inform window manager about window rect in screen coords */
- SwmAddWindow(hwnd, &data->window_rect, style, ex_style);
- data->whole_window = (PVOID)1;
}
return data;
@@ -157,9 +227,41 @@
if (!data) return NULL;
/* Mark it as being a whole window */
- data->whole_window = (PVOID)1;
+ data->whole_window = data->client_window = root_window;
+ SetPropA( data->hwnd, whole_window_prop, (HANDLE)root_window );
+ SetPropA( data->hwnd, client_window_prop, (HANDLE)root_window );
return data;
+}
+
+/**********************************************************************
+ * destroy_whole_window
+ *
+ * Destroy the whole WM window for a given window.
+ */
+static void destroy_whole_window( struct ntdrv_win_data *data, BOOL already_destroyed )
+{
+ if (!data->whole_window) return;
+
+ TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window,
data->client_window );
+ //if (!already_destroyed) GrDestroyWindow( data->whole_window );
+ if (!already_destroyed) SwmRemoveWindow( data->hwnd );
+ data->whole_window = data->client_window = 0;
+ //data->wm_state = WithdrawnState;
+ //data->net_wm_state = 0;
+ data->mapped = FALSE;
+ /*if (data->xic)
+ {
+ XUnsetICFocus( data->xic );
+ XDestroyIC( data->xic );
+ data->xic = 0;
+ }*/
+ /* Outlook stops processing messages after destroying a dialog, so we need an
explicit flush */
+ //XFlush( display );
+ //XFree( data->wm_hints );
+ //data->wm_hints = NULL;
+ RemovePropA( data->hwnd, whole_window_prop );
+ RemovePropA( data->hwnd, client_window_prop );
}
/***********************************************************************
@@ -175,8 +277,7 @@
/* Remove property and free its data */
associate_destroy( data );
- /* Inform window manager */
- SwmRemoveWindow( hwnd );
+ destroy_whole_window( data, FALSE );
}
/***********************************************************************
@@ -186,7 +287,9 @@
{
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
- SwmShowWindow( data->hwnd, TRUE, 0);
+ //sync_window_style( display, data );
+ //GrMapWindow( data->whole_window );
+ SwmShowWindow( data->hwnd, TRUE, 0 );
data->mapped = TRUE;
data->iconic = (new_style & WS_MINIMIZE) != 0;
@@ -200,10 +303,171 @@
{
TRACE( "win %p/%lx\n", data->hwnd, data->whole_window );
- SwmShowWindow( data->hwnd, FALSE, 0);
+ //GrUnmapWindow( data->whole_window );
+ SwmShowWindow( data->hwnd, FALSE, 0 );
data->mapped = FALSE;
//data->net_wm_state = 0;
+}
+
+/***********************************************************************
+ * sync_window_position
+ *
+ * Synchronize the SWM window position with the Windows one
+ */
+void sync_window_position( struct ntdrv_win_data *data,
+ UINT swp_flags, const RECT *old_window_rect,
+ const RECT *old_whole_rect, const RECT *old_client_rect )
+{
+ //DWORD style = GetWindowLongW( data->hwnd, GWL_STYLE );
+ LONG width, height;
+ LONG x, y;
+
+ if (data->iconic) return;
+
+ SwmPosChanged(data->hwnd, &data->whole_rect, old_whole_rect, NULL,
swp_flags);
+
+ width = data->whole_rect.right - data->whole_rect.left;
+ height = data->whole_rect.bottom - data->whole_rect.top;
+ /* if window rect is empty force size to 1x1 */
+ if (width <= 0 || height <= 0) width = height = 1;
+ if (width > 65535) width = 65535;
+ if (height > 65535) height = 65535;
+
+ //GrResizeWindow(data->whole_window, width, height);
+
+ /* only the size is allowed to change for the desktop window */
+ if (data->whole_window != root_window)
+ {
+ x = data->whole_rect.left;
+ y = data->whole_rect.top;
+ //GrMoveWindow(data->whole_window, x, y);
+ }
+
+ if (!(swp_flags & SWP_NOZORDER) || (swp_flags & SWP_SHOWWINDOW))
+ {
+ /* find window that this one must be after */
+ HWND prev = GetWindow( data->hwnd, GW_HWNDPREV );
+ while (prev && !(GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE))
+ prev = GetWindow( prev, GW_HWNDPREV );
+ if (!prev) /* top child */
+ {
+ //GR_WINDOW_INFO infoptr;
+ //GrGetWindowInfo(data->whole_window, &infoptr);
+
+ //GrRaiseWindow(data->whole_window);
+ //changes.stack_mode = Above;
+ //mask |= CWStackMode;
+ SwmSetForeground(data->hwnd);
+ }
+ /* should use stack_mode Below but most window managers don't get it right
*/
+ /* and Above with a sibling doesn't work so well either, so we ignore it */
+ }
+
+
+ TRACE( "win %p/%lx pos %d,%d,%dx%d\n",
+ data->hwnd, data->whole_window, data->whole_rect.left,
data->whole_rect.top,
+ data->whole_rect.right - data->whole_rect.left,
+ data->whole_rect.bottom - data->whole_rect.top );
+}
+
+/***********************************************************************
+ * sync_client_position
+ *
+ * Synchronize the X client window position with the Windows one
+ */
+static void sync_client_position( struct ntdrv_win_data *data,
+ UINT swp_flags, const RECT *old_client_rect,
+ const RECT *old_whole_rect )
+{
+ LONG width, height;
+ BOOL resize = FALSE;
+ RECT old = *old_client_rect;
+ RECT new = data->client_rect;
+
+ OffsetRect( &old, -old_whole_rect->left, -old_whole_rect->top );
+ OffsetRect( &new, -data->whole_rect.left, -data->whole_rect.top );
+
+ width = old.right - old.left;
+ height = old.bottom - old.top;
+ if (old.right - old.left != new.right - new.left)
+ {
+ if ((width = new.right - new.left) <= 0) width = 1;
+ else if (width > 65535) width = 65535;
+ resize = TRUE;
+ }
+ if (old.bottom - old.top != new.bottom - new.top)
+ {
+ if ((height = new.bottom - new.top) <= 0) height = 1;
+ else if (height > 65535) height = 65535;
+ resize = TRUE;
+ }
+
+ TRACE( "setting client win %lx pos %d,%d,%dx%d\n",
+ data->client_window, new.left, new.top,
+ new.right - new.left, new.bottom - new.top );
+
+ //if (resize) GrResizeWindow( data->client_window, width, height );
+
+ if ((old.left != new.left) || (old.top != new.top))
+ {
+ //GrMoveWindow(data->client_window, new.left, new.top);
+ }
+}
+
+/***********************************************************************
+ * move_window_bits
+ *
+ * Move the window bits when a window is moved.
+ */
+void move_window_bits( struct ntdrv_win_data *data, const RECT *old_rect, const RECT
*new_rect,
+ const RECT *old_client_rect )
+{
+ RECT src_rect = *old_rect;
+ RECT dst_rect = *new_rect;
+ HDC hdc_src, hdc_dst;
+ HRGN rgn = 0;
+ HWND parent = 0;
+
+ if (!data->whole_window)
+ {
+ OffsetRect( &dst_rect, -data->window_rect.left, -data->window_rect.top
);
+ parent = GetAncestor( data->hwnd, GA_PARENT );
+ hdc_src = GetDCEx( parent, 0, DCX_CACHE );
+ hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE | DCX_WINDOW );
+ }
+ else
+ {
+ OffsetRect( &dst_rect, -data->client_rect.left, -data->client_rect.top
);
+ /* make src rect relative to the old position of the window */
+ OffsetRect( &src_rect, -old_client_rect->left, -old_client_rect->top
);
+ if (dst_rect.left == src_rect.left && dst_rect.top == src_rect.top)
return;
+ hdc_src = hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE );
+ }
+
+ TRACE( "copying bits for win %p (parent %p)/ %s -> %s\n",
+ data->hwnd, parent,
+ wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) );
+ BitBlt( hdc_dst, dst_rect.left, dst_rect.top,
+ dst_rect.right - dst_rect.left, dst_rect.bottom - dst_rect.top,
+ hdc_src, src_rect.left, src_rect.top, SRCCOPY );
+
+ ReleaseDC( data->hwnd, hdc_dst );
+ if (hdc_src != hdc_dst) ReleaseDC( parent, hdc_src );
+
+ if (rgn)
+ {
+ if (!data->whole_window)
+ {
+ /* map region to client rect since we are using DCX_WINDOW */
+ OffsetRgn( rgn, data->window_rect.left - data->client_rect.left,
+ data->window_rect.top - data->client_rect.top );
+ RedrawWindow( data->hwnd, NULL, rgn,
+ RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN );
+ }
+ else RedrawWindow( data->hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE |
RDW_ALLCHILDREN );
+ DeleteObject( rgn );
+ }
}
/***********************************************************************
@@ -224,50 +488,427 @@
}
/***********************************************************************
- * sync_window_position
- *
- * Synchronize the SWM window position with the Windows one
- */
-void sync_window_position( struct ntdrv_win_data *data,
- UINT swp_flags, const RECT *old_window_rect,
- const RECT *old_whole_rect, const RECT *old_client_rect )
-{
- SwmPosChanged(data->hwnd, &data->whole_rect, old_whole_rect, NULL,
swp_flags);
-
- if (!(swp_flags & SWP_NOZORDER) || (swp_flags & SWP_SHOWWINDOW))
- {
- /* find window that this one must be after */
- HWND prev = GetWindow( data->hwnd, GW_HWNDPREV );
- while (prev && !(GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE))
- prev = GetWindow( prev, GW_HWNDPREV );
- if (!prev) /* top child */
- {
- /* Bring this window to foreground */
- SwmSetForeground(data->hwnd);
- }
- /* should use stack_mode Below but most window managers don't get it right
*/
- /* and Above with a sibling doesn't work so well either, so we ignore it */
- }
-
-#ifdef HAVE_LIBXSHAPE
- if (IsRectEmpty( old_window_rect ) != IsRectEmpty( &data->window_rect ))
- sync_window_region( display, data, (HRGN)1 );
- if (data->shaped)
- {
- int old_x_offset = old_window_rect->left - old_whole_rect->left;
- int old_y_offset = old_window_rect->top - old_whole_rect->top;
- int new_x_offset = data->window_rect.left - data->whole_rect.left;
- int new_y_offset = data->window_rect.top - data->whole_rect.top;
- if (old_x_offset != new_x_offset || old_y_offset != new_y_offset)
- XShapeOffsetShape( display, data->whole_window, ShapeBounding,
- new_x_offset - old_x_offset, new_y_offset - old_y_offset
);
- }
+ * create_client_window
+ */
+static GR_WINDOW_ID create_client_window( struct ntdrv_win_data *data )
+{
+ int cx, cy;
+ GR_WINDOW_ID client;
+
+ /*attr.bit_gravity = NorthWestGravity;
+ attr.win_gravity = NorthWestGravity;
+ attr.backing_store = NotUseful;
+ attr.event_mask = (ExposureMask | PointerMotionMask |
+ ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
+ mask = CWEventMask | CWBitGravity | CWWinGravity | CWBackingStore;*/
+
+ if ((cx = data->client_rect.right - data->client_rect.left) <= 0) cx = 1;
+ else if (cx > 65535) cx = 65535;
+ if ((cy = data->client_rect.bottom - data->client_rect.top) <= 0) cy = 1;
+ else if (cy > 65535) cy = 65535;
+
+ client = (GR_WINDOW_ID)1;//GrNewWindow( data->whole_window,
+ // data->client_rect.left - data->whole_rect.left,
+ // data->client_rect.top - data->whole_rect.top,
+ // cx, cy, 0, RGB(255,255,255), 0 );
+
+ if (!client)
+ {
+ return 0;
+ }
+
+ //GrSelectEvents(client, GR_EVENT_MASK_EXPOSURE);
+
+ if (data->client_window)
+ {
+ //GrDestroyWindow( data->client_window );
+ }
+ data->client_window = client;
+
+ //GrMapWindow( data->client_window );
+
+ SetPropA( data->hwnd, client_window_prop, (HANDLE)data->client_window );
+ return data->client_window;
+}
+
+/**********************************************************************
+ * create_whole_window
+ *
+ * Create the whole X window for a given window
+ */
+GR_WINDOW_ID create_whole_window( struct ntdrv_win_data *data )
+{
+ int cx, cy;
+ //int mask;
+ //WCHAR text[1024];
+ //COLORREF key;
+ //BYTE alpha;
+ //DWORD layered_flags;
+ HRGN win_rgn;
+ //GR_WM_PROPERTIES props;
+ DWORD style, ex_style;
+
+ if ((win_rgn = CreateRectRgn( 0, 0, 0, 0 )) &&
+ GetWindowRgn( data->hwnd, win_rgn ) == ERROR)
+ {
+ DeleteObject( win_rgn );
+ win_rgn = 0;
+ }
+ data->shaped = (win_rgn != 0);
+
+ //mask = get_window_attributes( display, data, &attr );
+
+ data->whole_rect = data->window_rect;
+ //X11DRV_window_to_X_rect( data, &data->whole_rect );
+ if (!(cx = data->whole_rect.right - data->whole_rect.left)) cx = 1;
+ else if (cx > 65535) cx = 65535;
+ if (!(cy = data->whole_rect.bottom - data->whole_rect.top)) cy = 1;
+ else if (cy > 65535) cy = 65535;
+
+ //data->whole_window = GrNewWindow( root_window,
+ // data->whole_rect.left,
+ // data->whole_rect.top,
+ // cx, cy, 0, RGB(255,255,255), 0 );
+ data->whole_window = (GR_WINDOW_ID)1;
+
+ /* Inform window manager about window rect in screen coords */
+ style = GetWindowLongW( data->hwnd, GWL_STYLE );
+ ex_style = GetWindowLongW( data->hwnd, GWL_EXSTYLE );
+ SwmAddWindow(data->hwnd, &data->window_rect, style, ex_style);
+
+ //GrSelectEvents(data->whole_window, GR_EVENT_MASK_EXPOSURE);
+
+ //if (data->whole_window) GrSetHwnd( data->whole_window, data->hwnd );
+
+ if (!data->whole_window) goto done;
+
+ /* Set override_redirect */
+ //props.props = GR_WM_PROPS_NODECORATE;
+ //props.flags = GR_WM_FLAGS_PROPS;
+ //GrSetWMProperties(data->whole_window, &props);
+
+ if (!create_client_window( data ))
+ {
+ //GrDestroyWindow( data->whole_window );
+ data->whole_window = 0;
+ goto done;
+ }
+
+ //set_initial_wm_hints( display, data );
+ //set_wm_hints( display, data );
+
+ SetPropA( data->hwnd, whole_window_prop, (HANDLE)data->whole_window );
+
+ /* set the window text */
+ //if (!InternalGetWindowText( data->hwnd, text, sizeof(text)/sizeof(WCHAR) ))
text[0] = 0;
+ //sync_window_text( display, data->whole_window, text );
+
+ /* set the window region */
+ //if (win_rgn || IsRectEmpty( &data->window_rect )) sync_window_region(
display, data, win_rgn );
+
+ /* set the window opacity */
+ //if (!GetLayeredWindowAttributes( data->hwnd, &key, &alpha,
&layered_flags )) layered_flags = 0;
+ //sync_window_opacity( display, data->whole_window, key, alpha, layered_flags );
+
+ //sync_window_cursor( data );
+done:
+ if (win_rgn) DeleteObject( win_rgn );
+ return data->whole_window;
+}
+
+/***********************************************************************
+ * NTDRV_get_whole_window
+ *
+ * Return the X window associated with the full area of a window
+ */
+GR_WINDOW_ID NTDRV_get_whole_window( HWND hwnd )
+{
+ struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
+
+ if (!data)
+ {
+ if (hwnd == GetDesktopWindow()) return root_window;
+ return (GR_WINDOW_ID)GetPropA( hwnd, whole_window_prop );
+ }
+ return data->whole_window;
+}
+
+/***********************************************************************
+ * NTDRV_get_client_window
+ *
+ * Return the X window associated with the client area of a window
+ */
+#if 0
+static GR_WINDOW_ID NTDRV_get_client_window( HWND hwnd )
+{
+ struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
+
+ if (!data)
+ {
+ if (hwnd == GetDesktopWindow()) return root_window;
+ return (GR_WINDOW_ID)GetPropA( hwnd, client_window_prop );
+ }
+ return data->client_window;
+}
#endif
-
- TRACE( "win %p/%lx pos %d,%d,%dx%d\n",
- data->hwnd, data->whole_window, data->whole_rect.left,
data->whole_rect.top,
- data->whole_rect.right - data->whole_rect.left,
- data->whole_rect.bottom - data->whole_rect.top );
+/***********************************************************************
+ * NTDRV_GetDC (NTDRV.@)
+ */
+void CDECL RosDrv_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
+ const RECT *top_rect, DWORD flags )
+{
+ struct ntdrv_escape_set_drawable escape;
+ //struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
+ //HWND parent;
+
+ escape.code = NTDRV_SET_DRAWABLE;
+ escape.clip_children = FALSE;
+ escape.gl_copy = FALSE;
+ escape.hwnd = 0;
+ escape.release = FALSE;
+
+ escape.dc_rect.left = win_rect->left - top_rect->left;
+ escape.dc_rect.top = win_rect->top - top_rect->top;
+ escape.dc_rect.right = win_rect->right - top_rect->left;
+ escape.dc_rect.bottom = win_rect->bottom - top_rect->top;
+ escape.drawable_rect.left = top_rect->left;
+ escape.drawable_rect.top = top_rect->top;
+ escape.drawable_rect.right = top_rect->right;
+ escape.drawable_rect.bottom = top_rect->bottom;
+#if GOOD_VERSION
+ if (top == hwnd)
+ {
+ if (flags & DCX_WINDOW)
+ {
+ escape.drawable = data ? data->whole_window : NTDRV_get_whole_window( hwnd
);
+ }
+ else
+ escape.drawable = data ? data->client_window : NTDRV_get_client_window(
hwnd );
+ }
+ else
+ {
+ for (parent = hwnd; parent && parent != top; parent = GetAncestor(
parent, GA_PARENT ))
+ if ((escape.drawable = NTDRV_get_client_window( parent ))) break;
+
+ if (escape.drawable)
+ {
+ POINT pt = { 0, 0 };
+ MapWindowPoints( top, parent, &pt, 1 );
+ OffsetRect( &escape.dc_rect, pt.x, pt.y );
+ OffsetRect( &escape.drawable_rect, -pt.x, -pt.y );
+
+ FIXME("Offset by (%d, %d)\n", pt.x, pt.y);
+ }
+ else escape.drawable = NTDRV_get_client_window( top );
+
+ if (flags & DCX_CLIPCHILDREN) escape.clip_children = TRUE;
+ }
+#else
+ escape.hwnd = GetAncestor(hwnd, GA_ROOT);
+#endif
+
+ TRACE("hdc %x, hwnd %x, top %x\n win_rect %s, top_rect %s\n", hdc, hwnd,
top,
+ wine_dbgstr_rect(win_rect), wine_dbgstr_rect(top_rect));
+
+ ExtEscape( hdc, NTDRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
+}
+
+void CDECL RosDrv_ReleaseDC( HWND hwnd, HDC hdc )
+{
+ struct ntdrv_escape_set_drawable escape;
+ RECTL virtual_screen_rect;
+
+ escape.code = NTDRV_SET_DRAWABLE;
+ escape.drawable = root_window;
+ escape.clip_children = FALSE;
+ escape.gl_copy = FALSE;
+ escape.release = TRUE;
+ escape.hwnd = hwnd;
+
+ virtual_screen_rect.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ virtual_screen_rect.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ virtual_screen_rect.left = 0; virtual_screen_rect.top = 0;
+
+ SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right -
virtual_screen_rect.left,
+ virtual_screen_rect.bottom - virtual_screen_rect.top );
+ OffsetRect( &escape.dc_rect, -escape.drawable_rect.left,
-escape.drawable_rect.top );
+
+ ExtEscape( hdc, NTDRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
+}
+
+/***********************************************************************
+ * SetCapture (NTDRV.@)
+ */
+void CDECL RosDrv_SetCapture( HWND hwnd, UINT flags )
+{
+ if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
+
+ if (hwnd)
+ {
+ /* Capturing */
+ TRACE("Capture set for hwnd %x\n", hwnd);
+ }
+ else
+ {
+ TRACE("Capture released\n");
+ }
+}
+
+
+/*****************************************************************
+ * SetParent (NTDRV.@)
+ */
+void CDECL RosDrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
+{
+ struct ntdrv_win_data *data = NTDRV_get_win_data( hwnd );
+
+ if (!data) return;
+ if (parent == old_parent) return;
+
+ if (parent != GetDesktopWindow()) /* a child window */
+ {
+ if (old_parent == GetDesktopWindow())
+ {
+ /* destroy the old windows */
+ //destroy_whole_window( data, FALSE );
+ //destroy_icon_window( data );
+ FIXME("Should destroy hwnd %x\n", data->hwnd);
+ }
+ }
+ else /* new top level window */
+ {
+ /* FIXME: we ignore errors since we can't really recover anyway */
+ //create_whole_window( data );
+ FIXME("Should create a new whole window for hwnd %x\n",
data->hwnd);
+ }
+}
+
+/*****************************************************************
+ * SetFocus (NTDRV.@)
+ *
+ * Set the Nano focus.
+ */
+void CDECL RosDrv_SetFocus( HWND hwnd )
+{
+ struct ntdrv_win_data *data;
+
+ if (!(hwnd = GetAncestor( hwnd, GA_ROOT ))) return;
+ if (!(data = NTDRV_get_win_data( hwnd ))) return;
+ if (!data->whole_window) return;
+
+ TRACE("SetFocus %x, desk %x\n", hwnd, GetDesktopWindow());
+
+ /* Bring this window to foreground */
+ SwmSetForeground(hwnd);
+ //GrRaiseWindow(data->whole_window);
+}
+
+/***********************************************************************
+ * WindowPosChanging (NTDRV.@)
+ */
+void CDECL RosDrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT swp_flags,
+ const RECT *window_rect, const RECT
*client_rect,
+ RECT *visible_rect )
+{
+ DWORD style = GetWindowLongW( hwnd, GWL_STYLE );
+ struct ntdrv_win_data *data = NTDRV_get_win_data(hwnd);
+
+ if (!data)
+ {
+ /* create the win data if the window is being made visible */
+ if (!(style & WS_VISIBLE) && !(swp_flags & SWP_SHOWWINDOW))
return;
+ if (!(data = NTDRV_create_win_data( hwnd ))) return;
+ }
+
+ //SwmPosChanging(hwnd, window_rect);
+
+ //TRACE( "win %x pos is changing. vis rect %s, win rect %s\n",
+ // hwnd, wine_dbgstr_rect(visible_rect), wine_dbgstr_rect(window_rect) );
+
+ *visible_rect = *window_rect;
+}
+
+void CDECL RosDrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
+ const RECT *window_rect, const RECT *rectClient,
+ const RECT *visible_rect, const RECT *valid_rects )
+{
+ RECT old_whole_rect, old_client_rect, old_window_rect;
+ struct ntdrv_win_data *data = NTDRV_get_win_data(hwnd);
+ DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
+
+ if (!data) return;
+
+ TRACE( "win %x pos changed. new vis rect %s, old whole rect %s, swp_flags %x
insert_after %x\n",
+ hwnd, wine_dbgstr_rect(visible_rect),
wine_dbgstr_rect(&data->whole_rect), swp_flags, insert_after );
+
+ old_window_rect = data->window_rect;
+ old_whole_rect = data->whole_rect;
+ old_client_rect = data->client_rect;
+ data->window_rect = *window_rect;
+ data->whole_rect = *visible_rect;
+ data->client_rect = *rectClient;
+
+ if (!IsRectEmpty( &valid_rects[0] ))
+ {
+ int x_offset = old_whole_rect.left - data->whole_rect.left;
+ int y_offset = old_whole_rect.top - data->whole_rect.top;
+
+ /* if all that happened is that the whole window moved, copy everything */
+ if (!(swp_flags & SWP_FRAMECHANGED) &&
+ old_whole_rect.right - data->whole_rect.right == x_offset &&
+ old_whole_rect.bottom - data->whole_rect.bottom == y_offset &&
+ old_client_rect.left - data->client_rect.left == x_offset &&
+ old_client_rect.right - data->client_rect.right == x_offset &&
+ old_client_rect.top - data->client_rect.top == y_offset &&
+ old_client_rect.bottom - data->client_rect.bottom == y_offset &&
+ !memcmp( &valid_rects[0], &data->client_rect, sizeof(RECT) ))
+ {
+ /* if we have an SWM window the bits will be moved by the SWM */
+ if (!data->whole_window)
+ move_window_bits( data, &old_whole_rect, &data->whole_rect,
&old_client_rect );
+ }
+ else
+ {
+ move_window_bits( data, &valid_rects[1], &valid_rects[0],
&old_client_rect );
+ }
+ }
+
+ sync_client_position( data, swp_flags, &old_client_rect, &old_whole_rect );
+
+ if (!data->whole_window) return;
+
+ /* Sync window position with the SWM */
+ sync_window_position( data, swp_flags,
+ &old_window_rect, &old_whole_rect, &old_client_rect
);
+
+ if (data->mapped)
+ {
+ if (((swp_flags & SWP_HIDEWINDOW) && !(new_style & WS_VISIBLE))
||
+ (!is_window_rect_mapped( window_rect ) && is_window_rect_mapped(
&old_window_rect )))
+ unmap_window( data );
+ }
+
+ /* Pass show/hide information to the window manager */
+ if ((new_style & WS_VISIBLE) &&
+ ((new_style & WS_MINIMIZE) || is_window_rect_mapped( window_rect )))
+ {
+ //if (!data->mapped || (swp_flags & (SWP_FRAMECHANGED|SWP_STATECHANGED)))
+ //set_wm_hints( display, data );
+
+ if (!data->mapped)
+ {
+ map_window( data, new_style );
+ }
+ else if ((swp_flags & SWP_STATECHANGED) && (!data->iconic !=
!(new_style & WS_MINIMIZE)))
+ {
+ data->iconic = (new_style & WS_MINIMIZE) != 0;
+ FIXME( "changing win %p iconic state to %u\n", data->hwnd,
data->iconic );
+ //if (data->iconic)
+ // XIconifyWindow( display, data->whole_window, DefaultScreen(display)
);
+ //else if (is_window_rect_mapped( rectWindow ))
+ // XMapWindow( display, data->whole_window );
+ }
+ }
}
/* EOF */
Modified: branches/arwinss/reactos/dll/win32/winent.drv/winent.h
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/winent.h [iso-8859-1] Fri Jan 7
20:50:13 2011
@@ -58,7 +58,8 @@
struct ntdrv_escape_set_drawable
{
- enum ntdrv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */
+ enum ntdrv_escape_codes code; /* escape code (NTDRV_SET_DRAWABLE) */
+ GR_WINDOW_ID drawable;
BOOL clip_children;/* ClipByChildren or IncludeInferiors */
RECT dc_rect; /* DC rectangle relative to drawable */
RECT drawable_rect;/* Drawable rectangle relative to screen */
@@ -70,17 +71,30 @@
/* ntdrv private window data */
struct ntdrv_win_data
{
- struct list entry; /* entry in the linked list of win data */
- HWND hwnd; /* hwnd that this private data belongs to */
- PVOID whole_window; /* SWM window for the complete window */
+ struct list entry; /* entry in the linked list of win data */
+ HWND hwnd; /* hwnd that this private data belongs to */
+ GR_WINDOW_ID whole_window; /* SWM window for the complete window */
+ GR_WINDOW_ID client_window; /* SWM window for the client area */
RECT window_rect; /* USER window rectangle relative to parent */
- RECT whole_rect; /* X window rectangle for the whole window relative to
parent */
+ RECT whole_rect; /* SWM window rectangle for the whole window relative to
parent */
RECT client_rect; /* client area relative to parent */
HCURSOR cursor; /* current cursor */
BOOL mapped : 1; /* is window mapped? (in either normal or iconic state)
*/
BOOL iconic : 1; /* is window in iconic state? */
BOOL shaped : 1; /* is window using a custom region shape? */
};
+
+//typedef void (*ntdrv_event_handler)( HWND hwnd, GR_EVENT *event );
+
+extern GR_WINDOW_ID root_window;
+
+static inline void mirror_rect( const RECT *window_rect, RECT *rect )
+{
+ int width = window_rect->right - window_rect->left;
+ int tmp = rect->left;
+ rect->left = width - rect->right;
+ rect->right = width - tmp;
+}
/* clipboard.c */
void NTDRV_InitClipboard(void);
@@ -116,7 +130,7 @@
BOOL CDECL RosDrv_GetCursorPos( LPPOINT pt );
-/* wnd.c */
+/* window.c */
struct ntdrv_win_data *NTDRV_get_win_data( HWND hwnd );
struct ntdrv_win_data *NTDRV_create_win_data( HWND hwnd );
struct ntdrv_win_data *NTDRV_create_desktop_win_data( HWND hwnd );
@@ -128,3 +142,4 @@
void sync_window_position( struct ntdrv_win_data *data,
UINT swp_flags, const RECT *old_window_rect,
const RECT *old_whole_rect, const RECT *old_client_rect );
+GR_WINDOW_ID create_whole_window( struct ntdrv_win_data *data );
Modified: branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winen…
==============================================================================
--- branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild [iso-8859-1] (original)
+++ branches/arwinss/reactos/dll/win32/winent.drv/winent.rbuild [iso-8859-1] Fri Jan 7
20:50:13 2011
@@ -9,6 +9,7 @@
<file>bitblt.c</file>
<file>clipboard.c</file>
<file>dib.c</file>
+ <file>event.c</file>
<file>font.c</file>
<file>gdidrv.c</file>
<file>graphics.c</file>