Fix the computation of the trackbar's size.
[wine/wine-kai.git] / dlls / x11drv / event.c
bloba570993a1ff798bbb924b80fafc5c8167b67dbc2
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 Bool ignore;
141 XNextEvent( data->display, &event );
142 ignore = XFilterEvent( &event, None );
143 wine_tsx11_unlock();
144 if (!ignore) EVENT_ProcessEvent( &event );
145 count++;
146 wine_tsx11_lock();
148 wine_tsx11_unlock();
149 return count;
153 /***********************************************************************
154 * MsgWaitForMultipleObjectsEx (X11DRV.@)
156 DWORD X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
157 DWORD timeout, DWORD mask, DWORD flags )
159 HANDLE new_handles[MAXIMUM_WAIT_OBJECTS+1]; /* FIXME! */
160 DWORD i, ret;
161 struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
163 if (!data || data->process_event_count)
164 return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
165 timeout, flags & MWMO_ALERTABLE );
167 for (i = 0; i < count; i++) new_handles[i] = handles[i];
168 new_handles[count] = data->display_fd;
170 wine_tsx11_lock();
171 XFlush( gdi_display );
172 XFlush( data->display );
173 wine_tsx11_unlock();
175 data->process_event_count++;
176 if (process_events( data )) ret = count;
177 else
179 ret = WaitForMultipleObjectsEx( count+1, new_handles, flags & MWMO_WAITALL,
180 timeout, flags & MWMO_ALERTABLE );
181 if (ret == count) process_events( data );
183 data->process_event_count--;
184 return ret;
188 /***********************************************************************
189 * EVENT_ProcessEvent
191 * Process an X event.
193 static void EVENT_ProcessEvent( XEvent *event )
195 HWND hWnd;
196 Display *display = event->xany.display;
198 TRACE( "called.\n" );
200 switch (event->type)
202 case SelectionNotify: /* all of these should be caught by XCheckTypedWindowEvent() */
203 FIXME("Got SelectionNotify - must not happen!\n");
204 /* fall through */
206 /* We get all these because of StructureNotifyMask.
207 This check is placed here to avoid getting error messages below,
208 as X might send some of these even for windows that have already
209 been deleted ... */
210 case CirculateNotify:
211 case CreateNotify:
212 case DestroyNotify:
213 case GravityNotify:
214 case ReparentNotify:
215 return;
218 #ifdef HAVE_LIBXXF86DGA2
219 if (DGAUsed) {
220 if (event->type == DGAMotionEventType) {
221 TRACE("DGAMotionEvent received.\n");
222 X11DRV_DGAMotionEvent( DGAhwnd, (XDGAMotionEvent *)event );
223 return;
225 if (event->type == DGAButtonPressEventType) {
226 TRACE("DGAButtonPressEvent received.\n");
227 X11DRV_DGAButtonPressEvent( DGAhwnd, (XDGAButtonEvent *)event );
228 return;
230 if (event->type == DGAButtonReleaseEventType) {
231 TRACE("DGAButtonReleaseEvent received.\n");
232 X11DRV_DGAButtonReleaseEvent( DGAhwnd, (XDGAButtonEvent *)event );
233 return;
235 if ((event->type == DGAKeyPressEventType) ||
236 (event->type == DGAKeyReleaseEventType)) {
237 /* Fill a XKeyEvent to send to EVENT_Key */
238 XKeyEvent ke;
239 XDGAKeyEvent *evt = (XDGAKeyEvent *) event;
241 TRACE("DGAKeyPress/ReleaseEvent received.\n");
243 if (evt->type == DGAKeyReleaseEventType)
244 ke.type = KeyRelease;
245 else
246 ke.type = KeyPress;
247 ke.serial = evt->serial;
248 ke.send_event = FALSE;
249 ke.display = evt->display;
250 ke.window = 0;
251 ke.root = 0;
252 ke.subwindow = 0;
253 ke.time = evt->time;
254 ke.x = -1;
255 ke.y = -1;
256 ke.x_root = -1;
257 ke.y_root = -1;
258 ke.state = evt->state;
259 ke.keycode = evt->keycode;
260 ke.same_screen = TRUE;
261 X11DRV_KeyEvent( 0, &ke );
262 return;
265 #endif
267 wine_tsx11_lock();
268 if (XFindContext( display, event->xany.window, winContext, (char **)&hWnd ) != 0)
269 hWnd = 0; /* Not for a registered window */
270 wine_tsx11_unlock();
272 if ( !hWnd && event->xany.window != root_window
273 && event->type != PropertyNotify
274 && event->type != MappingNotify)
275 WARN( "Got event %s for unknown Window %08lx\n",
276 event_names[event->type], event->xany.window );
277 else
278 TRACE("Got event %s for hwnd %p\n",
279 event_names[event->type], hWnd );
281 switch(event->type)
283 case KeyPress:
284 case KeyRelease:
285 /* FIXME: should generate a motion event if event point is different from current pos */
286 X11DRV_KeyEvent( hWnd, (XKeyEvent*)event );
287 break;
289 case ButtonPress:
290 X11DRV_ButtonPress( hWnd, (XButtonEvent*)event );
291 break;
293 case ButtonRelease:
294 X11DRV_ButtonRelease( hWnd, (XButtonEvent*)event );
295 break;
297 case MotionNotify:
298 X11DRV_MotionNotify( hWnd, (XMotionEvent*)event );
299 break;
301 case EnterNotify:
302 X11DRV_EnterNotify( hWnd, (XCrossingEvent*)event );
303 break;
305 case FocusIn:
306 EVENT_FocusIn( hWnd, (XFocusChangeEvent*)event );
307 break;
309 case FocusOut:
310 EVENT_FocusOut( hWnd, (XFocusChangeEvent*)event );
311 break;
313 case Expose:
314 X11DRV_Expose( hWnd, &event->xexpose );
315 break;
317 case ConfigureNotify:
318 if (!hWnd) return;
319 X11DRV_ConfigureNotify( hWnd, &event->xconfigure );
320 break;
322 case SelectionRequest:
323 if (!hWnd) return;
324 EVENT_SelectionRequest( hWnd, (XSelectionRequestEvent *)event, FALSE );
325 break;
327 case SelectionClear:
328 if (!hWnd) return;
329 EVENT_SelectionClear( hWnd, (XSelectionClearEvent*) event );
330 break;
332 case PropertyNotify:
333 EVENT_PropertyNotify( (XPropertyEvent *)event );
334 break;
336 case ClientMessage:
337 if (!hWnd) return;
338 EVENT_ClientMessage( hWnd, (XClientMessageEvent *) event );
339 break;
341 case NoExpose:
342 break;
344 case MapNotify:
345 X11DRV_MapNotify( hWnd, (XMapEvent *)event );
346 break;
348 case UnmapNotify:
349 X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event );
350 break;
352 case KeymapNotify:
353 X11DRV_KeymapNotify( hWnd, (XKeymapEvent *)event );
354 break;
356 case MappingNotify:
357 X11DRV_MappingNotify( (XMappingEvent *) event );
358 break;
360 default:
361 WARN("Unprocessed event %s for hwnd %p\n", event_names[event->type], hWnd );
362 break;
364 TRACE( "returns.\n" );
368 /*******************************************************************
369 * can_activate_window
371 * Check if we can activate the specified window.
373 inline static BOOL can_activate_window( HWND hwnd )
375 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
376 if (!(style & WS_VISIBLE)) return FALSE;
377 if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
378 return !(style & WS_DISABLED);
382 /**********************************************************************
383 * set_focus_error_handler
385 * Handler for X errors happening during XSetInputFocus call.
387 static int set_focus_error_handler( Display *display, XErrorEvent *event, void *arg )
389 return (event->error_code == BadMatch);
393 /**********************************************************************
394 * set_focus
396 static void set_focus( HWND hwnd, Time time )
398 HWND focus;
399 Window win;
401 TRACE( "setting foreground window to %p\n", hwnd );
402 SetForegroundWindow( hwnd );
404 focus = GetFocus();
405 if (focus) focus = GetAncestor( focus, GA_ROOT );
406 win = X11DRV_get_whole_window(focus);
408 if (win)
410 Display *display = thread_display();
411 TRACE( "setting focus to %p (%lx) time=%ld\n", focus, win, time );
412 X11DRV_expect_error( display, set_focus_error_handler, NULL );
413 XSetInputFocus( display, win, RevertToParent, time );
414 if (X11DRV_check_error()) TRACE("got BadMatch, ignoring\n" );
419 /**********************************************************************
420 * handle_wm_protocols_message
422 static void handle_wm_protocols_message( HWND hwnd, XClientMessageEvent *event )
424 Atom protocol = (Atom)event->data.l[0];
426 if (!protocol) return;
428 if (protocol == wmDeleteWindow)
430 /* Ignore the delete window request if the window has been disabled
431 * and we are in managed mode. This is to disallow applications from
432 * being closed by the window manager while in a modal state.
434 if (IsWindowEnabled(hwnd)) PostMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
436 else if (protocol == wmTakeFocus)
438 Time event_time = (Time)event->data.l[1];
439 HWND last_focus = x11drv_thread_data()->last_focus;
441 TRACE( "got take focus msg for %p, enabled=%d, focus=%p, active=%p, fg=%p, last=%p\n",
442 hwnd, IsWindowEnabled(hwnd), GetFocus(), GetActiveWindow(),
443 GetForegroundWindow(), last_focus );
445 if (can_activate_window(hwnd))
447 /* simulate a mouse click on the caption to find out
448 * whether the window wants to be activated */
449 LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE,
450 (WPARAM)GetAncestor( hwnd, GA_ROOT ),
451 MAKELONG(HTCAPTION,WM_LBUTTONDOWN) );
452 if (ma != MA_NOACTIVATEANDEAT && ma != MA_NOACTIVATE) set_focus( hwnd, event_time );
453 else TRACE( "not setting focus to %p (%lx), ma=%ld\n", hwnd, event->window, ma );
455 else
457 hwnd = GetFocus();
458 if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT );
459 if (!hwnd) hwnd = GetActiveWindow();
460 if (!hwnd) hwnd = last_focus;
461 if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, event_time );
467 static const char * const focus_details[] =
469 "NotifyAncestor",
470 "NotifyVirtual",
471 "NotifyInferior",
472 "NotifyNonlinear",
473 "NotifyNonlinearVirtual",
474 "NotifyPointer",
475 "NotifyPointerRoot",
476 "NotifyDetailNone"
479 /**********************************************************************
480 * EVENT_FocusIn
482 static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event )
484 XIC xic;
486 if (!hwnd) return;
488 TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
490 if (event->detail == NotifyPointer) return;
492 if ((xic = X11DRV_get_ic( hwnd )))
494 wine_tsx11_lock();
495 XSetICFocus( xic );
496 wine_tsx11_unlock();
498 if (wmTakeFocus) return; /* ignore FocusIn if we are using take focus */
500 if (!can_activate_window(hwnd))
502 HWND hwnd = GetFocus();
503 if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT );
504 if (!hwnd) hwnd = GetActiveWindow();
505 if (!hwnd) hwnd = x11drv_thread_data()->last_focus;
506 if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, CurrentTime );
508 else SetForegroundWindow( hwnd );
512 /**********************************************************************
513 * EVENT_FocusOut
515 * Note: only top-level windows get FocusOut events.
517 static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
519 HWND hwnd_tmp;
520 Window focus_win;
521 int revert;
522 XIC xic;
524 TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] );
526 if (event->detail == NotifyPointer) return;
527 x11drv_thread_data()->last_focus = hwnd;
528 if ((xic = X11DRV_get_ic( hwnd )))
530 wine_tsx11_lock();
531 XUnsetICFocus( xic );
532 wine_tsx11_unlock();
534 if (hwnd != GetForegroundWindow()) return;
535 SendMessageA( hwnd, WM_CANCELMODE, 0, 0 );
537 /* don't reset the foreground window, if the window which is
538 getting the focus is a Wine window */
540 wine_tsx11_lock();
541 XGetInputFocus( thread_display(), &focus_win, &revert );
542 if (focus_win)
544 if (XFindContext( thread_display(), focus_win, winContext, (char **)&hwnd_tmp ) != 0)
545 focus_win = 0;
547 wine_tsx11_unlock();
549 if (!focus_win)
551 /* Abey : 6-Oct-99. Check again if the focus out window is the
552 Foreground window, because in most cases the messages sent
553 above must have already changed the foreground window, in which
554 case we don't have to change the foreground window to 0 */
555 if (hwnd == GetForegroundWindow())
557 TRACE( "lost focus, setting fg to 0\n" );
558 SetForegroundWindow( 0 );
564 /***********************************************************************
565 * EVENT_SelectionRequest_TARGETS
566 * Service a TARGETS selection request event
568 static Atom EVENT_SelectionRequest_TARGETS( Display *display, Window requestor,
569 Atom target, Atom rprop )
571 Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
572 Atom* targets;
573 Atom prop;
574 UINT wFormat;
575 unsigned long cTargets;
576 BOOL bHavePixmap;
577 int xRc;
579 TRACE("Request for %s\n", TSXGetAtomName(display, target));
582 * Count the number of items we wish to expose as selection targets.
583 * We include the TARGETS item, and a PIXMAP if we have CF_DIB or CF_BITMAP
585 cTargets = CountClipboardFormats() + 1;
586 if ( CLIPBOARD_IsPresent(CF_DIB) || CLIPBOARD_IsPresent(CF_BITMAP) )
587 cTargets++;
589 /* Allocate temp buffer */
590 targets = (Atom*)HeapAlloc( GetProcessHeap(), 0, cTargets * sizeof(Atom));
591 if(targets == NULL) return None;
593 /* Create TARGETS property list (First item in list is TARGETS itself) */
595 for ( targets[0] = xaTargets, cTargets = 1, wFormat = 0, bHavePixmap = FALSE;
596 (wFormat = EnumClipboardFormats( wFormat )); )
598 if ( (prop = X11DRV_CLIPBOARD_MapFormatToProperty(wFormat)) != None )
600 /* Scan through what we have so far to avoid duplicates */
601 int i;
602 BOOL bExists;
603 for (i = 0, bExists = FALSE; i < cTargets; i++)
605 if (targets[i] == prop)
607 bExists = TRUE;
608 break;
611 if (!bExists)
613 targets[cTargets++] = prop;
615 /* Add PIXMAP prop for bitmaps additionally */
616 if ( (wFormat == CF_DIB || wFormat == CF_BITMAP )
617 && !bHavePixmap )
619 targets[cTargets++] = XA_PIXMAP;
620 bHavePixmap = TRUE;
626 if (TRACE_ON(event))
628 int i;
629 for ( i = 0; i < cTargets; i++)
631 if (targets[i])
633 char *itemFmtName = TSXGetAtomName(display, targets[i]);
634 TRACE("\tAtom# %d: Type %s\n", i, itemFmtName);
635 TSXFree(itemFmtName);
640 /* Update the X property */
641 TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
643 /* We may want to consider setting the type to xaTargets instead,
644 * in case some apps expect this instead of XA_ATOM */
645 xRc = TSXChangeProperty(display, requestor, rprop,
646 XA_ATOM, 32, PropModeReplace,
647 (unsigned char *)targets, cTargets);
648 TRACE("(Rc=%d)\n", xRc);
650 HeapFree( GetProcessHeap(), 0, targets );
652 return rprop;
656 /***********************************************************************
657 * EVENT_SelectionRequest_STRING
658 * Service a STRING selection request event
660 static Atom EVENT_SelectionRequest_STRING( Display *display, Window requestor,
661 Atom target, Atom rprop )
663 static UINT text_cp = (UINT)-1;
664 HANDLE hUnicodeText;
665 LPWSTR uni_text;
666 LPSTR text;
667 int size,i,j;
668 char* lpstr = 0;
669 char *itemFmtName;
670 int xRc;
672 if(text_cp == (UINT)-1)
674 HKEY hkey;
675 /* default value */
676 text_cp = CP_ACP;
677 if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\x11drv", &hkey))
679 char buf[20];
680 DWORD type, count = sizeof(buf);
681 if(!RegQueryValueExA(hkey, "TextCP", 0, &type, buf, &count))
682 text_cp = atoi(buf);
683 RegCloseKey(hkey);
688 * Map the requested X selection property type atom name to a
689 * windows clipboard format ID.
691 itemFmtName = TSXGetAtomName(display, target);
692 TRACE("Request for %s (wFormat=%x %s)\n",
693 itemFmtName, CF_UNICODETEXT, CLIPBOARD_GetFormatName(CF_UNICODETEXT, NULL, 0));
694 TSXFree(itemFmtName);
696 hUnicodeText = GetClipboardData(CF_UNICODETEXT);
697 if(!hUnicodeText)
698 return None;
699 uni_text = GlobalLock(hUnicodeText);
700 if(!uni_text)
701 return None;
703 size = WideCharToMultiByte(text_cp, 0, uni_text, -1, NULL, 0, NULL, NULL);
704 text = HeapAlloc(GetProcessHeap(), 0, size);
705 if (!text)
706 return None;
707 WideCharToMultiByte(text_cp, 0, uni_text, -1, text, size, NULL, NULL);
709 /* remove carriage returns */
711 lpstr = (char*)HeapAlloc( GetProcessHeap(), 0, size-- );
712 if(lpstr == NULL) return None;
713 for(i=0,j=0; i < size && text[i]; i++ )
715 if( text[i] == '\r' &&
716 (text[i+1] == '\n' || text[i+1] == '\0') ) continue;
717 lpstr[j++] = text[i];
719 lpstr[j]='\0';
721 /* Update the X property */
722 TRACE("\tUpdating property %s...\n", TSXGetAtomName(display, rprop));
723 xRc = TSXChangeProperty(display, requestor, rprop,
724 XA_STRING, 8, PropModeReplace,
725 lpstr, j);
726 TRACE("(Rc=%d)\n", xRc);
728 GlobalUnlock(hUnicodeText);
729 HeapFree(GetProcessHeap(), 0, text);
730 HeapFree( GetProcessHeap(), 0, lpstr );
732 return rprop;
735 /***********************************************************************
736 * EVENT_SelectionRequest_PIXMAP
737 * Service a PIXMAP selection request event
739 static Atom EVENT_SelectionRequest_PIXMAP( Display *display, Window requestor,
740 Atom target, Atom rprop )
742 HANDLE hClipData = 0;
743 Pixmap pixmap = 0;
744 UINT wFormat;
745 char * itemFmtName;
746 int xRc;
747 #if(0)
748 XSetWindowAttributes win_attr;
749 XWindowAttributes win_attr_src;
750 #endif
753 * Map the requested X selection property type atom name to a
754 * windows clipboard format ID.
756 itemFmtName = TSXGetAtomName(display, target);
757 wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
758 TRACE("Request for %s (wFormat=%x %s)\n",
759 itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat, NULL, 0 ));
760 TSXFree(itemFmtName);
762 hClipData = GetClipboardData(wFormat);
763 if ( !hClipData )
765 TRACE("Could not retrieve a Pixmap compatible format from clipboard!\n");
766 rprop = None; /* Fail the request */
767 goto END;
770 if (wFormat == CF_DIB)
772 HWND hwnd = GetOpenClipboardWindow();
773 HDC hdc = GetDC(hwnd);
775 /* For convert from packed DIB to Pixmap */
776 pixmap = X11DRV_DIB_CreatePixmapFromDIB(hClipData, hdc);
778 ReleaseDC(hwnd, hdc);
780 else if (wFormat == CF_BITMAP)
782 HWND hwnd = GetOpenClipboardWindow();
783 HDC hdc = GetDC(hwnd);
785 pixmap = X11DRV_BITMAP_CreatePixmapFromBitmap(hClipData, hdc);
787 ReleaseDC(hwnd, hdc);
789 else
791 FIXME("%s to PIXMAP conversion not yet implemented!\n",
792 CLIPBOARD_GetFormatName(wFormat, NULL, 0));
793 rprop = None;
794 goto END;
797 TRACE("\tUpdating property %s on Window %ld with %s %ld...\n",
798 TSXGetAtomName(display, rprop), (long)requestor,
799 TSXGetAtomName(display, target), pixmap);
801 /* Store the Pixmap handle in the property */
802 xRc = TSXChangeProperty(display, requestor, rprop, target,
803 32, PropModeReplace,
804 (unsigned char *)&pixmap, 1);
805 TRACE("(Rc=%d)\n", xRc);
807 /* Enable the code below if you want to handle destroying Pixmap resources
808 * in response to property notify events. Clients like XPaint don't
809 * appear to be duplicating Pixmaps so they don't like us deleting,
810 * the resource in response to the property being deleted.
812 #if(0)
813 /* Express interest in property notify events so that we can delete the
814 * pixmap when the client deletes the property atom.
816 xRc = TSXGetWindowAttributes(display, requestor, &win_attr_src);
817 TRACE("Turning on PropertyChangeEvent notifications from window %ld\n",
818 (long)requestor);
819 win_attr.event_mask = win_attr_src.your_event_mask | PropertyChangeMask;
820 TSXChangeWindowAttributes(display, requestor, CWEventMask, &win_attr);
822 /* Register the Pixmap we created with the request property Atom.
823 * When this property is destroyed we also destroy the Pixmap in
824 * response to the PropertyNotify event.
826 X11DRV_CLIPBOARD_RegisterPixmapResource( rprop, pixmap );
827 #endif
829 END:
830 return rprop;
834 /***********************************************************************
835 * EVENT_SelectionRequest_WCF
836 * Service a Wine Clipboard Format selection request event.
837 * For <WCF>* data types we simply copy the data to X without conversion.
839 static Atom EVENT_SelectionRequest_WCF( Display *display, Window requestor,
840 Atom target, Atom rprop )
842 HANDLE hClipData = 0;
843 void* lpClipData;
844 UINT wFormat;
845 char * itemFmtName;
846 int cBytes;
847 int xRc;
848 int bemf;
851 * Map the requested X selection property type atom name to a
852 * windows clipboard format ID.
854 itemFmtName = TSXGetAtomName(display, target);
855 wFormat = X11DRV_CLIPBOARD_MapPropertyToFormat(itemFmtName);
856 TRACE("Request for %s (wFormat=%x %s)\n",
857 itemFmtName, wFormat, CLIPBOARD_GetFormatName( wFormat, NULL, 0));
858 TSXFree(itemFmtName);
860 hClipData = GetClipboardData(wFormat);
862 bemf = wFormat == CF_METAFILEPICT || wFormat == CF_ENHMETAFILE;
863 if (bemf)
864 hClipData = X11DRV_CLIPBOARD_SerializeMetafile(wFormat, hClipData, sizeof(hClipData), TRUE);
866 if( hClipData && (lpClipData = GlobalLock(hClipData)) )
868 cBytes = GlobalSize(hClipData);
870 TRACE("\tUpdating property %s, %d bytes...\n",
871 TSXGetAtomName(display, rprop), cBytes);
873 xRc = TSXChangeProperty(display, requestor, rprop,
874 target, 8, PropModeReplace,
875 (unsigned char *)lpClipData, cBytes);
876 TRACE("(Rc=%d)\n", xRc);
878 GlobalUnlock(hClipData);
880 else
882 TRACE("\tCould not retrieve native format!\n");
883 rprop = None; /* Fail the request */
886 if (bemf) /* We must free serialized metafile data */
887 GlobalFree(hClipData);
889 return rprop;
893 /***********************************************************************
894 * EVENT_SelectionRequest_MULTIPLE
895 * Service a MULTIPLE selection request event
896 * rprop contains a list of (target,property) atom pairs.
897 * The first atom names a target and the second names a property.
898 * The effect is as if we have received a sequence of SelectionRequest events
899 * (one for each atom pair) except that:
900 * 1. We reply with a SelectionNotify only when all the requested conversions
901 * have been performed.
902 * 2. If we fail to convert the target named by an atom in the MULTIPLE property,
903 * we replace the atom in the property by None.
905 static Atom EVENT_SelectionRequest_MULTIPLE( HWND hWnd, XSelectionRequestEvent *pevent )
907 Display *display = pevent->display;
908 Atom rprop;
909 Atom atype=AnyPropertyType;
910 int aformat;
911 unsigned long remain;
912 Atom* targetPropList=NULL;
913 unsigned long cTargetPropList = 0;
914 /* Atom xAtomPair = TSXInternAtom(display, "ATOM_PAIR", False); */
916 /* If the specified property is None the requestor is an obsolete client.
917 * We support these by using the specified target atom as the reply property.
919 rprop = pevent->property;
920 if( rprop == None )
921 rprop = pevent->target;
922 if (!rprop)
923 goto END;
925 /* Read the MULTIPLE property contents. This should contain a list of
926 * (target,property) atom pairs.
928 if(TSXGetWindowProperty(display, pevent->requestor, rprop,
929 0, 0x3FFF, False, AnyPropertyType, &atype,&aformat,
930 &cTargetPropList, &remain,
931 (unsigned char**)&targetPropList) != Success)
932 TRACE("\tCouldn't read MULTIPLE property\n");
933 else
935 TRACE("\tType %s,Format %d,nItems %ld, Remain %ld\n",
936 TSXGetAtomName(display, atype), aformat, cTargetPropList, remain);
939 * Make sure we got what we expect.
940 * NOTE: According to the X-ICCCM Version 2.0 documentation the property sent
941 * in a MULTIPLE selection request should be of type ATOM_PAIR.
942 * However some X apps(such as XPaint) are not compliant with this and return
943 * a user defined atom in atype when XGetWindowProperty is called.
944 * The data *is* an atom pair but is not denoted as such.
946 if(aformat == 32 /* atype == xAtomPair */ )
948 int i;
950 /* Iterate through the ATOM_PAIR list and execute a SelectionRequest
951 * for each (target,property) pair */
953 for (i = 0; i < cTargetPropList; i+=2)
955 char *targetName = TSXGetAtomName(display, targetPropList[i]);
956 char *propName = TSXGetAtomName(display, targetPropList[i+1]);
957 XSelectionRequestEvent event;
959 TRACE("MULTIPLE(%d): Target='%s' Prop='%s'\n",
960 i/2, targetName, propName);
961 TSXFree(targetName);
962 TSXFree(propName);
964 /* We must have a non "None" property to service a MULTIPLE target atom */
965 if ( !targetPropList[i+1] )
967 TRACE("\tMULTIPLE(%d): Skipping target with empty property!\n", i);
968 continue;
971 /* Set up an XSelectionRequestEvent for this (target,property) pair */
972 memcpy( &event, pevent, sizeof(XSelectionRequestEvent) );
973 event.target = targetPropList[i];
974 event.property = targetPropList[i+1];
976 /* Fire a SelectionRequest, informing the handler that we are processing
977 * a MULTIPLE selection request event.
979 EVENT_SelectionRequest( hWnd, &event, TRUE );
983 /* Free the list of targets/properties */
984 TSXFree(targetPropList);
987 END:
988 return rprop;
992 /***********************************************************************
993 * EVENT_SelectionRequest
994 * Process an event selection request event.
995 * The bIsMultiple flag is used to signal when EVENT_SelectionRequest is called
996 * recursively while servicing a "MULTIPLE" selection target.
998 * Note: We only receive this event when WINE owns the X selection
1000 static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple )
1002 Display *display = event->display;
1003 XSelectionEvent result;
1004 Atom rprop = None;
1005 Window request = event->requestor;
1006 BOOL couldOpen = FALSE;
1007 Atom xaClipboard = TSXInternAtom(display, "CLIPBOARD", False);
1008 Atom xaTargets = TSXInternAtom(display, "TARGETS", False);
1009 Atom xaMultiple = TSXInternAtom(display, "MULTIPLE", False);
1012 * We can only handle the selection request if :
1013 * The selection is PRIMARY or CLIPBOARD, AND we can successfully open the clipboard.
1014 * Don't do these checks or open the clipboard while recursively processing MULTIPLE,
1015 * since this has been already done.
1017 if ( !bIsMultiple )
1019 if ( ( (event->selection != XA_PRIMARY) && (event->selection != xaClipboard) )
1020 || !(couldOpen = OpenClipboard(hWnd)) )
1021 goto END;
1024 /* If the specified property is None the requestor is an obsolete client.
1025 * We support these by using the specified target atom as the reply property.
1027 rprop = event->property;
1028 if( rprop == None )
1029 rprop = event->target;
1031 if(event->target == xaTargets) /* Return a list of all supported targets */
1033 /* TARGETS selection request */
1034 rprop = EVENT_SelectionRequest_TARGETS( display, request, event->target, rprop );
1036 else if(event->target == xaMultiple) /* rprop contains a list of (target, property) atom pairs */
1038 /* MULTIPLE selection request */
1039 rprop = EVENT_SelectionRequest_MULTIPLE( hWnd, event );
1041 else if(event->target == XA_STRING) /* treat CF_TEXT as Unix text */
1043 /* XA_STRING selection request */
1044 rprop = EVENT_SelectionRequest_STRING( display, request, event->target, rprop );
1046 else if(event->target == XA_PIXMAP) /* Convert DIB's to Pixmaps */
1048 /* XA_PIXMAP selection request */
1049 rprop = EVENT_SelectionRequest_PIXMAP( display, request, event->target, rprop );
1051 else if(event->target == XA_BITMAP) /* Convert DIB's to 1-bit Pixmaps */
1053 /* XA_BITMAP selection request - TODO: create a monochrome Pixmap */
1054 rprop = EVENT_SelectionRequest_PIXMAP( display, request, XA_PIXMAP, rprop );
1056 else if(X11DRV_CLIPBOARD_IsNativeProperty(event->target)) /* <WCF>* */
1058 /* All <WCF> selection requests */
1059 rprop = EVENT_SelectionRequest_WCF( display, request, event->target, rprop );
1061 else
1062 rprop = None; /* Don't support this format */
1064 END:
1065 /* close clipboard only if we opened before */
1066 if(couldOpen) CloseClipboard();
1068 if( rprop == None)
1069 TRACE("\tRequest ignored\n");
1071 /* reply to sender
1072 * SelectionNotify should be sent only at the end of a MULTIPLE request
1074 if ( !bIsMultiple )
1076 result.type = SelectionNotify;
1077 result.display = display;
1078 result.requestor = request;
1079 result.selection = event->selection;
1080 result.property = rprop;
1081 result.target = event->target;
1082 result.time = event->time;
1083 TRACE("Sending SelectionNotify event...\n");
1084 TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
1088 /***********************************************************************
1089 * EVENT_SelectionClear
1091 static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event )
1093 Atom xaClipboard = TSXInternAtom(event->display, "CLIPBOARD", False);
1095 if (event->selection == XA_PRIMARY || event->selection == xaClipboard)
1096 X11DRV_CLIPBOARD_ReleaseSelection( event->selection, event->window, hWnd );
1099 /***********************************************************************
1100 * EVENT_PropertyNotify
1101 * We use this to release resources like Pixmaps when a selection
1102 * client no longer needs them.
1104 static void EVENT_PropertyNotify( XPropertyEvent *event )
1106 /* Check if we have any resources to free */
1107 TRACE("Received PropertyNotify event: \n");
1109 switch(event->state)
1111 case PropertyDelete:
1113 TRACE("\tPropertyDelete for atom %s on window %ld\n",
1114 TSXGetAtomName(event->display, event->atom), (long)event->window);
1116 if (X11DRV_IsSelectionOwner())
1117 X11DRV_CLIPBOARD_FreeResources( event->atom );
1118 break;
1121 case PropertyNewValue:
1123 TRACE("\tPropertyNewValue for atom %s on window %ld\n\n",
1124 TSXGetAtomName(event->display, event->atom), (long)event->window);
1125 break;
1128 default:
1129 break;
1133 static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt )
1135 RECT tempRect;
1137 if (!IsWindowEnabled(hQueryWnd)) return 0;
1139 GetWindowRect(hQueryWnd, &tempRect);
1141 if(!PtInRect(&tempRect, *lpPt)) return 0;
1143 if (!IsIconic( hQueryWnd ))
1145 GetClientRect( hQueryWnd, &tempRect );
1146 MapWindowPoints( hQueryWnd, 0, (LPPOINT)&tempRect, 2 );
1148 if (PtInRect( &tempRect, *lpPt))
1150 HWND *list = WIN_ListChildren( hQueryWnd );
1151 HWND bResult = 0;
1153 if (list)
1155 int i;
1157 for (i = 0; list[i]; i++)
1159 if (GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE)
1161 GetWindowRect( list[i], &tempRect );
1162 if (PtInRect( &tempRect, *lpPt )) break;
1165 if (list[i])
1167 if (IsWindowEnabled( list[i] ))
1168 bResult = find_drop_window( list[i], lpPt );
1170 HeapFree( GetProcessHeap(), 0, list );
1172 if(bResult) return bResult;
1176 if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0;
1178 ScreenToClient(hQueryWnd, lpPt);
1180 return hQueryWnd;
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;
1193 union {
1194 Atom atom_aux;
1195 struct {
1196 int x;
1197 int y;
1198 } pt_aux;
1199 int i;
1200 } u;
1201 int x, y;
1202 BOOL bAccept;
1203 Window w_aux_root, w_aux_child;
1204 WND* pWnd;
1205 HWND hScope = hWnd;
1207 pWnd = WIN_FindWndPtr(hWnd);
1209 TSXQueryPointer( event->display, get_whole_window(pWnd), &w_aux_root, &w_aux_child,
1210 &x, &y, (int *) &u.pt_aux.x, (int *) &u.pt_aux.y,
1211 (unsigned int*)&aux_long);
1213 /* find out drop point and drop window */
1214 if( x < 0 || y < 0 ||
1215 x > (pWnd->rectWindow.right - pWnd->rectWindow.left) ||
1216 y > (pWnd->rectWindow.bottom - pWnd->rectWindow.top) )
1218 bAccept = pWnd->dwExStyle & WS_EX_ACCEPTFILES;
1219 x = 0;
1220 y = 0;
1222 else
1224 POINT pt = { x, y };
1225 HWND hwndDrop = find_drop_window( hWnd, &pt );
1226 if (hwndDrop)
1228 x = pt.x;
1229 y = pt.y;
1230 hScope = hwndDrop;
1231 bAccept = TRUE;
1233 else
1235 bAccept = FALSE;
1238 WIN_ReleaseWndPtr(pWnd);
1240 if (!bAccept) return;
1242 TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
1243 dndSelection, 0, 65535, FALSE,
1244 AnyPropertyType, &u.atom_aux, (int *) &u.pt_aux.y,
1245 &data_length, &aux_long, &p_data);
1247 if( !aux_long && p_data) /* don't bother if > 64K */
1249 signed char *p = (signed char*) p_data;
1250 char *p_drop;
1252 aux_long = 0;
1253 while( *p ) /* calculate buffer size */
1255 p_drop = p;
1256 if((u.i = *p) != -1 )
1258 INT len = GetShortPathNameA( p, NULL, 0 );
1259 if (len) aux_long += len + 1;
1260 else *p = -1;
1262 p += strlen(p) + 1;
1264 if( aux_long && aux_long < 65535 )
1266 HDROP hDrop;
1267 DROPFILES *lpDrop;
1269 aux_long += sizeof(DROPFILES) + 1;
1270 hDrop = GlobalAlloc( GMEM_SHARE, aux_long );
1271 lpDrop = (DROPFILES*)GlobalLock( hDrop );
1273 if( lpDrop )
1275 WND *pDropWnd = WIN_FindWndPtr( hScope );
1276 lpDrop->pFiles = sizeof(DROPFILES);
1277 lpDrop->pt.x = x;
1278 lpDrop->pt.y = y;
1279 lpDrop->fNC =
1280 ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
1281 y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
1282 x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
1283 y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
1284 lpDrop->fWide = FALSE;
1285 WIN_ReleaseWndPtr(pDropWnd);
1286 p_drop = (char *)(lpDrop + 1);
1287 p = p_data;
1288 while(*p)
1290 if( *p != -1 ) /* use only "good" entries */
1292 GetShortPathNameA( p, p_drop, 65535 );
1293 p_drop += strlen( p_drop ) + 1;
1295 p += strlen(p) + 1;
1297 *p_drop = '\0';
1298 PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
1302 if( p_data ) TSXFree(p_data);
1305 /**********************************************************************
1306 * EVENT_DropURLs
1308 * drop items are separated by \n
1309 * each item is prefixed by its mime type
1311 * event->data.l[3], event->data.l[4] contains drop x,y position
1313 static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
1315 unsigned long data_length;
1316 unsigned long aux_long, drop_len = 0;
1317 unsigned char *p_data = NULL; /* property data */
1318 char *p_drop = NULL;
1319 char *p, *next;
1320 int x, y;
1321 DROPFILES *lpDrop;
1322 HDROP hDrop;
1323 union {
1324 Atom atom_aux;
1325 int i;
1326 Window w_aux;
1327 } u; /* unused */
1329 if (!(GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return;
1331 TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
1332 dndSelection, 0, 65535, FALSE,
1333 AnyPropertyType, &u.atom_aux, &u.i,
1334 &data_length, &aux_long, &p_data);
1335 if (aux_long)
1336 WARN("property too large, truncated!\n");
1337 TRACE("urls=%s\n", p_data);
1339 if( !aux_long && p_data) { /* don't bother if > 64K */
1340 /* calculate length */
1341 p = p_data;
1342 next = strchr(p, '\n');
1343 while (p) {
1344 if (next) *next=0;
1345 if (strncmp(p,"file:",5) == 0 ) {
1346 INT len = GetShortPathNameA( p+5, NULL, 0 );
1347 if (len) drop_len += len + 1;
1349 if (next) {
1350 *next = '\n';
1351 p = next + 1;
1352 next = strchr(p, '\n');
1353 } else {
1354 p = NULL;
1358 if( drop_len && drop_len < 65535 ) {
1359 TSXQueryPointer( event->display, root_window, &u.w_aux, &u.w_aux,
1360 &x, &y, &u.i, &u.i, &u.i);
1362 drop_len += sizeof(DROPFILES) + 1;
1363 hDrop = GlobalAlloc( GMEM_SHARE, drop_len );
1364 lpDrop = (DROPFILES *) GlobalLock( hDrop );
1366 if( lpDrop ) {
1367 WND *pDropWnd = WIN_FindWndPtr( hWnd );
1368 lpDrop->pFiles = sizeof(DROPFILES);
1369 lpDrop->pt.x = (INT)x;
1370 lpDrop->pt.y = (INT)y;
1371 lpDrop->fNC =
1372 ( x < (pDropWnd->rectClient.left - pDropWnd->rectWindow.left) ||
1373 y < (pDropWnd->rectClient.top - pDropWnd->rectWindow.top) ||
1374 x > (pDropWnd->rectClient.right - pDropWnd->rectWindow.left) ||
1375 y > (pDropWnd->rectClient.bottom - pDropWnd->rectWindow.top) );
1376 lpDrop->fWide = FALSE;
1377 p_drop = (char*)(lpDrop + 1);
1378 WIN_ReleaseWndPtr(pDropWnd);
1381 /* create message content */
1382 if (p_drop) {
1383 p = p_data;
1384 next = strchr(p, '\n');
1385 while (p) {
1386 if (next) *next=0;
1387 if (strncmp(p,"file:",5) == 0 ) {
1388 INT len = GetShortPathNameA( p+5, p_drop, 65535 );
1389 if (len) {
1390 TRACE("drop file %s as %s\n", p+5, p_drop);
1391 p_drop += len+1;
1392 } else {
1393 WARN("can't convert file %s to dos name \n", p+5);
1395 } else {
1396 WARN("unknown mime type %s\n", p);
1398 if (next) {
1399 *next = '\n';
1400 p = next + 1;
1401 next = strchr(p, '\n');
1402 } else {
1403 p = NULL;
1405 *p_drop = '\0';
1408 GlobalUnlock(hDrop);
1409 PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
1412 if( p_data ) TSXFree(p_data);
1416 /**********************************************************************
1417 * EVENT_ClientMessage
1419 static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event )
1421 if (event->message_type != None && event->format == 32) {
1422 if (event->message_type == wmProtocols)
1423 handle_wm_protocols_message( hWnd, event );
1424 else if (event->message_type == dndProtocol)
1426 /* query window (drag&drop event contains only drag window) */
1427 Window root, child;
1428 int root_x, root_y, child_x, child_y;
1429 unsigned int u;
1431 wine_tsx11_lock();
1432 XQueryPointer( event->display, root_window, &root, &child,
1433 &root_x, &root_y, &child_x, &child_y, &u);
1434 if (XFindContext( event->display, child, winContext, (char **)&hWnd ) != 0) hWnd = 0;
1435 wine_tsx11_unlock();
1436 if (!hWnd) return;
1437 if (event->data.l[0] == DndFile || event->data.l[0] == DndFiles)
1438 EVENT_DropFromOffiX(hWnd, event);
1439 else if (event->data.l[0] == DndURL)
1440 EVENT_DropURLs(hWnd, event);
1442 else {
1443 #if 0
1444 /* enable this if you want to see the message */
1445 unsigned char* p_data = NULL;
1446 union {
1447 unsigned long l;
1448 int i;
1449 Atom atom;
1450 } u; /* unused */
1451 TSXGetWindowProperty( event->display, DefaultRootWindow(event->display),
1452 dndSelection, 0, 65535, FALSE,
1453 AnyPropertyType, &u.atom, &u.i,
1454 &u.l, &u.l, &p_data);
1455 TRACE("message_type=%ld, data=%ld,%ld,%ld,%ld,%ld, msg=%s\n",
1456 event->message_type, event->data.l[0], event->data.l[1],
1457 event->data.l[2], event->data.l[3], event->data.l[4],
1458 p_data);
1459 #endif
1460 TRACE("unrecognized ClientMessage\n" );
1466 /**********************************************************************
1467 * X11DRV_EVENT_SetInputMethod
1469 INPUT_TYPE X11DRV_EVENT_SetInputMethod(INPUT_TYPE type)
1471 INPUT_TYPE prev = current_input_type;
1473 /* Flag not used yet */
1474 in_transition = FALSE;
1475 current_input_type = type;
1477 return prev;
1480 #ifdef HAVE_LIBXXF86DGA2
1481 /**********************************************************************
1482 * X11DRV_EVENT_SetDGAStatus
1484 void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base)
1486 if (event_base < 0) {
1487 DGAUsed = FALSE;
1488 DGAhwnd = 0;
1489 } else {
1490 DGAUsed = TRUE;
1491 DGAhwnd = hwnd;
1492 DGAMotionEventType = event_base + MotionNotify;
1493 DGAButtonPressEventType = event_base + ButtonPress;
1494 DGAButtonReleaseEventType = event_base + ButtonRelease;
1495 DGAKeyPressEventType = event_base + KeyPress;
1496 DGAKeyReleaseEventType = event_base + KeyRelease;
1499 #endif