mirror of
https://github.com/reactos/wine.git
synced 2025-02-18 03:48:01 +00:00
Update the cursor for each window on receiving an X11 event, don't
wait for the SetCursor call. Added EnterNotify handler to set the cursor on window map/unmap.
This commit is contained in:
parent
c0d1ff5967
commit
9428f06993
@ -102,6 +102,7 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
|
||||
extern void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event );
|
||||
extern void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event );
|
||||
extern void X11DRV_MotionNotify( HWND hwnd, XMotionEvent *event );
|
||||
extern void X11DRV_EnterNotify( HWND hwnd, XCrossingEvent *event );
|
||||
extern void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event );
|
||||
extern void X11DRV_KeymapNotify( HWND hwnd, XKeymapEvent *event );
|
||||
extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event );
|
||||
@ -298,6 +299,10 @@ static void EVENT_ProcessEvent( XEvent *event )
|
||||
X11DRV_MotionNotify( hWnd, (XMotionEvent*)event );
|
||||
break;
|
||||
|
||||
case EnterNotify:
|
||||
X11DRV_EnterNotify( hWnd, (XCrossingEvent*)event );
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
EVENT_FocusIn( hWnd, (XFocusChangeEvent*)event );
|
||||
break;
|
||||
|
@ -134,9 +134,31 @@ static void send_mouse_event( HWND hwnd, DWORD flags, DWORD posX, DWORD posY,
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_GetCursor
|
||||
* update_cursor
|
||||
*
|
||||
* Update the cursor of a window on a mouse event.
|
||||
*/
|
||||
Cursor X11DRV_GetCursor( Display *display, CURSORICONINFO *ptr )
|
||||
static void update_cursor( HWND hwnd, Window win )
|
||||
{
|
||||
struct x11drv_thread_data *data = x11drv_thread_data();
|
||||
|
||||
if (win == X11DRV_get_client_window( hwnd ))
|
||||
win = X11DRV_get_whole_window( hwnd ); /* always set cursor on whole window */
|
||||
|
||||
if (data->cursor_window != win)
|
||||
{
|
||||
data->cursor_window = win;
|
||||
if (data->cursor) TSXDefineCursor( data->display, win, data->cursor );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* create_cursor
|
||||
*
|
||||
* Create an X cursor from a Windows one.
|
||||
*/
|
||||
static Cursor create_cursor( Display *display, CURSORICONINFO *ptr )
|
||||
{
|
||||
Pixmap pixmapBits, pixmapMask, pixmapMaskInv, pixmapAll;
|
||||
XColor fg, bg;
|
||||
@ -420,13 +442,6 @@ Cursor X11DRV_GetCursor( Display *display, CURSORICONINFO *ptr )
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/* set the cursor of a window; helper for X11DRV_SetCursor */
|
||||
static BOOL CALLBACK set_win_cursor( HWND hwnd, LPARAM cursor )
|
||||
{
|
||||
Window win = X11DRV_get_whole_window( hwnd );
|
||||
if (win) TSXDefineCursor( thread_display(), win, (Cursor)cursor );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetCursor (X11DRV.@)
|
||||
@ -440,27 +455,34 @@ void X11DRV_SetCursor( CURSORICONINFO *lpCursor )
|
||||
/* If in desktop mode, set the cursor on the desktop window */
|
||||
|
||||
wine_tsx11_lock();
|
||||
cursor = X11DRV_GetCursor( gdi_display, lpCursor );
|
||||
cursor = create_cursor( gdi_display, lpCursor );
|
||||
if (cursor)
|
||||
{
|
||||
XDefineCursor( gdi_display, root_window, cursor );
|
||||
/* Make the change take effect immediately */
|
||||
XFlush(gdi_display);
|
||||
XFreeCursor( gdi_display, cursor );
|
||||
}
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
else /* set the same cursor for all top-level windows of the current thread */
|
||||
{
|
||||
Display *display = thread_display();
|
||||
struct x11drv_thread_data *data = x11drv_thread_data();
|
||||
|
||||
wine_tsx11_lock();
|
||||
cursor = X11DRV_GetCursor( display, lpCursor );
|
||||
wine_tsx11_unlock();
|
||||
cursor = create_cursor( data->display, lpCursor );
|
||||
if (cursor)
|
||||
{
|
||||
/* EnumThreadWindows( GetCurrentThreadId(), set_win_cursor, (LPARAM)cursor );*/
|
||||
EnumWindows( set_win_cursor, (LPARAM)cursor );
|
||||
TSXFreeCursor( display, cursor );
|
||||
if (data->cursor) XFreeCursor( data->display, data->cursor );
|
||||
data->cursor = cursor;
|
||||
if (data->cursor_window)
|
||||
{
|
||||
XDefineCursor( data->display, data->cursor_window, cursor );
|
||||
/* Make the change take effect immediately */
|
||||
XFlush( data->display );
|
||||
}
|
||||
}
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,6 +515,7 @@ void X11DRV_GetCursorPos(LPPOINT pos)
|
||||
&rootX, &rootY, &winX, &winY, &xstate ))
|
||||
return;
|
||||
|
||||
update_key_state( xstate );
|
||||
TRACE("pointer at (%d,%d)\n", winX, winY );
|
||||
pos->x = winX;
|
||||
pos->y = winY;
|
||||
@ -503,18 +526,7 @@ void X11DRV_GetCursorPos(LPPOINT pos)
|
||||
*/
|
||||
void X11DRV_InitMouse( BYTE *key_state_table )
|
||||
{
|
||||
Window root, child;
|
||||
int root_x, root_y, child_x, child_y;
|
||||
unsigned int KeyState;
|
||||
|
||||
pKeyStateTable = key_state_table;
|
||||
/* Get the current mouse position and simulate an absolute mouse
|
||||
movement to initialize the mouse global variables */
|
||||
TSXQueryPointer( thread_display(), root_window, &root, &child,
|
||||
&root_x, &root_y, &child_x, &child_y, &KeyState);
|
||||
update_key_state( KeyState );
|
||||
send_mouse_event( 0, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
|
||||
root_x, root_y, 0, GetTickCount() + X11DRV_server_startticks );
|
||||
}
|
||||
|
||||
|
||||
@ -528,7 +540,9 @@ void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event )
|
||||
POINT pt;
|
||||
|
||||
if (buttonNum >= NB_BUTTONS) return;
|
||||
if (!hwnd) return;
|
||||
|
||||
update_cursor( hwnd, event->window );
|
||||
get_coords( &hwnd, event->window, event->x, event->y, &pt );
|
||||
|
||||
switch (buttonNum)
|
||||
@ -555,7 +569,9 @@ void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event )
|
||||
POINT pt;
|
||||
|
||||
if (buttonNum >= NB_BUTTONS || !button_up_flags[buttonNum]) return;
|
||||
if (!hwnd) return;
|
||||
|
||||
update_cursor( hwnd, event->window );
|
||||
get_coords( &hwnd, event->window, event->x, event->y, &pt );
|
||||
update_key_state( event->state );
|
||||
send_mouse_event( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE,
|
||||
@ -570,6 +586,28 @@ void X11DRV_MotionNotify( HWND hwnd, XMotionEvent *event )
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
if (!hwnd) return;
|
||||
|
||||
update_cursor( hwnd, event->window );
|
||||
get_coords( &hwnd, event->window, event->x, event->y, &pt );
|
||||
update_key_state( event->state );
|
||||
send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
|
||||
pt.x, pt.y, 0, event->time );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_EnterNotify
|
||||
*/
|
||||
void X11DRV_EnterNotify( HWND hwnd, XCrossingEvent *event )
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
if (event->detail == NotifyVirtual || event->detail == NotifyNonlinearVirtual) return;
|
||||
if (!hwnd) return;
|
||||
|
||||
/* simulate a mouse motion event */
|
||||
update_cursor( hwnd, event->window );
|
||||
get_coords( &hwnd, event->window, event->x, event->y, &pt );
|
||||
update_key_state( event->state );
|
||||
send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
|
||||
|
@ -115,7 +115,6 @@ inline static BOOL is_client_window_mapped( WND *win )
|
||||
* get_window_attributes
|
||||
*
|
||||
* Fill the window attributes structure for an X window.
|
||||
* Returned cursor must be freed by caller.
|
||||
*/
|
||||
static int get_window_attributes( Display *display, WND *win, XSetWindowAttributes *attr )
|
||||
{
|
||||
@ -128,14 +127,13 @@ static int get_window_attributes( Display *display, WND *win, XSetWindowAttribut
|
||||
attr->override_redirect = !managed;
|
||||
attr->colormap = X11DRV_PALETTE_PaletteXColormap;
|
||||
attr->save_under = ((win->clsStyle & CS_SAVEBITS) != 0);
|
||||
attr->cursor = None;
|
||||
attr->cursor = x11drv_thread_data()->cursor;
|
||||
attr->event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask);
|
||||
ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
|
||||
|
||||
if (is_window_top_level( win ))
|
||||
{
|
||||
attr->event_mask |= StructureNotifyMask | FocusChangeMask | KeymapStateMask;
|
||||
attr->cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );
|
||||
}
|
||||
|
||||
return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor);
|
||||
}
|
||||
|
||||
@ -153,7 +151,6 @@ static void sync_window_style( Display *display, WND *win )
|
||||
wine_tsx11_lock();
|
||||
mask = get_window_attributes( display, win, &attr );
|
||||
XChangeWindowAttributes( display, get_whole_window(win), mask, &attr );
|
||||
if (attr.cursor) XFreeCursor( display, attr.cursor );
|
||||
wine_tsx11_unlock();
|
||||
}
|
||||
|
||||
@ -200,7 +197,7 @@ static Window create_icon_window( Display *display, WND *win )
|
||||
XSetWindowAttributes attr;
|
||||
|
||||
attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask);
|
||||
ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
|
||||
attr.bit_gravity = NorthWestGravity;
|
||||
attr.backing_store = NotUseful/*WhenMapped*/;
|
||||
attr.colormap = X11DRV_PALETTE_PaletteXColormap; /* Needed due to our visual */
|
||||
@ -230,6 +227,8 @@ inline static void destroy_icon_window( Display *display, WND *win )
|
||||
struct x11drv_win_data *data = win->pDriverData;
|
||||
|
||||
if (!data->icon_window) return;
|
||||
if (x11drv_thread_data()->cursor_window == data->icon_window)
|
||||
x11drv_thread_data()->cursor_window = None;
|
||||
wine_tsx11_lock();
|
||||
XDeleteContext( display, data->icon_window, winContext );
|
||||
XDestroyWindow( display, data->icon_window );
|
||||
@ -695,7 +694,6 @@ static Window create_whole_window( Display *display, WND *win )
|
||||
data->whole_window = XCreateWindow( display, parent, rect.left, rect.top, cx, cy,
|
||||
0, screen_depth, InputOutput, visual,
|
||||
mask, &attr );
|
||||
if (attr.cursor) XFreeCursor( display, attr.cursor );
|
||||
|
||||
if (!data->whole_window)
|
||||
{
|
||||
@ -734,7 +732,7 @@ static Window create_client_window( Display *display, WND *win )
|
||||
data->client_rect = rect;
|
||||
|
||||
attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask);
|
||||
ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
|
||||
attr.bit_gravity = (win->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ?
|
||||
ForgetGravity : NorthWestGravity;
|
||||
attr.backing_store = NotUseful/*WhenMapped*/;
|
||||
@ -827,7 +825,8 @@ BOOL X11DRV_SetWindowText( HWND hwnd, LPCWSTR text )
|
||||
*/
|
||||
BOOL X11DRV_DestroyWindow( HWND hwnd )
|
||||
{
|
||||
Display *display = thread_display();
|
||||
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
||||
Display *display = thread_data->display;
|
||||
WND *wndPtr = WIN_GetPtr( hwnd );
|
||||
X11DRV_WND_DATA *data = wndPtr->pDriverData;
|
||||
|
||||
@ -836,6 +835,7 @@ BOOL X11DRV_DestroyWindow( HWND hwnd )
|
||||
if (data->whole_window)
|
||||
{
|
||||
TRACE( "win %x xwin %lx/%lx\n", hwnd, data->whole_window, data->client_window );
|
||||
if (thread_data->cursor_window == data->whole_window) thread_data->cursor_window = None;
|
||||
wine_tsx11_lock();
|
||||
XSync( gdi_display, False ); /* flush any reference to this drawable in GDI queue */
|
||||
XDeleteContext( display, data->whole_window, winContext );
|
||||
|
@ -456,6 +456,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
|
||||
ExitProcess(1);
|
||||
}
|
||||
data->process_event_count = 0;
|
||||
data->cursor = None;
|
||||
data->cursor_window = None;
|
||||
NtCurrentTeb()->driver_data = data;
|
||||
return data;
|
||||
}
|
||||
|
@ -324,6 +324,8 @@ struct x11drv_thread_data
|
||||
Display *display;
|
||||
HANDLE display_fd;
|
||||
int process_event_count; /* recursion count for event processing */
|
||||
Cursor cursor; /* current cursor */
|
||||
Window cursor_window; /* current window that contains the cursor */
|
||||
};
|
||||
|
||||
extern struct x11drv_thread_data *x11drv_init_thread_data(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user