Eliminate lots of __WINE__ conditionals from the headers.
[wine/wine64.git] / dlls / x11drv / event.c
blobdfae906c437e0746896d819e978cc4065ac5990c
1 /*
2 * X11 event driver
4 * Copyright 1993 Alexandre Julliard
5 * 1999 Noel Borthwick
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #define COM_NO_WINDOWS_H
23 #include "config.h"
25 #include <X11/Xatom.h>
26 #include <X11/keysym.h>
28 #include "ts_xlib.h"
29 #include <X11/Xresource.h>
30 #include <X11/Xutil.h>
31 #ifdef HAVE_LIBXXF86DGA2
32 #include <X11/extensions/xf86dga.h>
33 #endif
35 #include <assert.h>
36 #include <string.h>
37 #include "wine/winuser16.h"
38 #include "shlobj.h" /* DROPFILES */
40 #include "clipboard.h"
41 #include "win.h"
42 #include "winpos.h"
43 #include "windef.h"
44 #include "winreg.h"
45 #include "x11drv.h"
46 #include "shellapi.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(event);
51 /* X context to associate a hwnd to an X window */
52 extern XContext winContext;
54 extern Atom wmProtocols;
55 extern Atom wmDeleteWindow;
56 extern Atom dndProtocol;
57 extern Atom dndSelection;
59 #define DndNotDnd -1 /* OffiX drag&drop */
60 #define DndUnknown 0
61 #define DndRawData 1
62 #define DndFile 2
63 #define DndFiles 3
64 #define DndText 4
65 #define DndDir 5
66 #define DndLink 6
67 #define DndExe 7
69 #define DndEND 8
71 #define DndURL 128 /* KDE drag&drop */
73 static const char * const event_names[] =
75 "", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
76 "MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut",
77 "KeymapNotify", "Expose", "GraphicsExpose", "NoExpose", "VisibilityNotify",
78 "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", "MapRequest",
79 "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
80 "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify",
81 "SelectionClear", "SelectionRequest", "SelectionNotify", "ColormapNotify",
82 "ClientMessage", "MappingNotify"
86 static void EVENT_ProcessEvent( XEvent *event );
88 /* Event handlers */
89 static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event );
90 static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event );
91 static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple );
92 static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event);
93 static void EVENT_PropertyNotify( XPropertyEvent *event );
94 static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
96 extern void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event );
97 extern void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event );
98 extern void X11DRV_MotionNotify( HWND hwnd, XMotionEvent *event );
99 extern void X11DRV_EnterNotify( HWND hwnd, XCrossingEvent *event );
100 extern void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event );
101 extern void X11DRV_KeymapNotify( HWND hwnd, XKeymapEvent *event );
102 extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event );
103 extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
104 extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
105 extern void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
106 extern void X11DRV_MappingNotify( XMappingEvent *event );
108 #ifdef HAVE_LIBXXF86DGA2
109 static int DGAMotionEventType;
110 static int DGAButtonPressEventType;
111 static int DGAButtonReleaseEventType;
112 static int DGAKeyPressEventType;
113 static int DGAKeyReleaseEventType;
115 static BOOL DGAUsed = FALSE;
116 static HWND DGAhwnd = 0;
118 extern void X11DRV_DGAMotionEvent( HWND hwnd, XDGAMotionEvent *event );
119 extern void X11DRV_DGAButtonPressEvent( HWND hwnd, XDGAButtonEvent *event );
120 extern void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XDGAButtonEvent *event );
121 #endif
123 /* Static used for the current input method */
124 static INPUT_TYPE current_input_type = X11DRV_INPUT_ABSOLUTE;
125 static BOOL in_transition = FALSE; /* This is not used as for today */
128 /***********************************************************************
129 * process_events
131 static int process_events( struct x11drv_thread_data *data )
133 XEvent event;
134 int count = 0;
136 wine_tsx11_lock();
137 while ( XPending( data->display ) )
139 XNextEvent( data->display, &event );
140 wine_tsx11_unlock();
141 EVENT_ProcessEvent( &event );
142 count++;
143 wine_tsx11_lock();
145 wine_tsx11_unlock();
146 return count;
150 /***********************************************************************
151 * MsgWaitForMultipleObjectsEx (X11DRV.@)
153 DWORD X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
154 DWORD timeout, DWORD mask, DWORD flags )
156 HANDLE new_handles[MAXIMUM_WAIT_OBJECTS+1]; /* FIXME! */
157 DWORD i, ret;
158 struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
160 if (!data || data->process_event_count)
161 return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
162 timeout, flags & MWMO_ALERTABLE );
164 for (i = 0; i < count; i++) new_handles[i] = handles[i];
165 new_handles[count] = data->display_fd;
167 wine_tsx11_lock();
168 XFlush( gdi_display );
169 XFlush( data->display );
170 wine_tsx11_unlock();
172 data->process_event_count++;
173 if (process_events( data )) ret = count;
174 else
176 ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
177 timeout, flags & MWMO_ALERTABLE );
178 if (ret == count) process_events( data );
180 data->process_event_count--;
181 return ret;
185 /***********************************************************************
186 * EVENT_ProcessEvent
188 * Process an X event.
190 static void EVENT_ProcessEvent( XEvent *event )
192 HWND hWnd;
193 Display *display = event->xany.display;
195 TRACE( "called.\n" );
197 switch (event->type)
199 case SelectionNotify: /* all of these should be caught by XCheckTypedWindowEvent() */
200 FIXME("Got SelectionNotify - must not happen!\n");
201 /* fall through */
203 /* We get all these because of StructureNotifyMask.
204 This check is placed here to avoid getting error messages below,
205 as X might send some of these even for windows that have already
206 been deleted ... */
207 case CirculateNotify:
208 case CreateNotify:
209 case DestroyNotify:
210 case GravityNotify:
211 case ReparentNotify:
212 return;
215 #ifdef HAVE_LIBXXF86DGA2
216 if (DGAUsed) {
217 if (event->type == DGAMotionEventType) {
218 TRACE("DGAMotionEvent received.\n");
219 X11DRV_DGAMotionEvent( DGAhwnd, (XDGAMotionEvent *)event );
220 return;
222 if (event->type == DGAButtonPressEventType) {
223 TRACE("DGAButtonPressEvent received.\n");
224 X11DRV_DGAButtonPressEvent( DGAhwnd, (XDGAButtonEvent *)event );
225 return;
227 if (event->type == DGAButtonReleaseEventType) {
228 TRACE("DGAButtonReleaseEvent received.\n");
229 X11DRV_DGAButtonReleaseEvent( DGAhwnd, (XDGAButtonEvent *)event );
230 return;
232 if ((event->type == DGAKeyPressEventType) ||
233 (event->type == DGAKeyReleaseEventType)) {
234 /* Fill a XKeyEvent to send to EVENT_Key */
235 XKeyEvent ke;
236 XDGAKeyEvent *evt = (XDGAKeyEvent *) event;
238 TRACE("DGAKeyPress/ReleaseEvent received.\n");
240 if (evt->type == DGAKeyReleaseEventType)
241 ke.type = KeyRelease;
242 else
243 ke.type = KeyPress;
244 ke.serial = evt->serial;
245 ke.send_event = FALSE;
246 ke.display = evt->display;
247 ke.window = 0;
248 ke.root = 0;
249 ke.subwindow = 0;
250 ke.time = evt->time;
251 ke.x = -1;
252 ke.y = -1;
253 ke.x_root = -1;
254 ke.y_root = -1;
255 ke.state = evt->state;
256 ke.keycode = evt->keycode;
257 ke.same_screen = TRUE;
258 X11DRV_KeyEvent( 0, &ke );
259 return;
262 #endif
264 wine_tsx11_lock();
265 if (XFindContext( display, event->xany.window, winContext, (char **)&hWnd ) != 0)
266 hWnd = 0; /* Not for a registered window */
267 wine_tsx11_unlock();
269 if ( !hWnd && event->xany.window != root_window
270 && event->type != PropertyNotify
271 && event->type != MappingNotify)
272 WARN( "Got event %s for unknown Window %08lx\n",
273 event_names[event->type], event->xany.window );
274 else
275 TRACE("Got event %s for hwnd %p\n",
276 event_names[event->type], hWnd );
278 switch(event->type)
280 case KeyPress:
281 case KeyRelease:
282 /* FIXME: should generate a motion event if event point is different from current pos */
283 X11DRV_KeyEvent( hWnd, (XKeyEvent*)event );
284 break;
286 case ButtonPress:
287 X11DRV_ButtonPress( hWnd, (XButtonEvent*)event );
288 break;
290 case ButtonRelease:
291 X11DRV_ButtonRelease( hWnd, (XButtonEvent*)event );
292 break;
294 case MotionNotify:
295 X11DRV_MotionNotify( hWnd, (XMotionEvent*)event );
296 break;
298 case EnterNotify:
299 X11DRV_EnterNotify( hWnd, (XCrossingEvent*)event );
300 break;
302 case FocusIn:
303 EVENT_FocusIn( hWnd, (XFocusChangeEvent*)event );
304 break;
306 case FocusOut:
307 EVENT_FocusOut( hWnd, (XFocusChangeEvent*)event );
308 break;
310 case Expose:
311 X11DRV_Expose( hWnd, &event->xexpose );
312 break;
314 case ConfigureNotify:
315 if (!hWnd) return;
316 X11DRV_ConfigureNotify( hWnd, &event->xconfigure );
317 break;
319 case SelectionRequest:
320 if (!hWnd) return;
321 EVENT_SelectionRequest( hWnd, (XSelectionRequestEvent *)event, FALSE );
322 break;
324 case SelectionClear:
325 if (!hWnd) return;
326 EVENT_SelectionClear( hWnd, (XSelectionClearEvent*) event );
327 break;
329 case PropertyNotify:
330 EVENT_PropertyNotify( (XPropertyEvent *)event );
331 break;
333 case ClientMessage:
334 if (!hWnd) return;
335 EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event );
336 break;
338 case NoExpose:
339 break;
341 case MapNotify:
342 X11DRV_MapNotify( hWnd, (XMapEvent *)event );
343 break;
345 case UnmapNotify:
346 X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event );
347 break;
349 case KeymapNotify:
350 X11DRV_KeymapNotify( hWnd, (XKeymapEvent *)event );
351 break;
353 case MappingNotify:
354 X11DRV_MappingNotify( (XMappingEvent *) event );
355 break;
357 default:
358 WARN("Unprocessed event %s for hwnd %p\n", event_names[event->type], hWnd );
359 break;
361 TRACE( "returns.\n" );
365 /*******************************************************************
366 * can_activate_window
368 * Check if we can activate the specified window.
370 inline static BOOL can_activate_window( HWND hwnd )
372 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
373 if (!(style & WS_VISIBLE)) return FALSE;
374 if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
375 return !(style & WS_DISABLED);
379 /**********************************************************************
380 * set_focus_error_handler
382 * Handler for X errors happening during XSetInputFocus call.
384 static int set_focus_error_handler( Display *display, XErrorEvent *event, void *arg )
386 return (event->error_code == BadMatch);
390 /**********************************************************************
391 * set_focus
393 static void set_focus( HWND hwnd, Time time )
395 HWND focus;
396 Window win;
398 TRACE( "setting foreground window to %p\n", hwnd );
399 SetForegroundWindow( hwnd );
401 focus = GetFocus();
402 win = X11DRV_get_whole_window(focus);
404 if (win)
406 Display *display = thread_display();
407 TRACE( "setting focus to %p (%lx) time=%ld\n", focus, win, time );
408 X11DRV_expect_error( display, set_focus_error_handler, NULL );
409 XSetInputFocus( display, win, RevertToParent, time );
410 if (X11DRV_check_error()) TRACE("got BadMatch, ignoring\n" );
415 /**********************************************************************
416 * handle_wm_protocols_message
418 static void handle_wm_protocols_message( HWND hwnd, XClientMessageEvent *event )
420 Atom protocol = (Atom)event->data.l[0];
422 if (!protocol) return;
424 if (protocol == wmDeleteWindow)
426 /* Ignore the delete window request if the window has been disabled
427 * and we are in managed mode. This is to disallow applications from
428 * being closed by the window manager while in a modal state.
430 if (IsWindowEnabled(hwnd)) PostMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
432 else if (protocol == wmTakeFocus)
434 Time event_time = (Time)event->data.l[1];
435 HWND last_focus = x11drv_thread_data()->last_focus;
437 TRACE( "got take focus msg for %p, enabled=%d, focus=%p, active=%p, fg=%p, last=%p\n",
438 hwnd, IsWindowEnabled(hwnd), GetFocus(), GetActiveWindow(),
439 GetForegroundWindow(), last_focus );
441 if (can_activate_window(hwnd))
443 /* simulate a mouse click on the caption to find out
444 * whether the window wants to be activated */
445 LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE,
446 (WPARAM)GetAncestor( hwnd, GA_ROOT ),
447 MAKELONG(HTCAPTION,WM_LBUTTONDOWN) );
448 if (ma != MA_NOACTIVATEANDEAT && ma != MA_NOACTIVATE) set_focus( hwnd, event_time );
449 else TRACE( "not setting focus to %p (%lx), ma=%ld\n", hwnd, event->window, ma );
451 else
453 hwnd = GetFocus();
454 if (!hwnd) hwnd = GetActiveWindow();
455 if (!hwnd) hwnd = last_focus;
456 if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, event_time );
462 static const char * const focus_details[] =
464 "NotifyAncestor",
465 "NotifyVirtual",
466 "NotifyInferior",
467 "NotifyNonlinear",
468 "NotifyNonlinearVirtual",
469 "NotifyPointer",
470 "NotifyPointerRoot",
471 "NotifyDetailNone"
474 /**********************************************************************
475 * EVENT_FocusIn
477 static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event )
479 if (!hwnd) return;
481 TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
483 if (wmTakeFocus) return; /* ignore FocusIn if we are using take focus */
484 if (event->detail == NotifyPointer) return;
486 if (!can_activate_window(hwnd))
488 HWND hwnd = GetFocus();
489 if (!hwnd) hwnd = GetActiveWindow();
490 if (!hwnd) hwnd = x11drv_thread_data()->last_focus;
491 if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, CurrentTime );
493 else SetForegroundWindow( hwnd );
497 /**********************************************************************
498 * EVENT_FocusOut
500 * Note: only top-level windows get FocusOut events.
502 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
504 HWND hwnd_tmp;
505 Window focus_win;
506 int revert;
508 TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
510 if (event->detail == NotifyPointer) return;
511 x11drv_thread_data()->last_focus = hwnd;
512 if (hwnd != GetForegroundWindow()) return;
513 SendMessageA( hwnd, WM_CANCELMODE, 0, 0 );
515 /* don't reset the foreground window, if the window which is
516 getting the focus is a Wine window */
518 wine_tsx11_lock();
519 XGetInputFocus( thread_display(), &focus_win, &revert );
520 if (focus_win)
522 if (XFindContext( thread_display(), focus_win, winContext, (char **)&hwnd_tmp ) != 0)
523 focus_win = 0;
525 wine_tsx11_unlock();
527 if (!focus_win)
529 /* Abey : 6-Oct-99. Check again if the focus out window is the
530 Foreground window, because in most cases the messages sent
531 above must have already changed the foreground window, in which
532 case we don't have to change the foreground window to 0 */
533 if (hwnd == GetForegroundWindow())
535 TRACE( "lost focus, setting fg to 0\n" );
536 SetForegroundWindow( 0 );
542 /***********************************************************************
543 * EVENT_SelectionRequest_TARGETS
544 * Service a TARGETS selection request event
546 static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
547 Atom target, Atom rprop )
549 Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
550 Atom* targets;
551 Atom prop;
552 UINT wFormat;
553 unsigned long cTargets;
554 BOOL bHavePixmap;
555 int xRc;
557 TRACE("Request for %s\n", TSXGetAtomName(display, target));
560 * Count the number of items we wish to expose as selection targets.
561 * We include the TARGETS item, and a PIXMAP if we have CF_DIB or CF_BITMAP
563 cTargets = CountClipboardFormats() + 1;
564 if ( CLIPBOARD_IsPresent(CF_DIB) || CLIPBOARD_IsPresent(CF_BITMAP) )
565 cTargets++;
567 /* Allocate temp buffer */
568 targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
569 if(targets == NULL) return None;
571 /* Create TARGETS property list (First item in list is TARGETS itself) */
573 for ( targets[0] = xaTargets, cTargets = 1, wFormat = 0, bHavePixmap = FALSE;
574 (wFormat = EnumClipboardFormats( wFormat )); )
576 if ( (prop = X11DRV_CLIPBOARD_MapFormatToProperty(wFormat)) != None )
578 /* Scan through what we have so far to avoid duplicates */
579 int i;
580 BOOL bExists;
581 for (i = 0, bExists = FALSE; i < cTargets; i++)
583 if (targets[i] == prop)
585 bExists = TRUE;
586 break;
589 if (!bExists)
591 targets[cTargets++] = prop;
593 /* Add PIXMAP prop for bitmaps additionally */
594 if ( (wFormat == CF_DIB || wFormat == CF_BITMAP )
595 && !bHavePixmap )
597 targets[cTargets++] = XA_PIXMAP;
598 bHavePixmap = TRUE;
604 if (TRACE_ON(event))
606 int i;
607 for ( i = 0; i < cTargets; i++)
609 if (targets[i])
611 char *itemFmtName = TSXGetAtomName(display, targets[i]);
612 TRACE("\tAtom# %d: Type %s\n", i, itemFmtName);
613 TSXFree(itemFmtName);
618 /* Update the X property */
619 TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
621 /* We may want to consider setting the type to xaTargets instead,
622 * in case some apps expect this instead of XA_ATOM */
623 xRc = TSXChangeProperty(display, requestor, rprop,
624 XA_ATOM, 32, PropModeReplace,
625 (unsigned char *)targets, cTargets);
626 TRACE("(Rc=%d)\n", xRc);
628 HeapFree( GetProcessHeap(), 0, targets );
630 return rprop;
634 /***********************************************************************
635 * EVENT_SelectionRequest_STRING
636 * Service a STRING selection request event
638 static Atom EVENT_SelectionRequest_STRING( Display *display, Window requestor,
639 Atom target, Atom rprop )
641 static UINT text_cp = (UINT)-1;
642 HANDLE hUnicodeText;
643 LPWSTR uni_text;
644 LPSTR text;
645 int size,i,j;
646 char* lpstr = 0;
647 char *itemFmtName;
648 int xRc;
650 if(text_cp == (UINT)-1)
652 HKEY hkey;
653 /* default value */
654 text_cp = CP_ACP;
655 if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\x11drv", &hkey))
657 char buf[20];
658 DWORD type, count = sizeof(buf);
659 if(!RegQueryValueExA(hkey, "TextCP", 0, &type, buf, &count))
660 text_cp = atoi(buf);
661 RegCloseKey(hkey);
666 * Map the requested X selection property type atom name to a
667 * windows clipboard format ID.
669 itemFmtName = TSXGetAtomName(display, target);
670 TRACE("Request for %s (wFormat=%x %s)\n",
671 itemFmtName, CF_UNICODETEXT, CLIPBOARD_GetFormatName(CF_UNICODETEXT, NULL, 0));
672 TSXFree(itemFmtName);
674 hUnicodeText = GetClipboardData(CF_UNICODETEXT);
675 if(!hUnicodeText)
676 return None;
677 uni_text = GlobalLock(hUnicodeText);
678 if(!uni_text)
679 return None;
681 size = WideCharToMultiByte(text_cp, 0, uni_text, -1, NULL, 0, NULL, NULL);
682 text = HeapAlloc(GetProcessHeap(), 0, size);
683 if (!text)
684 return None;
685 WideCharToMultiByte(text_cp, 0, uni_text, -1, text, size, NULL, NULL);
687 /* remove carriage returns */
689 lpstr = (char*)HeapAlloc( GetProcessHeap(), 0, size-- );
690 if(lpstr == NULL) return None;
691 for(i=0,j=0; i < size && text[i]; i++ )
693 if( text[i] == '\r' &&
694 (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
695 lpstr[j++] = text[i];
697 lpstr[j]='\0';
699 /* Update the X property */
700 TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
701 xRc = TSXChangeProperty(display, requestor, rprop,
702 XA_STRING, 8, PropModeReplace,
703 lpstr, j);
704 TRACE("(Rc=%d)\n", xRc);
706 GlobalUnlock(hUnicodeText);
707 HeapFree(GetProcessHeap(), 0, text);
708 HeapFree( GetProcessHeap(), 0, lpstr );
710 return rprop;
713 /***********************************************************************
714 * EVENT_SelectionRequest_PIXMAP
715 * Service a PIXMAP selection request event
717 static Atom EVENT_SelectionRequest_PIXMAP( Display *display, Window requestor,
718 Atom target, Atom rprop )
720 HANDLE hClipData = 0;
721 Pixmap pixmap = 0;
722 UINT wFormat;
723 char * itemFmtName;
724 int xRc;
725 #if(0)
726 XSetWindowAttributes win_attr;
727 XWindowAttributes win_attr_src;
728 #endif
731 * Map the requested X selection property type atom name to a
732 * windows clipboard format ID.
734 itemFmtName = TSXGetAtomName(display, target);
735 wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
736 TRACE("Request for %s (wFormat=%x %s)\n",
737 itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat, NULL, 0 ));
738 TSXFree(itemFmtName);
740 hClipData = GetClipboardData(wFormat);
741 if ( !hClipData )
743 TRACE("Could not retrieve a Pixmap compatible format from clipboard!\n");
744 rprop = None; /* Fail the request */
745 goto END;
748 if (wFormat == CF_DIB)
750 HWND hwnd = GetOpenClipboardWindow();
751 HDC hdc = GetDC(hwnd);
753 /* For convert from packed DIB to Pixmap */
754 pixmap = X11DRV_DIB_CreatePixmapFromDIB(hClipData, hdc);
756 ReleaseDC(hwnd, hdc);
758 else if (wFormat == CF_BITMAP)
760 HWND hwnd = GetOpenClipboardWindow();
761 HDC hdc = GetDC(hwnd);
763 pixmap = X11DRV_BITMAP_CreatePixmapFromBitmap(hClipData, hdc);
765 ReleaseDC(hwnd, hdc);
767 else
769 FIXME("%s to PIXMAP conversion not yet implemented!\n",
770 CLIPBOARD_GetFormatName(wFormat, NULL, 0));
771 rprop = None;
772 goto END;
775 TRACE("\tUpdating property %s on Window %ld with %s %ld...\n",
776 TSXGetAtomName(display, rprop), (long)requestor,
777 TSXGetAtomName(display, target), pixmap);
779 /* Store the Pixmap handle in the property */
780 xRc = TSXChangeProperty(display, requestor, rprop, target,
781 32, PropModeReplace,
782 (unsigned char *)&pixmap, 1);
783 TRACE("(Rc=%d)\n", xRc);
785 /* Enable the code below if you want to handle destroying Pixmap resources
786 * in response to property notify events. Clients like XPaint don't
787 * appear to be duplicating Pixmaps so they don't like us deleting,
788 * the resource in response to the property being deleted.
790 #if(0)
791 /* Express interest in property notify events so that we can delete the
792 * pixmap when the client deletes the property atom.
794 xRc = TSXGetWindowAttributes(display, requestor, &win_attr_src);
795 TRACE("Turning on PropertyChangeEvent notifications from window %ld\n",
796 (long)requestor);
797 win_attr.event_mask = win_attr_src.your_event_mask | PropertyChangeMask;
798 TSXChangeWindowAttributes(display, requestor, CWEventMask, &win_attr);
800 /* Register the Pixmap we created with the request property Atom.
801 * When this property is destroyed we also destroy the Pixmap in
802 * response to the PropertyNotify event.
804 X11DRV_CLIPBOARD_RegisterPixmapResource( rprop, pixmap );
805 #endif
807 END:
808 return rprop;
812 /***********************************************************************
813 * EVENT_SelectionRequest_WCF
814 * Service a Wine Clipboard Format selection request event.
815 * For <WCF>* data types we simply copy the data to X without conversion.
817 static Atom EVENT_SelectionRequest_WCF( Display *display, Window requestor,
818 Atom target, Atom rprop )
820 HANDLE hClipData = 0;
821 void* lpClipData;
822 UINT wFormat;
823 char * itemFmtName;
824 int cBytes;
825 int xRc;
826 int bemf;
829 * Map the requested X selection property type atom name to a
830 * windows clipboard format ID.
832 itemFmtName = TSXGetAtomName(display, target);
833 wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
834 TRACE("Request for %s (wFormat=%x %s)\n",
835 itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat, NULL, 0));
836 TSXFree(itemFmtName);
838 hClipData = GetClipboardData(wFormat);
840 bemf = wFormat == CF_METAFILEPICT || wFormat == CF_ENHMETAFILE;
841 if (bemf)
842 hClipData = X11DRV_CLIPBOARD_SerializeMetafile(wFormat, hClipData, sizeof(hClipData), TRUE);
844 if( hClipData && (lpClipData = GlobalLock(hClipData)) )
846 cBytes = GlobalSize(hClipData);
848 TRACE("\tUpdating property %s, %d bytes...\n",
849 TSXGetAtomName(display, rprop), cBytes);
851 xRc = TSXChangeProperty(display, requestor, rprop,
852 target, 8, PropModeReplace,
853 (unsigned char *)lpClipData, cBytes);
854 TRACE("(Rc=%d)\n", xRc);
856 GlobalUnlock(hClipData);
858 else
860 TRACE("\tCould not retrieve native format!\n");
861 rprop = None; /* Fail the request */
864 if (bemf) /* We must free serialized metafile data */
865 GlobalFree(hClipData);
867 return rprop;
871 /***********************************************************************
872 * EVENT_SelectionRequest_MULTIPLE
873 * Service a MULTIPLE selection request event
874 * rprop contains a list of (target,property) atom pairs.
875 * The first atom names a target and the second names a property.
876 * The effect is as if we have received a sequence of SelectionRequest events
877 * (one for each atom pair) except that:
878 * 1. We reply with a SelectionNotify only when all the requested conversions
879 * have been performed.
880 * 2. If we fail to convert the target named by an atom in the MULTIPLE property,
881 * we replace the atom in the property by None.
883 static Atom EVENT_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent )
885 Display *display = pevent->display;
886 Atom rprop;
887 Atom atype=AnyPropertyType;
888 int aformat;
889 unsigned long remain;
890 Atom* targetPropList=NULL;
891 unsigned long cTargetPropList = 0;
892 /* Atom xAtomPair = TSXInternAtom(display, "ATOM_PAIR", False); */
894 /* If the specified property is None the requestor is an obsolete client.
895 * We support these by using the specified target atom as the reply property.
897 rprop = pevent->property;
898 if( rprop == None )
899 rprop = pevent->target;
900 if (!rprop)
901 goto END;
903 /* Read the MULTIPLE property contents. This should contain a list of
904 * (target,property) atom pairs.
906 if(TSXGetWindowProperty(display, pevent->requestor, rprop,
907 0, 0x3FFF, False, AnyPropertyType, &atype,&aformat,
908 &cTargetPropList, &remain,
909 (unsigned char**)&targetPropList) != Success)
910 TRACE("\tCouldn't read MULTIPLE property\n");
911 else
913 TRACE("\tType %s,Format %d,nItems %ld, Remain %ld\n",
914 TSXGetAtomName(display, atype), aformat, cTargetPropList, remain);
917 * Make sure we got what we expect.
918 * NOTE: According to the X-ICCCM Version 2.0 documentation the property sent
919 * in a MULTIPLE selection request should be of type ATOM_PAIR.
920 * However some X apps(such as XPaint) are not compliant with this and return
921 * a user defined atom in atype when XGetWindowProperty is called.
922 * The data *is* an atom pair but is not denoted as such.
924 if(aformat == 32 /* atype == xAtomPair */ )
926 int i;
928 /* Iterate through the ATOM_PAIR list and execute a SelectionRequest
929 * for each (target,property) pair */
931 for (i = 0; i < cTargetPropList; i+=2)
933 char *targetName = TSXGetAtomName(display, targetPropList[i]);
934 char *propName = TSXGetAtomName(display, targetPropList[i+1]);
935 XSelectionRequestEvent event;
937 TRACE("MULTIPLE(%d): Target='%s' Prop='%s'\n",
938 i/2, targetName, propName);
939 TSXFree(targetName);
940 TSXFree(propName);
942 /* We must have a non "None" property to service a MULTIPLE target atom */
943 if ( !targetPropList[i+1] )
945 TRACE("\tMULTIPLE(%d): Skipping target with empty property!\n", i);
946 continue;
949 /* Set up an XSelectionRequestEvent for this (target,property) pair */
950 memcpy( &event, pevent, sizeof(XSelectionRequestEvent) );
951 event.target = targetPropList[i];
952 event.property = targetPropList[i+1];
954 /* Fire a SelectionRequest, informing the handler that we are processing
955 * a MULTIPLE selection request event.
957 EVENT_SelectionRequest( hWnd, &event, TRUE );
961 /* Free the list of targets/properties */
962 TSXFree(targetPropList);
965 END:
966 return rprop;
970 /***********************************************************************
971 * EVENT_SelectionRequest
972 * Process an event selection request event.
973 * The bIsMultiple flag is used to signal when EVENT_SelectionRequest is called
974 * recursively while servicing a "MULTIPLE" selection target.
976 * Note: We only receive this event when WINE owns the X selection
978 static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple )
980 Display *display = event->display;
981 XSelectionEvent result;
982 Atom rprop = None;
983 Window request = event->requestor;
984 BOOL couldOpen = FALSE;
985 Atom xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
986 Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
987 Atom xaMultiple = TSXInternAtom(display, "MULTIPLE", False);
990 * We can only handle the selection request if :
991 * The selection is PRIMARY or CLIPBOARD, AND we can successfully open the clipboard.
992 * Don't do these checks or open the clipboard while recursively processing MULTIPLE,
993 * since this has been already done.
995 if ( !bIsMultiple )
997 if ( ( (event->selection != XA_PRIMARY) && (event->selection != xaClipboard) )
998 || !(couldOpen = OpenClipboard(hWnd)) )
999 goto END;
1002 /* If the specified property is None the requestor is an obsolete client.
1003 * We support these by using the specified target atom as the reply property.
1005 rprop = event->property;
1006 if( rprop == None )
1007 rprop = event->target;
1009 if(event->target == xaTargets) /* Return a list of all supported targets */
1011 /* TARGETS selection request */
1012 rprop = EVENT_SelectionRequest_TARGETS( display, request, event->target, rprop );
1014 else if(event->target == xaMultiple) /* rprop contains a list of (target, property) atom pairs */
1016 /* MULTIPLE selection request */
1017 rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
1019 else if(event->target == XA_STRING) /* treat CF_TEXT as Unix text */
1021 /* XA_STRING selection request */
1022 rprop = EVENT_SelectionRequest_STRING( display, request, event->target, rprop );
1024 else if(event->target == XA_PIXMAP) /* Convert DIB's to Pixmaps */
1026 /* XA_PIXMAP selection request */
1027 rprop = EVENT_SelectionRequest_PIXMAP( display, request, event->target, rprop );
1029 else if(event->target == XA_BITMAP) /* Convert DIB's to 1-bit Pixmaps */
1031 /* XA_BITMAP selection request - TODO: create a monochrome Pixmap */
1032 rprop = EVENT_SelectionRequest_PIXMAP( display, request, XA_PIXMAP, rprop );
1034 else if(X11DRV_CLIPBOARD_IsNativeProperty(event->target)) /* <WCF>* */
1036 /* All <WCF> selection requests */
1037 rprop = EVENT_SelectionRequest_WCF( display, request, event->target, rprop );
1039 else
1040 rprop = None; /* Don't support this format */
1042 END:
1043 /* close clipboard only if we opened before */
1044 if(couldOpen) CloseClipboard();
1046 if( rprop == None)
1047 TRACE("\tRequest ignored\n");
1049 /* reply to sender
1050 * SelectionNotify should be sent only at the end of a MULTIPLE request
1052 if ( !bIsMultiple )
1054 result.type = SelectionNotify;
1055 result.display = display;
1056 result.requestor = request;
1057 result.selection = event->selection;
1058 result.property = rprop;
1059 result.target = event->target;
1060 result.time = event->time;
1061 TRACE("Sending SelectionNotify event...\n");
1062 TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
1066 /***********************************************************************
1067 * EVENT_SelectionClear
1069 static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
1071 Atom xaClipboard = TSXInternAtom(event->display, "CLIPBOARD", False);
1073 if (event->selection == XA_PRIMARY || event->selection == xaClipboard)
1074 X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd );
1077 /***********************************************************************
1078 * EVENT_PropertyNotify
1079 * We use this to release resources like Pixmaps when a selection
1080 * client no longer needs them.
1082 static void EVENT_PropertyNotify( XPropertyEvent *event )
1084 /* Check if we have any resources to free */
1085 TRACE("Received PropertyNotify event: \n");
1087 switch(event->state)
1089 case PropertyDelete:
1091 TRACE("\tPropertyDelete for atom %s on window %ld\n",
1092 TSXGetAtomName(event->display, event->atom), (long)event->window);
1094 if (X11DRV_IsSelectionOwner())
1095 X11DRV_CLIPBOARD_FreeResources( event->atom );
1096 break;
1099 case PropertyNewValue:
1101 TRACE("\tPropertyNewValue for atom %s on window %ld\n\n",
1102 TSXGetAtomName(event->display, event->atom), (long)event->window);
1103 break;
1106 default:
1107 break;
1111 static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt )
1113 RECT tempRect;
1115 if (!IsWindowEnabled(hQueryWnd)) return 0;
1117 GetWindowRect(hQueryWnd, &tempRect);
1119 if(!PtInRect(&tempRect, *lpPt)) return 0;
1121 if (!IsIconic( hQueryWnd ))
1123 GetClientRect( hQueryWnd, &tempRect );
1124 MapWindowPoints( hQueryWnd, 0, (LPPOINT)&tempRect, 2 );
1126 if (PtInRect( &tempRect, *lpPt))
1128 HWND *list = WIN_ListChildren( hQueryWnd );
1129 HWND bResult = 0;
1131 if (list)
1133 int i;
1135 for (i = 0; list[i]; i++)
1137 if (GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE)
1139 GetWindowRect( list[i], &tempRect );
1140 if (PtInRect( &tempRect, *lpPt )) break;
1143 if (list[i])
1145 if (IsWindowEnabled( list[i] ))
1146 bResult = find_drop_window( list[i], lpPt );
1148 HeapFree( GetProcessHeap(), 0, list );
1150 if(bResult) return bResult;
1154 if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0;
1156 ScreenToClient(hQueryWnd, lpPt);
1158 return hQueryWnd;
1161 /**********************************************************************
1162 * EVENT_DropFromOffix
1164 * don't know if it still works (last Changlog is from 96/11/04)
1166 static void EVENT_DropFromOffiX( HWND hWnd, XClientMessageEvent *event )
1168 unsigned long data_length;
1169 unsigned long aux_long;
1170 unsigned char* p_data = NULL;
1171 union {
1172 Atom atom_aux;
1173 struct {
1174 int x;
1175 int y;
1176 } pt_aux;
1177 int i;
1178 } u;
1179 int x, y;
1180 BOOL bAccept;
1181 Window w_aux_root, w_aux_child;
1182 WND* pWnd;
1183 HWND hScope = hWnd;
1185 pWnd = WIN_FindWndPtr(hWnd);
1187 TSXQueryPointer( event->display, get_whole_window(pWnd), &w_aux_root, &w_aux_child,
1188 &x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
1189 (unsigned int*)&aux_long);
1191 /* find out drop point and drop window */
1192 if( x < 0 || y < 0 ||
1193 x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
1194 y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
1196 bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES;
1197 x = 0;
1198 y = 0;
1200 else
1202 POINT pt = { x, y };
1203 HWND hwndDrop = find_drop_window( hWnd, &pt );
1204 if (hwndDrop)
1206 x = pt.x;
1207 y = pt.y;
1208 hScope = hwndDrop;
1209 bAccept = TRUE;
1211 else
1213 bAccept = FALSE;
1216 WIN_ReleaseWndPtr(pWnd);
1218 if (!bAccept) return;
1220 TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
1221 dndSelection, 0, 65535, FALSE,
1222 AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
1223 &data_length, &aux_long, &p_data);
1225 if( !aux_long && p_data) /* don't bother if > 64K */
1227 signed char *p = (signed char*) p_data;
1228 char *p_drop;
1230 aux_long = 0;
1231 while( *p ) /* calculate buffer size */
1233 p_drop = p;
1234 if((u.i = *p) != -1 )
1236 INT len = GetShortPathNameA( p, NULL, 0 );
1237 if (len) aux_long += len + 1;
1238 else *p = -1;
1240 p += strlen(p) + 1;
1242 if( aux_long && aux_long < 65535 )
1244 HDROP hDrop;
1245 DROPFILES *lpDrop;
1247 aux_long += sizeof(DROPFILES) + 1;
1248 hDrop = GlobalAlloc( GMEM_SHARE, aux_long );
1249 lpDrop = (DROPFILES*)GlobalLock( hDrop );
1251 if( lpDrop )
1253 WND *pDropWnd = WIN_FindWndPtr( hScope );
1254 lpDrop->pFiles = sizeof(DROPFILES);
1255 lpDrop->pt.x = x;
1256 lpDrop->pt.y = y;
1257 lpDrop->fNC =
1258 ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
1259 y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
1260 x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
1261 y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
1262 lpDrop->fWide = FALSE;
1263 WIN_ReleaseWndPtr(pDropWnd);
1264 p_drop = (char *)(lpDrop + 1);
1265 p = p_data;
1266 while(*p)
1268 if( *p != -1 ) /* use only "good" entries */
1270 GetShortPathNameA( p, p_drop, 65535 );
1271 p_drop += strlen( p_drop ) + 1;
1273 p += strlen(p) + 1;
1275 *p_drop = '\0';
1276 PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
1280 if( p_data ) TSXFree(p_data);
1283 /**********************************************************************
1284 * EVENT_DropURLs
1286 * drop items are separated by \n
1287 * each item is prefixed by its mime type
1289 * event->data.l[3], event->data.l[4] contains drop x,y position
1291 static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
1293 unsigned long data_length;
1294 unsigned long aux_long, drop_len = 0;
1295 unsigned char *p_data = NULL; /* property data */
1296 char *p_drop = NULL;
1297 char *p, *next;
1298 int x, y;
1299 DROPFILES *lpDrop;
1300 HDROP hDrop;
1301 union {
1302 Atom atom_aux;
1303 int i;
1304 Window w_aux;
1305 } u; /* unused */
1307 if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return;
1309 TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
1310 dndSelection, 0, 65535, FALSE,
1311 AnyPropertyType, &u.atom_aux, &u.i,
1312 &data_length, &aux_long, &p_data);
1313 if (aux_long)
1314 WARN("property too large, truncated!\n");
1315 TRACE("urls=%s\n", p_data);
1317 if( !aux_long && p_data) { /* don't bother if > 64K */
1318 /* calculate length */
1319 p = p_data;
1320 next = strchr(p, '\n');
1321 while (p) {
1322 if (next) *next=0;
1323 if (strncmp(p,"file:",5) == 0 ) {
1324 INT len = GetShortPathNameA( p+5, NULL, 0 );
1325 if (len) drop_len += len + 1;
1327 if (next) {
1328 *next = '\n';
1329 p = next + 1;
1330 next = strchr(p, '\n');
1331 } else {
1332 p = NULL;
1336 if( drop_len && drop_len < 65535 ) {
1337 TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
1338 &x, &y, &u.i, &u.i, &u.i);
1340 drop_len += sizeof(DROPFILES) + 1;
1341 hDrop = GlobalAlloc( GMEM_SHARE, drop_len );
1342 lpDrop = (DROPFILES *) GlobalLock( hDrop );
1344 if( lpDrop ) {
1345 WND *pDropWnd = WIN_FindWndPtr( hWnd );
1346 lpDrop->pFiles = sizeof(DROPFILES);
1347 lpDrop->pt.x = (INT)x;
1348 lpDrop->pt.y = (INT)y;
1349 lpDrop->fNC =
1350 ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
1351 y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
1352 x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
1353 y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
1354 lpDrop->fWide = FALSE;
1355 p_drop = (char*)(lpDrop + 1);
1356 WIN_ReleaseWndPtr(pDropWnd);
1359 /* create message content */
1360 if (p_drop) {
1361 p = p_data;
1362 next = strchr(p, '\n');
1363 while (p) {
1364 if (next) *next=0;
1365 if (strncmp(p,"file:",5) == 0 ) {
1366 INT len = GetShortPathNameA( p+5, p_drop, 65535 );
1367 if (len) {
1368 TRACE("drop file %s as %s\n", p+5, p_drop);
1369 p_drop += len+1;
1370 } else {
1371 WARN("can't convert file %s to dos name \n", p+5);
1373 } else {
1374 WARN("unknown mime type %s\n", p);
1376 if (next) {
1377 *next = '\n';
1378 p = next + 1;
1379 next = strchr(p, '\n');
1380 } else {
1381 p = NULL;
1383 *p_drop = '\0';
1386 GlobalUnlock(hDrop);
1387 PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
1390 if( p_data ) TSXFree(p_data);
1394 /**********************************************************************
1395 * EVENT_ClientMessage
1397 static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event )
1399 if (event->message_type != None && event->format == 32) {
1400 if (event->message_type == wmProtocols)
1401 handle_wm_protocols_message( hWnd, event );
1402 else if (event->message_type == dndProtocol)
1404 /* query window (drag&drop event contains only drag window) */
1405 Window root, child;
1406 int root_x, root_y, child_x, child_y;
1407 unsigned int u;
1409 wine_tsx11_lock();
1410 XQueryPointer( event->display, root_window, &root, &child,
1411 &root_x, &root_y, &child_x, &child_y, &u);
1412 if (XFindContext( event->display, child, winContext, (char **)&hWnd ) != 0) hWnd = 0;
1413 wine_tsx11_unlock();
1414 if (!hWnd) return;
1415 if (event->data.l[0] == DndFile || event->data.l[0] == DndFiles)
1416 EVENT_DropFromOffiX(hWnd, event);
1417 else if (event->data.l[0] == DndURL)
1418 EVENT_DropURLs(hWnd, event);
1420 else {
1421 #if 0
1422 /* enable this if you want to see the message */
1423 unsigned char* p_data = NULL;
1424 union {
1425 unsigned long l;
1426 int i;
1427 Atom atom;
1428 } u; /* unused */
1429 TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
1430 dndSelection, 0, 65535, FALSE,
1431 AnyPropertyType, &u.atom, &u.i,
1432 &u.l, &u.l, &p_data);
1433 TRACE("message_type=%ld, data=%ld,%ld,%ld,%ld,%ld, msg=%s\n",
1434 event->message_type, event->data.l[0], event->data.l[1],
1435 event->data.l[2], event->data.l[3], event->data.l[4],
1436 p_data);
1437 #endif
1438 TRACE("unrecognized ClientMessage\n" );
1444 /**********************************************************************
1445 * X11DRV_EVENT_SetInputMethod
1447 INPUT_TYPE X11DRV_EVENT_SetInputMethod(INPUT_TYPE type)
1449 INPUT_TYPE prev = current_input_type;
1451 /* Flag not used yet */
1452 in_transition = FALSE;
1453 current_input_type = type;
1455 return prev;
1458 #ifdef HAVE_LIBXXF86DGA2
1459 /**********************************************************************
1460 * X11DRV_EVENT_SetDGAStatus
1462 void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base)
1464 if (event_base < 0) {
1465 DGAUsed = FALSE;
1466 DGAhwnd = 0;
1467 } else {
1468 DGAUsed = TRUE;
1469 DGAhwnd = hwnd;
1470 DGAMotionEventType = event_base + MotionNotify;
1471 DGAButtonPressEventType = event_base + ButtonPress;
1472 DGAButtonReleaseEventType = event_base + ButtonRelease;
1473 DGAKeyPressEventType = event_base + KeyPress;
1474 DGAKeyReleaseEventType = event_base + KeyRelease;
1477 #endif