4 * Copyright 1993 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
11 #include <X11/Xatom.h>
12 #include <X11/keysym.h>
14 #include "ts_xresource.h"
22 #include "clipboard.h"
39 DECLARE_DEBUG_CHANNEL(event
)
40 DECLARE_DEBUG_CHANNEL(win
)
42 /* X context to associate a hwnd to an X window */
43 extern XContext winContext
;
45 extern Atom wmProtocols
;
46 extern Atom wmDeleteWindow
;
47 extern Atom dndProtocol
;
48 extern Atom dndSelection
;
50 extern void X11DRV_KEYBOARD_UpdateState(void);
51 extern void X11DRV_KEYBOARD_HandleEvent(WND
*pWnd
, XKeyEvent
*event
);
53 #define NB_BUTTONS 3 /* Windows can handle 3 buttons */
55 #define DndNotDnd -1 /* OffiX drag&drop */
67 #define DndURL 128 /* KDE drag&drop */
69 /* EVENT_WaitNetEvent() master fd sets */
71 static fd_set __event_io_set
[3];
72 static int __event_max_fd
= 0;
73 static int __event_x_connection
= 0;
74 static int __wakeup_pipe
[2];
76 static const char * const event_names
[] =
78 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
79 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
80 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
81 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
82 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
83 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
84 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
85 "ClientMessage", "MappingNotify"
88 static void EVENT_ProcessEvent( XEvent
*event
);
91 static void EVENT_Key( HWND hWnd
, XKeyEvent
*event
);
92 static void EVENT_ButtonPress( HWND hWnd
, XButtonEvent
*event
);
93 static void EVENT_ButtonRelease( HWND hWnd
, XButtonEvent
*event
);
94 static void EVENT_MotionNotify( HWND hWnd
, XMotionEvent
*event
);
95 static void EVENT_FocusIn( HWND hWnd
, XFocusChangeEvent
*event
);
96 static void EVENT_FocusOut( HWND hWnd
, XFocusChangeEvent
*event
);
97 static void EVENT_Expose( HWND hWnd
, XExposeEvent
*event
);
98 static void EVENT_GraphicsExpose( HWND hWnd
, XGraphicsExposeEvent
*event
);
99 static void EVENT_ConfigureNotify( HWND hWnd
, XConfigureEvent
*event
);
100 static void EVENT_SelectionRequest( HWND hWnd
, XSelectionRequestEvent
*event
);
101 static void EVENT_SelectionClear( HWND hWnd
, XSelectionClearEvent
*event
);
102 static void EVENT_ClientMessage( HWND hWnd
, XClientMessageEvent
*event
);
103 static void EVENT_MapNotify( HWND pWnd
, XMapEvent
*event
);
104 static void EVENT_UnmapNotify( HWND pWnd
, XUnmapEvent
*event
);
106 /* Usable only with OLVWM - compile option perhaps?
107 static void EVENT_EnterNotify( HWND hWnd, XCrossingEvent *event );
110 static void EVENT_GetGeometry( Window win
, int *px
, int *py
,
111 unsigned int *pwidth
, unsigned int *pheight
);
114 /***********************************************************************
117 * Initialize network IO.
119 BOOL
X11DRV_EVENT_Init(void)
122 for( i
= 0; i
< 3; i
++ )
123 FD_ZERO( __event_io_set
+ i
);
125 __event_max_fd
= __event_x_connection
= ConnectionNumber(display
);
126 FD_SET( __event_x_connection
, &__event_io_set
[EVENT_IO_READ
] );
128 /* this pipe is used to be able to wake-up the scheduler(WaitNetEvent) by
129 a 32 bit thread, this will become obsolete when the input thread will be
133 /* make the pipe non-blocking */
134 fcntl(__wakeup_pipe
[0], F_SETFL
, O_NONBLOCK
);
135 fcntl(__wakeup_pipe
[1], F_SETFL
, O_NONBLOCK
);
137 FD_SET( __wakeup_pipe
[0], &__event_io_set
[EVENT_IO_READ
] );
138 if (__wakeup_pipe
[0] > __event_max_fd
)
139 __event_max_fd
= __wakeup_pipe
[0];
145 /***********************************************************************
148 void X11DRV_EVENT_AddIO( int fd
, unsigned io_type
)
150 FD_SET( fd
, &__event_io_set
[io_type
] );
151 if( __event_max_fd
<= fd
) __event_max_fd
= fd
+ 1;
154 /***********************************************************************
155 * X11DRV_EVENT_DeleteIO
157 void X11DRV_EVENT_DeleteIO( int fd
, unsigned io_type
)
159 FD_CLR( fd
, &__event_io_set
[io_type
] );
162 /***********************************************************************
163 * X11DRV_EVENT_IsUserIdle
165 BOOL16
X11DRV_EVENT_IsUserIdle(void)
167 struct timeval timeout
= {0, 0};
171 FD_SET(__event_x_connection
, &check_set
);
172 if( select(__event_x_connection
+ 1, &check_set
, NULL
, NULL
, &timeout
) > 0 )
178 /***********************************************************************
179 * EVENT_ReadWakeUpPipe
181 * Empty the wake up pipe
183 void EVENT_ReadWakeUpPipe(void)
188 EnterCriticalSection(&X11DRV_CritSection
);
190 /* Flush the wake-up pipe, it's just dummy data for waking-up this
191 thread. This will be obsolete when the input thread will be done */
192 while ( (ret
= read(__wakeup_pipe
[0], &tmpBuf
, 10)) == 10 );
194 LeaveCriticalSection(&X11DRV_CritSection
);
197 /***********************************************************************
198 * X11DRV_EVENT_WaitNetEvent
200 * Wait for a network event, optionally sleeping until one arrives.
201 * Returns TRUE if an event is pending that cannot be processed in
202 * 'peek' mode, FALSE otherwise.
205 BOOL
X11DRV_EVENT_WaitNetEvent( BOOL sleep
, BOOL peek
)
208 LONG maxWait
= sleep
? TIMER_GetNextExpiration() : 0;
209 int pending
= TSXPending(display
);
211 /* Wait for an event or a timeout. If maxWait is -1, we have no timeout;
212 * in this case, we fall through directly to the XNextEvent loop.
215 if ((maxWait
!= -1) && !pending
)
218 struct timeval timeout
;
221 memcpy( io_set
, __event_io_set
, sizeof(io_set
) );
223 timeout
.tv_usec
= (maxWait
% 1000) * 1000;
224 timeout
.tv_sec
= maxWait
/ 1000;
227 sigsetjmp(env_wait_x
, 1);
230 if (DDE_GetRemoteMessage()) {
231 while(DDE_GetRemoteMessage())
235 stop_wait_op
= STOP_WAIT_X
;
236 /* The code up to the next "stop_wait_op = CONT" must be reentrant */
237 num_pending
= select( __event_max_fd
, &io_set
[EVENT_IO_READ
],
238 &io_set
[EVENT_IO_WRITE
],
239 &io_set
[EVENT_IO_EXCEPT
], &timeout
);
240 if ( num_pending
== 0 )
243 TIMER_ExpireTimers();
246 else stop_wait_op
= CONT
;
247 #else /* CONFIG_IPC */
248 num_pending
= select( __event_max_fd
, &io_set
[EVENT_IO_READ
],
249 &io_set
[EVENT_IO_WRITE
],
250 &io_set
[EVENT_IO_EXCEPT
], &timeout
);
252 if ( num_pending
== 0)
254 /* Timeout or error */
255 TIMER_ExpireTimers();
258 #endif /* CONFIG_IPC */
260 /* Flush the wake-up pipe, it's just dummy data for waking-up this
261 thread. This will be obsolete when the input thread will be done */
262 if ( FD_ISSET( __wakeup_pipe
[0], &io_set
[EVENT_IO_READ
] ) )
265 EVENT_ReadWakeUpPipe();
268 /* Winsock asynchronous services */
270 if( FD_ISSET( __event_x_connection
, &io_set
[EVENT_IO_READ
]) )
274 WINSOCK_HandleIO( &__event_max_fd
, num_pending
, io_set
, __event_io_set
);
276 else /* no X events */
278 WINSOCK_HandleIO( &__event_max_fd
, num_pending
, io_set
, __event_io_set
);
283 { /* Wait for X11 input. */
288 FD_SET(__event_x_connection
, &set
);
290 /* wait on wake-up pipe also */
291 FD_SET(__wakeup_pipe
[0], &set
);
292 if (__event_x_connection
> __wakeup_pipe
[0])
293 max_fd
= __event_x_connection
+ 1;
295 max_fd
= __wakeup_pipe
[0] + 1;
297 select(max_fd
, &set
, 0, 0, 0 );
299 /* Flush the wake-up pipe, it's just dummy data for waking-up this
300 thread. This will be obsolete when the input thread will be done */
301 if ( FD_ISSET( __wakeup_pipe
[0], &set
) )
302 EVENT_ReadWakeUpPipe();
305 /* Process current X event (and possibly others that occurred in the meantime) */
307 EnterCriticalSection(&X11DRV_CritSection
);
308 while (XPending( display
))
312 if (DDE_GetRemoteMessage())
314 LeaveCriticalSection(&X11DRV_CritSection
);
315 while(DDE_GetRemoteMessage()) ;
318 #endif /* CONFIG_IPC */
320 XNextEvent( display
, &event
);
324 /* Check only for those events which can be processed
327 if( event
.type
== MotionNotify
||
328 event
.type
== ButtonPress
|| event
.type
== ButtonRelease
||
329 event
.type
== KeyPress
|| event
.type
== KeyRelease
||
330 event
.type
== SelectionRequest
|| event
.type
== SelectionClear
||
331 event
.type
== ClientMessage
)
333 LeaveCriticalSection(&X11DRV_CritSection
);
334 EVENT_ProcessEvent( &event
);
335 EnterCriticalSection(&X11DRV_CritSection
);
339 if ( event
.type
== NoExpose
)
342 XPutBackEvent(display
, &event
);
343 LeaveCriticalSection(&X11DRV_CritSection
);
348 LeaveCriticalSection(&X11DRV_CritSection
);
349 EVENT_ProcessEvent( &event
);
350 EnterCriticalSection(&X11DRV_CritSection
);
353 LeaveCriticalSection(&X11DRV_CritSection
);
358 /***********************************************************************
361 * Synchronize with the X server. Should not be used too often.
363 void X11DRV_EVENT_Synchronize()
367 /* Use of the X critical section is needed or we have a small
368 * race between XPending() and XNextEvent().
370 EnterCriticalSection( &X11DRV_CritSection
);
371 XSync( display
, False
);
372 while (XPending( display
))
374 XNextEvent( display
, &event
);
375 /* unlock X critsection for EVENT_ProcessEvent() might switch tasks */
376 LeaveCriticalSection( &X11DRV_CritSection
);
377 EVENT_ProcessEvent( &event
);
378 EnterCriticalSection( &X11DRV_CritSection
);
380 LeaveCriticalSection( &X11DRV_CritSection
);
383 /***********************************************************************
386 * Process an X event.
388 static void EVENT_ProcessEvent( XEvent
*event
)
395 case SelectionNotify
: /* all of these should be caught by XCheckTypedWindowEvent() */
396 FIXME(event
,"Got SelectionNotify - must not happen!\n");
399 /* We get all these because of StructureNotifyMask.
400 This check is placed here to avoid getting error messages below,
401 as X might send some of these even for windows that have already
403 case CirculateNotify
:
411 if ( TSXFindContext( display
, event
->xany
.window
, winContext
,
412 (char **)&pWnd
) != 0) {
413 if ( event
->type
== ClientMessage
) {
414 /* query window (drag&drop event contains only drag window) */
416 int root_x
, root_y
, child_x
, child_y
;
418 TSXQueryPointer( display
, X11DRV_GetXRootWindow(), &root
, &child
,
419 &root_x
, &root_y
, &child_x
, &child_y
, &u
);
420 if (TSXFindContext( display
, child
, winContext
, (char **)&pWnd
) != 0)
423 pWnd
= NULL
; /* Not for a registered window */
427 WIN_LockWndPtr(pWnd
);
432 hWnd
= pWnd
->hwndSelf
;
435 if ( !pWnd
&& event
->xany
.window
!= X11DRV_GetXRootWindow() )
436 ERR( event
, "Got event %s for unknown Window %08lx\n",
437 event_names
[event
->type
], event
->xany
.window
);
439 TRACE( event
, "Got event %s for hwnd %04x\n",
440 event_names
[event
->type
], hWnd
);
442 WIN_ReleaseWndPtr(pWnd
);
449 EVENT_Key( hWnd
, (XKeyEvent
*)event
);
453 EVENT_ButtonPress( hWnd
, (XButtonEvent
*)event
);
457 EVENT_ButtonRelease( hWnd
, (XButtonEvent
*)event
);
461 /* Wine between two fast machines across the overloaded campus
462 ethernet gets very boged down in MotionEvents. The following
463 simply finds the last motion event in the queue and drops
464 the rest. On a good link events are servered before they build
465 up so this doesn't take place. On a slow link this may cause
466 problems if the event order is important. I'm not yet seen
467 of any problems. Jon 7/6/96.
469 while (TSXCheckTypedWindowEvent(display
,((XAnyEvent
*)event
)->window
,
470 MotionNotify
, event
));
471 EVENT_MotionNotify( hWnd
, (XMotionEvent
*)event
);
476 EVENT_FocusIn( hWnd
, (XFocusChangeEvent
*)event
);
481 EVENT_FocusOut( hWnd
, (XFocusChangeEvent
*)event
);
485 EVENT_Expose( hWnd
, (XExposeEvent
*)event
);
489 EVENT_GraphicsExpose( hWnd
, (XGraphicsExposeEvent
*)event
);
492 case ConfigureNotify
:
494 EVENT_ConfigureNotify( hWnd
, (XConfigureEvent
*)event
);
497 case SelectionRequest
:
499 EVENT_SelectionRequest( hWnd
, (XSelectionRequestEvent
*)event
);
504 EVENT_SelectionClear( hWnd
, (XSelectionClearEvent
*) event
);
509 EVENT_ClientMessage( hWnd
, (XClientMessageEvent
*) event
);
514 EVENT_EnterNotify( hWnd
, (XCrossingEvent
*) event
);
523 EVENT_MapNotify( hWnd
, (XMapEvent
*)event
);
528 EVENT_UnmapNotify( hWnd
, (XUnmapEvent
*)event
);
532 WARN(event
, "Unprocessed event %s for hwnd %04x\n",
533 event_names
[event
->type
], hWnd
);
538 /***********************************************************************
541 * Synchronize internal z-order with the window manager's.
543 static BOOL
__check_query_condition( WND
** pWndA
, WND
** pWndB
)
545 /* return TRUE if we have at least two managed windows */
547 for( *pWndB
= NULL
; *pWndA
; *pWndA
= (*pWndA
)->next
)
548 if( (*pWndA
)->flags
& WIN_MANAGED
&&
549 (*pWndA
)->dwStyle
& WS_VISIBLE
) break;
551 for( *pWndB
= (*pWndA
)->next
; *pWndB
; *pWndB
= (*pWndB
)->next
)
552 if( (*pWndB
)->flags
& WIN_MANAGED
&&
553 (*pWndB
)->dwStyle
& WS_VISIBLE
) break;
554 return ((*pWndB
) != NULL
);
557 static Window
__get_common_ancestor( Window A
, Window B
,
558 Window
** children
, unsigned* total
)
560 /* find the real root window */
562 Window root
, *childrenB
;
567 TSXQueryTree( display
, A
, &root
, &A
, children
, total
);
568 TSXQueryTree( display
, B
, &root
, &B
, &childrenB
, &totalB
);
569 if( childrenB
) TSXFree( childrenB
);
570 if( *children
) TSXFree( *children
);
571 } while( A
!= B
&& A
&& B
);
575 TSXQueryTree( display
, A
, &root
, &B
, children
, total
);
581 static Window
__get_top_decoration( Window w
, Window ancestor
)
583 Window
* children
, root
, prev
= w
, parent
= w
;
589 TSXQueryTree( display
, w
, &root
, &parent
, &children
, &total
);
590 if( children
) TSXFree( children
);
591 } while( parent
&& parent
!= ancestor
);
592 TRACE(event
, "\t%08x -> %08x\n", (unsigned)prev
, (unsigned)w
);
593 return ( parent
) ? w
: 0 ;
596 static unsigned __td_lookup( Window w
, Window
* list
, unsigned max
)
599 for( i
= max
- 1; i
>= 0; i
-- ) if( list
[i
] == w
) break;
603 static BOOL
EVENT_QueryZOrder( HWND hWndCheck
)
606 HWND hwndInsertAfter
= HWND_TOP
;
607 WND
*pWndCheck
= WIN_FindWndPtr(hWndCheck
);
608 WND
*pDesktop
= WIN_GetDesktop();
609 WND
*pWnd
, *pWndZ
= WIN_LockWndPtr(pDesktop
->child
);
610 Window w
, parent
, *children
= NULL
;
611 unsigned total
, check
, pos
, best
;
613 if( !__check_query_condition(&pWndZ
, &pWnd
) )
615 WIN_ReleaseWndPtr(pWndCheck
);
616 WIN_ReleaseWndPtr(pDesktop
->child
);
617 WIN_ReleaseDesktop();
620 WIN_LockWndPtr(pWndZ
);
621 WIN_LockWndPtr(pWnd
);
622 WIN_ReleaseWndPtr(pDesktop
->child
);
623 WIN_ReleaseDesktop();
625 parent
= __get_common_ancestor( X11DRV_WND_GetXWindow(pWndZ
),
626 X11DRV_WND_GetXWindow(pWnd
),
628 if( parent
&& children
)
630 /* w is the ancestor if pWndCheck that is a direct descendant of 'parent' */
632 w
= __get_top_decoration( X11DRV_WND_GetXWindow(pWndCheck
), parent
);
634 if( w
!= children
[total
-1] ) /* check if at the top */
636 /* X child at index 0 is at the bottom, at index total-1 is at the top */
637 check
= __td_lookup( w
, children
, total
);
640 for( WIN_UpdateWndPtr(&pWnd
,pWndZ
); pWnd
;WIN_UpdateWndPtr(&pWnd
,pWnd
->next
))
642 /* go through all windows in Wine z-order... */
644 if( pWnd
!= pWndCheck
)
646 if( !(pWnd
->flags
& WIN_MANAGED
) ||
647 !(w
= __get_top_decoration( X11DRV_WND_GetXWindow(pWnd
), parent
)) )
649 pos
= __td_lookup( w
, children
, total
);
650 if( pos
< best
&& pos
> check
)
652 /* find a nearest Wine window precedes
653 * pWndCheck in the real z-order... */
655 hwndInsertAfter
= pWnd
->hwndSelf
;
657 if( best
- check
== 1 ) break;
660 /* and link pWndCheck right behind it in the local z-order */
662 WIN_UnlinkWindow( pWndCheck
->hwndSelf
);
663 WIN_LinkWindow( pWndCheck
->hwndSelf
, hwndInsertAfter
);
665 if( children
) TSXFree( children
);
666 WIN_ReleaseWndPtr(pWnd
);
667 WIN_ReleaseWndPtr(pWndZ
);
668 WIN_ReleaseWndPtr(pWndCheck
);
672 /***********************************************************************
673 * EVENT_XStateToKeyState
675 * Translate a X event state (Button1Mask, ShiftMask, etc...) to
676 * a Windows key state (MK_SHIFT, MK_CONTROL, etc...)
678 static WORD
EVENT_XStateToKeyState( int state
)
682 if (state
& Button1Mask
) kstate
|= MK_LBUTTON
;
683 if (state
& Button2Mask
) kstate
|= MK_MBUTTON
;
684 if (state
& Button3Mask
) kstate
|= MK_RBUTTON
;
685 if (state
& ShiftMask
) kstate
|= MK_SHIFT
;
686 if (state
& ControlMask
) kstate
|= MK_CONTROL
;
690 /***********************************************************************
691 * X11DRV_EVENT_QueryPointer
693 BOOL
X11DRV_EVENT_QueryPointer(DWORD
*posX
, DWORD
*posY
, DWORD
*state
)
696 int rootX
, rootY
, winX
, winY
;
699 if (!TSXQueryPointer( display
, X11DRV_GetXRootWindow(), &root
, &child
,
700 &rootX
, &rootY
, &winX
, &winY
, &xstate
))
708 *state
= EVENT_XStateToKeyState( xstate
);
713 /***********************************************************************
716 static void EVENT_Expose( HWND hWnd
, XExposeEvent
*event
)
720 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
721 /* Make position relative to client area instead of window */
722 rect
.left
= event
->x
- (pWnd
? (pWnd
->rectClient
.left
- pWnd
->rectWindow
.left
) : 0);
723 rect
.top
= event
->y
- (pWnd
? (pWnd
->rectClient
.top
- pWnd
->rectWindow
.top
) : 0);
724 rect
.right
= rect
.left
+ event
->width
;
725 rect
.bottom
= rect
.top
+ event
->height
;
726 WIN_ReleaseWndPtr(pWnd
);
728 Callout
.RedrawWindow( hWnd
, &rect
, 0,
729 RDW_INVALIDATE
| RDW_FRAME
| RDW_ALLCHILDREN
| RDW_ERASE
|
730 (event
->count
? 0 : RDW_ERASENOW
) );
734 /***********************************************************************
735 * EVENT_GraphicsExpose
737 * This is needed when scrolling area is partially obscured
738 * by non-Wine X window.
740 static void EVENT_GraphicsExpose( HWND hWnd
, XGraphicsExposeEvent
*event
)
743 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
745 /* Make position relative to client area instead of window */
746 rect
.left
= event
->x
- (pWnd
? (pWnd
->rectClient
.left
- pWnd
->rectWindow
.left
) : 0);
747 rect
.top
= event
->y
- (pWnd
? (pWnd
->rectClient
.top
- pWnd
->rectWindow
.top
) : 0);
748 rect
.right
= rect
.left
+ event
->width
;
749 rect
.bottom
= rect
.top
+ event
->height
;
751 WIN_ReleaseWndPtr(pWnd
);
753 Callout
.RedrawWindow( hWnd
, &rect
, 0,
754 RDW_INVALIDATE
| RDW_ALLCHILDREN
| RDW_ERASE
|
755 (event
->count
? 0 : RDW_ERASENOW
) );
759 /***********************************************************************
762 * Handle a X key event
764 static void EVENT_Key( HWND hWnd
, XKeyEvent
*event
)
766 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
767 X11DRV_KEYBOARD_HandleEvent( pWnd
, event
);
768 WIN_ReleaseWndPtr(pWnd
);
773 /***********************************************************************
776 static void EVENT_MotionNotify( HWND hWnd
, XMotionEvent
*event
)
778 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
779 int xOffset
= pWnd
? pWnd
->rectWindow
.left
: 0;
780 int yOffset
= pWnd
? pWnd
->rectWindow
.top
: 0;
781 WIN_ReleaseWndPtr(pWnd
);
783 MOUSE_SendEvent( MOUSEEVENTF_MOVE
,
784 xOffset
+ event
->x
, yOffset
+ event
->y
,
785 EVENT_XStateToKeyState( event
->state
),
786 event
->time
- MSG_WineStartTicks
,
791 /***********************************************************************
792 * X11DRV_EVENT_DummyMotionNotify
794 * Generate a dummy MotionNotify event. Used to force a WM_SETCURSOR message.
796 void X11DRV_EVENT_DummyMotionNotify(void)
798 DWORD winX
, winY
, state
;
800 if ( EVENT_QueryPointer( &winX
, &winY
, &state
) )
802 MOUSE_SendEvent( MOUSEEVENTF_MOVE
, winX
, winY
, state
,
808 /***********************************************************************
811 static void EVENT_ButtonPress( HWND hWnd
, XButtonEvent
*event
)
813 static WORD statusCodes
[NB_BUTTONS
] =
814 { MOUSEEVENTF_LEFTDOWN
, MOUSEEVENTF_MIDDLEDOWN
, MOUSEEVENTF_RIGHTDOWN
};
815 int buttonNum
= event
->button
- 1;
817 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
818 int xOffset
= pWnd
? pWnd
->rectWindow
.left
: 0;
819 int yOffset
= pWnd
? pWnd
->rectWindow
.top
: 0;
822 WIN_ReleaseWndPtr(pWnd
);
824 if (buttonNum
>= NB_BUTTONS
) return;
827 * Get the compatible keystate
829 keystate
= EVENT_XStateToKeyState( event
->state
);
832 * Make sure that the state of the button that was just
838 keystate
|= MK_LBUTTON
;
841 keystate
|= MK_MBUTTON
;
844 keystate
|= MK_RBUTTON
;
848 MOUSE_SendEvent( statusCodes
[buttonNum
],
849 xOffset
+ event
->x
, yOffset
+ event
->y
,
851 event
->time
- MSG_WineStartTicks
,
856 /***********************************************************************
857 * EVENT_ButtonRelease
859 static void EVENT_ButtonRelease( HWND hWnd
, XButtonEvent
*event
)
861 static WORD statusCodes
[NB_BUTTONS
] =
862 { MOUSEEVENTF_LEFTUP
, MOUSEEVENTF_MIDDLEUP
, MOUSEEVENTF_RIGHTUP
};
863 int buttonNum
= event
->button
- 1;
864 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
865 int xOffset
= pWnd
? pWnd
->rectWindow
.left
: 0;
866 int yOffset
= pWnd
? pWnd
->rectWindow
.top
: 0;
869 WIN_ReleaseWndPtr(pWnd
);
871 if (buttonNum
>= NB_BUTTONS
) return;
874 * Get the compatible keystate
876 keystate
= EVENT_XStateToKeyState( event
->state
);
879 * Make sure that the state of the button that was just
885 keystate
&= ~MK_LBUTTON
;
888 keystate
&= ~MK_MBUTTON
;
891 keystate
&= ~MK_RBUTTON
;
895 MOUSE_SendEvent( statusCodes
[buttonNum
],
896 xOffset
+ event
->x
, yOffset
+ event
->y
,
898 event
->time
- MSG_WineStartTicks
,
903 /**********************************************************************
906 static void EVENT_FocusIn( HWND hWnd
, XFocusChangeEvent
*event
)
908 if (Options
.managed
) EVENT_QueryZOrder( hWnd
);
910 if (event
->detail
!= NotifyPointer
)
912 if (hWnd
!= GetActiveWindow())
914 WINPOS_ChangeActiveWindow( hWnd
, FALSE
);
915 X11DRV_KEYBOARD_UpdateState();
917 if ((hWnd
!= GetFocus()) && !IsChild( hWnd
, GetFocus()))
923 /**********************************************************************
926 * Note: only top-level override-redirect windows get FocusOut events.
928 static void EVENT_FocusOut( HWND hWnd
, XFocusChangeEvent
*event
)
930 if (event
->detail
!= NotifyPointer
)
932 if (hWnd
== GetActiveWindow())
934 SendMessageA( hWnd
, WM_CANCELMODE
, 0, 0 );
935 WINPOS_ChangeActiveWindow( 0, FALSE
);
937 if ((hWnd
== GetFocus()) || IsChild( hWnd
, GetFocus()))
942 /**********************************************************************
943 * X11DRV_EVENT_CheckFocus
945 BOOL
X11DRV_EVENT_CheckFocus(void)
951 TSXGetInputFocus(display
, &xW
, &state
);
953 TSXFindContext(display
, xW
, winContext
, (char **)&pWnd
) )
958 /**********************************************************************
961 * Helper function for ConfigureNotify handling.
962 * Get the new geometry of a window relative to the root window.
964 static void EVENT_GetGeometry( Window win
, int *px
, int *py
,
965 unsigned int *pwidth
, unsigned int *pheight
)
967 Window root
, parent
, *children
;
969 unsigned int width
, height
, border
, depth
, nb_children
;
971 if (!TSXGetGeometry( display
, win
, &root
, px
, py
, pwidth
, pheight
,
972 &border
, &depth
)) return;
973 if (win
== X11DRV_GetXRootWindow())
981 if (!TSXQueryTree(display
, win
, &root
, &parent
, &children
, &nb_children
))
984 if (parent
== X11DRV_GetXRootWindow()) break;
986 if (!TSXGetGeometry( display
, win
, &root
, &xpos
, &ypos
,
987 &width
, &height
, &border
, &depth
)) return;
994 /**********************************************************************
995 * EVENT_ConfigureNotify
997 * The ConfigureNotify event is only selected on top-level windows
998 * when the -managed flag is used.
1000 static void EVENT_ConfigureNotify( HWND hWnd
, XConfigureEvent
*event
)
1003 RECT newWindowRect
, newClientRect
;
1004 RECT oldWindowRect
, oldClientRect
;
1005 Window above
= event
->above
;
1007 unsigned int width
, height
;
1009 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
1010 assert (pWnd
->flags
& WIN_MANAGED
);
1012 /* We don't rely on the event geometry info, because it is relative
1013 * to parent and not to root, and it may be wrong (XFree sets x,y to 0,0
1014 * if the window hasn't moved).
1016 EVENT_GetGeometry( event
->window
, &x
, &y
, &width
, &height
);
1018 TRACE(win
, "%04x adjusted to (%i,%i)-(%i,%i)\n", pWnd
->hwndSelf
,
1019 x
, y
, x
+ width
, y
+ height
);
1021 /* Fill WINDOWPOS struct */
1022 winpos
.flags
= SWP_NOACTIVATE
| SWP_NOZORDER
;
1029 /* Check for unchanged attributes */
1030 if (winpos
.x
== pWnd
->rectWindow
.left
&& winpos
.y
== pWnd
->rectWindow
.top
)
1031 winpos
.flags
|= SWP_NOMOVE
;
1032 if ((winpos
.cx
== pWnd
->rectWindow
.right
- pWnd
->rectWindow
.left
) &&
1033 (winpos
.cy
== pWnd
->rectWindow
.bottom
- pWnd
->rectWindow
.top
))
1034 winpos
.flags
|= SWP_NOSIZE
;
1041 rect
.right
= pWnd
->rectWindow
.right
- pWnd
->rectWindow
.left
;
1042 rect
.bottom
= pWnd
->rectWindow
.bottom
- pWnd
->rectWindow
.top
;
1044 DCE_InvalidateDCE( pWnd
, &rect
);
1047 /* Send WM_WINDOWPOSCHANGING */
1048 SendMessageA( winpos
.hwnd
, WM_WINDOWPOSCHANGING
, 0, (LPARAM
)&winpos
);
1050 if (!IsWindow( winpos
.hwnd
))
1052 WIN_ReleaseWndPtr(pWnd
);
1056 /* Calculate new position and size */
1057 newWindowRect
.left
= x
;
1058 newWindowRect
.right
= x
+ width
;
1059 newWindowRect
.top
= y
;
1060 newWindowRect
.bottom
= y
+ height
;
1062 WINPOS_SendNCCalcSize( winpos
.hwnd
, TRUE
, &newWindowRect
,
1063 &pWnd
->rectWindow
, &pWnd
->rectClient
,
1064 &winpos
, &newClientRect
);
1066 if (!IsWindow( winpos
.hwnd
))
1068 WIN_ReleaseWndPtr(pWnd
);
1072 oldWindowRect
= pWnd
->rectWindow
;
1073 oldClientRect
= pWnd
->rectClient
;
1075 /* Set new size and position */
1076 pWnd
->rectWindow
= newWindowRect
;
1077 pWnd
->rectClient
= newClientRect
;
1079 /* FIXME: Copy valid bits */
1081 if( oldClientRect
.top
- oldWindowRect
.top
!= newClientRect
.top
- newWindowRect
.top
||
1082 oldClientRect
.left
- oldWindowRect
.left
!= newClientRect
.left
- newWindowRect
.left
)
1083 RedrawWindow( winpos
.hwnd
, NULL
, 0, RDW_FRAME
| RDW_ALLCHILDREN
|
1084 RDW_INVALIDATE
| RDW_ERASE
| RDW_ERASENOW
);
1086 WIN_ReleaseWndPtr(pWnd
);
1088 SendMessageA( winpos
.hwnd
, WM_WINDOWPOSCHANGED
, 0, (LPARAM
)&winpos
);
1090 if (!IsWindow( winpos
.hwnd
)) return;
1091 if( above
== None
) /* absolute bottom */
1093 WIN_UnlinkWindow( winpos
.hwnd
);
1094 WIN_LinkWindow( winpos
.hwnd
, HWND_BOTTOM
);
1096 else EVENT_QueryZOrder( hWnd
); /* try to outsmart window manager */
1100 /***********************************************************************
1101 * EVENT_SelectionRequest
1103 static void EVENT_SelectionRequest( HWND hWnd
, XSelectionRequestEvent
*event
)
1105 XSelectionEvent result
;
1107 Window request
= event
->requestor
;
1109 if(event
->target
== XA_STRING
)
1115 rprop
= event
->property
;
1118 rprop
= event
->target
;
1120 if( event
->selection
!= XA_PRIMARY
)
1123 if( !CLIPBOARD_IsPresent(CF_OEMTEXT
) )
1127 /* open to make sure that clipboard is available */
1129 BOOL couldOpen
= OpenClipboard( hWnd
);
1132 hText
= GetClipboardData16(CF_TEXT
);
1133 text
= GlobalLock16(hText
);
1134 size
= GlobalSize16(hText
);
1136 /* remove carriage returns */
1138 lpstr
= (char*)HEAP_xalloc( GetProcessHeap(), 0, size
-- );
1139 for(i
=0,j
=0; i
< size
&& text
[i
]; i
++ )
1141 if( text
[i
] == '\r' &&
1142 (text
[i
+1] == '\n' || text
[i
+1] == '\0') ) continue;
1143 lpstr
[j
++] = text
[i
];
1147 TSXChangeProperty(display
, request
, rprop
,
1148 XA_STRING
, 8, PropModeReplace
,
1150 HeapFree( GetProcessHeap(), 0, lpstr
);
1152 /* close only if we opened before */
1154 if(couldOpen
) CloseClipboard();
1159 TRACE(event
,"Request for %s ignored\n", TSXGetAtomName(display
,event
->target
));
1161 /* reply to sender */
1163 result
.type
= SelectionNotify
;
1164 result
.display
= display
;
1165 result
.requestor
= request
;
1166 result
.selection
= event
->selection
;
1167 result
.property
= rprop
;
1168 result
.target
= event
->target
;
1169 result
.time
= event
->time
;
1170 TSXSendEvent(display
,event
->requestor
,False
,NoEventMask
,(XEvent
*)&result
);
1173 /***********************************************************************
1174 * EVENT_SelectionClear
1176 static void EVENT_SelectionClear( HWND hWnd
, XSelectionClearEvent
*event
)
1178 if (event
->selection
!= XA_PRIMARY
) return;
1179 X11DRV_CLIPBOARD_ReleaseSelection( event
->window
, hWnd
);
1183 /**********************************************************************
1184 * EVENT_DropFromOffix
1186 * don't know if it still works (last Changlog is from 96/11/04)
1188 static void EVENT_DropFromOffiX( HWND hWnd
, XClientMessageEvent
*event
)
1190 unsigned long data_length
;
1191 unsigned long aux_long
;
1192 unsigned char* p_data
= NULL
;
1203 HGLOBAL16 hDragInfo
= GlobalAlloc16( GMEM_SHARE
| GMEM_ZEROINIT
, sizeof(DRAGINFO
));
1204 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
) GlobalLock16(hDragInfo
);
1205 SEGPTR spDragInfo
= (SEGPTR
) WIN16_GlobalLock16(hDragInfo
);
1206 Window w_aux_root
, w_aux_child
;
1210 if( !lpDragInfo
|| !spDragInfo
) return;
1212 pWnd
= WIN_FindWndPtr(hWnd
);
1214 TSXQueryPointer( display
, X11DRV_WND_GetXWindow(pWnd
), &w_aux_root
, &w_aux_child
,
1215 &x
, &y
, (int *) &u
.pt_aux
.x
, (int *) &u
.pt_aux
.y
,
1216 (unsigned int*)&aux_long
);
1218 lpDragInfo
->hScope
= hWnd
;
1219 lpDragInfo
->pt
.x
= (INT16
)x
; lpDragInfo
->pt
.y
= (INT16
)y
;
1221 /* find out drop point and drop window */
1222 if( x
< 0 || y
< 0 ||
1223 x
> (pWnd
->rectWindow
.right
- pWnd
->rectWindow
.left
) ||
1224 y
> (pWnd
->rectWindow
.bottom
- pWnd
->rectWindow
.top
) )
1225 { bAccept
= pWnd
->dwExStyle
& WS_EX_ACCEPTFILES
; x
= y
= 0; }
1228 bAccept
= DRAG_QueryUpdate( hWnd
, spDragInfo
, TRUE
);
1229 x
= lpDragInfo
->pt
.x
; y
= lpDragInfo
->pt
.y
;
1231 pDropWnd
= WIN_FindWndPtr( lpDragInfo
->hScope
);
1232 WIN_ReleaseWndPtr(pWnd
);
1234 GlobalFree16( hDragInfo
);
1238 TSXGetWindowProperty( display
, DefaultRootWindow(display
),
1239 dndSelection
, 0, 65535, FALSE
,
1240 AnyPropertyType
, &u
.atom_aux
, (int *) &u
.pt_aux
.y
,
1241 &data_length
, &aux_long
, &p_data
);
1243 if( !aux_long
&& p_data
) /* don't bother if > 64K */
1245 char *p
= (char*) p_data
;
1249 while( *p
) /* calculate buffer size */
1252 if((u
.i
= *p
) != -1 )
1253 u
.i
= DRIVE_FindDriveRoot( (const char **)&p_drop
);
1254 if( u
.i
== -1 ) *p
= -1; /* mark as "bad" */
1257 INT len
= GetShortPathNameA( p
, NULL
, 0 );
1258 if (len
) aux_long
+= len
+ 1;
1263 if( aux_long
&& aux_long
< 65535 )
1266 LPDROPFILESTRUCT16 lpDrop
;
1268 aux_long
+= sizeof(DROPFILESTRUCT16
) + 1;
1269 hDrop
= (HDROP16
)GlobalAlloc16( GMEM_SHARE
, aux_long
);
1270 lpDrop
= (LPDROPFILESTRUCT16
) GlobalLock16( hDrop
);
1274 lpDrop
->wSize
= sizeof(DROPFILESTRUCT16
);
1275 lpDrop
->ptMousePos
.x
= (INT16
)x
;
1276 lpDrop
->ptMousePos
.y
= (INT16
)y
;
1277 lpDrop
->fInNonClientArea
= (BOOL16
)
1278 ( x
< (pDropWnd
->rectClient
.left
- pDropWnd
->rectWindow
.left
) ||
1279 y
< (pDropWnd
->rectClient
.top
- pDropWnd
->rectWindow
.top
) ||
1280 x
> (pDropWnd
->rectClient
.right
- pDropWnd
->rectWindow
.left
) ||
1281 y
> (pDropWnd
->rectClient
.bottom
- pDropWnd
->rectWindow
.top
) );
1282 p_drop
= ((char*)lpDrop
) + sizeof(DROPFILESTRUCT16
);
1286 if( *p
!= -1 ) /* use only "good" entries */
1288 GetShortPathNameA( p
, p_drop
, 65535 );
1289 p_drop
+= strlen( p_drop
) + 1;
1294 PostMessage16( hWnd
, WM_DROPFILES
,
1295 (WPARAM16
)hDrop
, 0L );
1299 if( p_data
) TSXFree(p_data
);
1301 } /* WS_EX_ACCEPTFILES */
1303 WIN_ReleaseWndPtr(pDropWnd
);
1306 /**********************************************************************
1309 * drop items are separated by \n
1310 * each item is prefixed by its mime type
1312 * event->data.l[3], event->data.l[4] contains drop x,y position
1314 static void EVENT_DropURLs( HWND hWnd
, XClientMessageEvent
*event
)
1318 unsigned long data_length
;
1319 unsigned long aux_long
, drop_len
= 0;
1320 unsigned char *p_data
= NULL
; /* property data */
1321 char *p_drop
= NULL
;
1323 int x
, y
, drop32
= FALSE
;
1334 pWnd
= WIN_FindWndPtr(hWnd
);
1335 drop32
= pWnd
->flags
& WIN_ISWIN32
;
1337 if (!(pWnd
->dwExStyle
& WS_EX_ACCEPTFILES
))
1339 WIN_ReleaseWndPtr(pWnd
);
1342 WIN_ReleaseWndPtr(pWnd
);
1344 TSXGetWindowProperty( display
, DefaultRootWindow(display
),
1345 dndSelection
, 0, 65535, FALSE
,
1346 AnyPropertyType
, &u
.atom_aux
, &u
.i
,
1347 &data_length
, &aux_long
, &p_data
);
1349 WARN(event
,"property too large, truncated!\n");
1350 TRACE(event
,"urls=%s\n", p_data
);
1352 if( !aux_long
&& p_data
) { /* don't bother if > 64K */
1353 /* calculate length */
1355 next
= strchr(p
, '\n');
1358 if (strncmp(p
,"file:",5) == 0 ) {
1359 INT len
= GetShortPathNameA( p
+5, NULL
, 0 );
1360 if (len
) drop_len
+= len
+ 1;
1365 next
= strchr(p
, '\n');
1371 if( drop_len
&& drop_len
< 65535 ) {
1372 TSXQueryPointer( display
, X11DRV_GetXRootWindow(), &u
.w_aux
, &u
.w_aux
,
1373 &x
, &y
, &u
.i
, &u
.i
, &u
.i
);
1375 pDropWnd
= WIN_FindWndPtr( hWnd
);
1378 LPDROPFILESTRUCT lpDrop
;
1379 drop_len
+= sizeof(DROPFILESTRUCT
) + 1;
1380 hDrop
.h32
= (HDROP
)GlobalAlloc( GMEM_SHARE
, drop_len
);
1381 lpDrop
= (LPDROPFILESTRUCT
) GlobalLock( hDrop
.h32
);
1384 lpDrop
->lSize
= sizeof(DROPFILESTRUCT
);
1385 lpDrop
->ptMousePos
.x
= (INT
)x
;
1386 lpDrop
->ptMousePos
.y
= (INT
)y
;
1387 lpDrop
->fInNonClientArea
= (BOOL
)
1388 ( x
< (pDropWnd
->rectClient
.left
- pDropWnd
->rectWindow
.left
) ||
1389 y
< (pDropWnd
->rectClient
.top
- pDropWnd
->rectWindow
.top
) ||
1390 x
> (pDropWnd
->rectClient
.right
- pDropWnd
->rectWindow
.left
) ||
1391 y
> (pDropWnd
->rectClient
.bottom
- pDropWnd
->rectWindow
.top
) );
1392 lpDrop
->fWideChar
= FALSE
;
1393 p_drop
= ((char*)lpDrop
) + sizeof(DROPFILESTRUCT
);
1396 LPDROPFILESTRUCT16 lpDrop
;
1397 drop_len
+= sizeof(DROPFILESTRUCT16
) + 1;
1398 hDrop
.h16
= (HDROP16
)GlobalAlloc16( GMEM_SHARE
, drop_len
);
1399 lpDrop
= (LPDROPFILESTRUCT16
) GlobalLock16( hDrop
.h16
);
1402 lpDrop
->wSize
= sizeof(DROPFILESTRUCT16
);
1403 lpDrop
->ptMousePos
.x
= (INT16
)x
;
1404 lpDrop
->ptMousePos
.y
= (INT16
)y
;
1405 lpDrop
->fInNonClientArea
= (BOOL16
)
1406 ( x
< (pDropWnd
->rectClient
.left
- pDropWnd
->rectWindow
.left
) ||
1407 y
< (pDropWnd
->rectClient
.top
- pDropWnd
->rectWindow
.top
) ||
1408 x
> (pDropWnd
->rectClient
.right
- pDropWnd
->rectWindow
.left
) ||
1409 y
> (pDropWnd
->rectClient
.bottom
- pDropWnd
->rectWindow
.top
) );
1410 p_drop
= ((char*)lpDrop
) + sizeof(DROPFILESTRUCT16
);
1414 /* create message content */
1417 next
= strchr(p
, '\n');
1420 if (strncmp(p
,"file:",5) == 0 ) {
1421 INT len
= GetShortPathNameA( p
+5, p_drop
, 65535 );
1423 TRACE(event
, "drop file %s as %s\n", p
+5, p_drop
);
1426 WARN(event
, "can't convert file %s to dos name \n", p
+5);
1429 WARN(event
, "unknown mime type %s\n", p
);
1434 next
= strchr(p
, '\n');
1442 /* can not use PostMessage32A because it is currently based on
1443 * PostMessage16 and WPARAM32 would be truncated to WPARAM16
1445 GlobalUnlock(hDrop
.h32
);
1446 SendMessageA( hWnd
, WM_DROPFILES
,
1447 (WPARAM
)hDrop
.h32
, 0L );
1449 GlobalUnlock16(hDrop
.h16
);
1450 PostMessage16( hWnd
, WM_DROPFILES
,
1451 (WPARAM16
)hDrop
.h16
, 0L );
1454 WIN_ReleaseWndPtr(pDropWnd
);
1456 if( p_data
) TSXFree(p_data
);
1460 /**********************************************************************
1461 * EVENT_ClientMessage
1463 static void EVENT_ClientMessage( HWND hWnd
, XClientMessageEvent
*event
)
1465 if (event
->message_type
!= None
&& event
->format
== 32) {
1466 if ((event
->message_type
== wmProtocols
) &&
1467 (((Atom
) event
->data
.l
[0]) == wmDeleteWindow
))
1469 /* Ignore the delete window request if the window has been disabled
1470 * and we are in managed mode. This is to disallow applications from
1471 * being closed by the window manager while in a modal state.
1474 bIsDisabled
= GetWindowLongA( hWnd
, GWL_STYLE
) & WS_DISABLED
;
1476 if ( !Options
.managed
|| !bIsDisabled
)
1477 SendMessage16( hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0 );
1479 else if ( event
->message_type
== dndProtocol
&&
1480 (event
->data
.l
[0] == DndFile
|| event
->data
.l
[0] == DndFiles
) )
1481 EVENT_DropFromOffiX(hWnd
, event
);
1482 else if ( event
->message_type
== dndProtocol
&&
1483 event
->data
.l
[0] == DndURL
)
1484 EVENT_DropURLs(hWnd
, event
);
1487 /* enable this if you want to see the message */
1488 unsigned char* p_data
= NULL
;
1494 TSXGetWindowProperty( display
, DefaultRootWindow(display
),
1495 dndSelection
, 0, 65535, FALSE
,
1496 AnyPropertyType
, &u
.atom
, &u
.i
,
1497 &u
.l
, &u
.l
, &p_data
);
1498 TRACE(event
, "message_type=%ld, data=%ld,%ld,%ld,%ld,%ld, msg=%s\n",
1499 event
->message_type
, event
->data
.l
[0], event
->data
.l
[1],
1500 event
->data
.l
[2], event
->data
.l
[3], event
->data
.l
[4],
1503 TRACE(event
, "unrecognized ClientMessage\n" );
1508 /**********************************************************************
1511 * Install colormap when Wine window is focused in
1512 * self-managed mode with private colormap
1515 void EVENT_EnterNotify( HWND hWnd
, XCrossingEvent
*event
)
1517 if( !Options
.managed
&& X11DRV_GetXRootWindow() == DefaultRootWindow(display
) &&
1518 (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
) && GetFocus() )
1519 TSXInstallColormap( display
, X11DRV_PALETTE_GetColormap() );
1523 /**********************************************************************
1526 void EVENT_MapNotify( HWND hWnd
, XMapEvent
*event
)
1528 HWND hwndFocus
= GetFocus();
1529 WND
*wndFocus
= WIN_FindWndPtr(hwndFocus
);
1530 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
1531 if (pWnd
->flags
& WIN_MANAGED
)
1532 pWnd
->dwStyle
&= ~WS_MINIMIZE
;
1533 WIN_ReleaseWndPtr(pWnd
);
1535 if (hwndFocus
&& IsChild( hWnd
, hwndFocus
))
1536 X11DRV_WND_SetFocus(wndFocus
);
1538 WIN_ReleaseWndPtr(wndFocus
);
1544 /**********************************************************************
1547 void EVENT_UnmapNotify( HWND hWnd
, XUnmapEvent
*event
)
1549 WND
*pWnd
= WIN_FindWndPtr(hWnd
);
1550 if (pWnd
->flags
& WIN_MANAGED
)
1553 pWnd
->dwStyle
|= WS_MINIMIZE
;
1555 WIN_ReleaseWndPtr(pWnd
);
1559 /**********************************************************************
1560 * X11DRV_EVENT_Pending
1562 BOOL
X11DRV_EVENT_Pending()
1564 return TSXPending(display
);
1567 /**********************************************************************
1568 * X11DRV_EVENT_WakeUp
1570 void X11DRV_EVENT_WakeUp(void)
1572 /* wake-up EVENT_WaitNetEvent function, a 32 bit thread post an event
1573 for a 16 bit task */
1574 if (write (__wakeup_pipe
[1], "A", 1) != 1)
1575 ERR(event
, "unable to write in wakeup_pipe\n");
1579 #endif /* !defined(X_DISPLAY_MISSING) */