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/winent... ============================================================================== --- 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@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/winent... ============================================================================== --- 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@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/winent... ============================================================================== --- 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@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/winent... ============================================================================== --- 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/winent... ============================================================================== --- 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@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/winent... ============================================================================== --- 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/winent... ============================================================================== --- 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>