Add a function to XSendEvent() and call a calback on failure/success.
Fri Jul 4 22:57:18 2003 Owen Taylor <otaylor@redhat.com> * gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add a function to XSendEvent() and call a calback on failure/success. * gdk/x11/gdkdnd-x11.c (xdnd_send_xevent): Short-circuit messages to the same process, use _gdk_send_xevent_async().
This commit is contained in:
		@ -1,3 +1,12 @@
 | 
				
			|||||||
 | 
					Fri Jul  4 22:57:18 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
 | 
				
			||||||
 | 
						a function to XSendEvent() and call a calback on
 | 
				
			||||||
 | 
						failure/success.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkdnd-x11.c (xdnd_send_xevent): Short-circuit
 | 
				
			||||||
 | 
						messages to the same process, use _gdk_send_xevent_async().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
					Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
						* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,12 @@
 | 
				
			|||||||
 | 
					Fri Jul  4 22:57:18 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
 | 
				
			||||||
 | 
						a function to XSendEvent() and call a calback on
 | 
				
			||||||
 | 
						failure/success.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkdnd-x11.c (xdnd_send_xevent): Short-circuit
 | 
				
			||||||
 | 
						messages to the same process, use _gdk_send_xevent_async().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
					Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
						* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,12 @@
 | 
				
			|||||||
 | 
					Fri Jul  4 22:57:18 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
 | 
				
			||||||
 | 
						a function to XSendEvent() and call a calback on
 | 
				
			||||||
 | 
						failure/success.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkdnd-x11.c (xdnd_send_xevent): Short-circuit
 | 
				
			||||||
 | 
						messages to the same process, use _gdk_send_xevent_async().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
					Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
						* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,12 @@
 | 
				
			|||||||
 | 
					Fri Jul  4 22:57:18 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
 | 
				
			||||||
 | 
						a function to XSendEvent() and call a calback on
 | 
				
			||||||
 | 
						failure/success.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkdnd-x11.c (xdnd_send_xevent): Short-circuit
 | 
				
			||||||
 | 
						messages to the same process, use _gdk_send_xevent_async().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
					Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
						* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,12 @@
 | 
				
			|||||||
 | 
					Fri Jul  4 22:57:18 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkasync.[ch] (_gdk_send_xevent_async): Add
 | 
				
			||||||
 | 
						a function to XSendEvent() and call a calback on
 | 
				
			||||||
 | 
						failure/success.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* gdk/x11/gdkdnd-x11.c (xdnd_send_xevent): Short-circuit
 | 
				
			||||||
 | 
						messages to the same process, use _gdk_send_xevent_async().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
					Fri Jul  4 22:26:27 2003  Owen Taylor  <otaylor@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
						* gdk/x11/gdkwindow-x11.[ch] gdkevents-x11.c: Split
 | 
				
			||||||
 | 
				
			|||||||
@ -47,17 +47,155 @@ in this Software without prior written authorization from The Open Group.
 | 
				
			|||||||
#include "gdkasync.h"
 | 
					#include "gdkasync.h"
 | 
				
			||||||
#include "gdkx.h"
 | 
					#include "gdkx.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct _SendEventState SendEventState;
 | 
				
			||||||
typedef struct _SetInputFocusState SetInputFocusState;
 | 
					typedef struct _SetInputFocusState SetInputFocusState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _SetInputFocusState
 | 
					struct _SendEventState
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  Display *dpy;
 | 
					  Display *dpy;
 | 
				
			||||||
  Window window;
 | 
					  Window window;
 | 
				
			||||||
  _XAsyncHandler async;
 | 
					  _XAsyncHandler async;
 | 
				
			||||||
 | 
					  gulong send_event_req;
 | 
				
			||||||
 | 
					  gulong get_input_focus_req;
 | 
				
			||||||
 | 
					  gboolean have_error;
 | 
				
			||||||
 | 
					  GdkSendXEventCallback callback;
 | 
				
			||||||
 | 
					  gpointer data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct _SetInputFocusState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Display *dpy;
 | 
				
			||||||
 | 
					  _XAsyncHandler async;
 | 
				
			||||||
  gulong set_input_focus_req;
 | 
					  gulong set_input_focus_req;
 | 
				
			||||||
  gulong get_input_focus_req;
 | 
					  gulong get_input_focus_req;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Bool
 | 
				
			||||||
 | 
					send_event_handler (Display *dpy,
 | 
				
			||||||
 | 
							    xReply  *rep,
 | 
				
			||||||
 | 
							    char    *buf,
 | 
				
			||||||
 | 
							    int      len,
 | 
				
			||||||
 | 
							    XPointer data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  SendEventState *state = (SendEventState *)data;  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (dpy->last_request_read == state->send_event_req)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (rep->generic.type == X_Error)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						  if (rep->error.errorCode == BadWindow)
 | 
				
			||||||
 | 
						    {
 | 
				
			||||||
 | 
						      state->have_error = TRUE;
 | 
				
			||||||
 | 
						      return True;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else if (dpy->last_request_read == state->get_input_focus_req)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      xGetInputFocusReply replbuf;
 | 
				
			||||||
 | 
					      xGetInputFocusReply *repl;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      if (rep->generic.type != X_Error)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						  repl = (xGetInputFocusReply *)
 | 
				
			||||||
 | 
						    _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
 | 
				
			||||||
 | 
								    (sizeof(xGetInputFocusReply) - sizeof(xReply)) >> 2,
 | 
				
			||||||
 | 
								    True);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (state->callback)
 | 
				
			||||||
 | 
						state->callback (state->window, !state->have_error, state->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      DeqAsyncHandler(state->dpy, &state->async);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      g_free (state);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      return True;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return False;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					_gdk_send_xevent_async (GdkDisplay           *display, 
 | 
				
			||||||
 | 
								Window                window, 
 | 
				
			||||||
 | 
								gboolean              propagate,
 | 
				
			||||||
 | 
								glong                 event_mask,
 | 
				
			||||||
 | 
								XEvent               *event_send,
 | 
				
			||||||
 | 
								GdkSendXEventCallback callback,
 | 
				
			||||||
 | 
								gpointer              data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Display *dpy;
 | 
				
			||||||
 | 
					  SendEventState *state;
 | 
				
			||||||
 | 
					  Status status;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  dpy = GDK_DISPLAY_XDISPLAY (display);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  state = g_new (SendEventState, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  state->dpy = dpy;
 | 
				
			||||||
 | 
					  state->window = window;
 | 
				
			||||||
 | 
					  state->callback = callback;
 | 
				
			||||||
 | 
					  state->data = data;
 | 
				
			||||||
 | 
					  state->have_error = FALSE;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  LockDisplay(dpy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  state->async.next = dpy->async_handlers;
 | 
				
			||||||
 | 
					  state->async.handler = send_event_handler;
 | 
				
			||||||
 | 
					  state->async.data = (XPointer) state;
 | 
				
			||||||
 | 
					  dpy->async_handlers = &state->async;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    register xSendEventReq *req;
 | 
				
			||||||
 | 
					    xEvent ev;
 | 
				
			||||||
 | 
					    register Status (**fp)();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /* call through display to find proper conversion routine */
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    fp = &dpy->wire_vec[event_send->type & 0177];
 | 
				
			||||||
 | 
					    if (*fp == NULL) *fp = _XEventToWire;
 | 
				
			||||||
 | 
					    status = (**fp)(dpy, event_send, &ev);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!status)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
						g_warning ("Error converting event to wire");
 | 
				
			||||||
 | 
						DeqAsyncHandler(dpy, &state->async);
 | 
				
			||||||
 | 
						UnlockDisplay(dpy);
 | 
				
			||||||
 | 
						SyncHandle();
 | 
				
			||||||
 | 
						g_free (state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					    GetReq(SendEvent, req);
 | 
				
			||||||
 | 
					    req->destination = window;
 | 
				
			||||||
 | 
					    req->propagate = propagate;
 | 
				
			||||||
 | 
					    req->eventMask = event_mask;
 | 
				
			||||||
 | 
					    /* gross, matches Xproto.h */
 | 
				
			||||||
 | 
					#ifdef WORD64			
 | 
				
			||||||
 | 
					    memcpy ((char *) req->eventdata, (char *) &ev, SIZEOF(xEvent));
 | 
				
			||||||
 | 
					#else    
 | 
				
			||||||
 | 
					    memcpy ((char *) &req->event, (char *) &ev, SIZEOF(xEvent));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    state->send_event_req = dpy->request;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * XSync (dpy, 0)
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    xReq *req;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    GetEmptyReq(GetInputFocus, req);
 | 
				
			||||||
 | 
					    state->get_input_focus_req = dpy->request;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  UnlockDisplay(dpy);
 | 
				
			||||||
 | 
					  SyncHandle();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Bool
 | 
					static Bool
 | 
				
			||||||
set_input_focus_handler (Display *dpy,
 | 
					set_input_focus_handler (Display *dpy,
 | 
				
			||||||
			 xReply  *rep,
 | 
								 xReply  *rep,
 | 
				
			||||||
@ -119,7 +257,6 @@ _gdk_x11_set_input_focus_safe (GdkDisplay             *display,
 | 
				
			|||||||
  state = g_new (SetInputFocusState, 1);
 | 
					  state = g_new (SetInputFocusState, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  state->dpy = dpy;
 | 
					  state->dpy = dpy;
 | 
				
			||||||
  state->window = window;
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  LockDisplay(dpy);
 | 
					  LockDisplay(dpy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
G_BEGIN_DECLS
 | 
					G_BEGIN_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (*GdkSendXEventCallback) (Window   window,
 | 
				
			||||||
 | 
									       gboolean success,
 | 
				
			||||||
 | 
									       gpointer data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void _gdk_send_xevent_async        (GdkDisplay            *display,
 | 
				
			||||||
 | 
									    Window                 window,
 | 
				
			||||||
 | 
									    gboolean               propagate,
 | 
				
			||||||
 | 
									    glong                  event_mask,
 | 
				
			||||||
 | 
									    XEvent                *event_send,
 | 
				
			||||||
 | 
									    GdkSendXEventCallback  callback,
 | 
				
			||||||
 | 
									    gpointer               data);
 | 
				
			||||||
void _gdk_x11_set_input_focus_safe (GdkDisplay            *display,
 | 
					void _gdk_x11_set_input_focus_safe (GdkDisplay            *display,
 | 
				
			||||||
				    Window                 window,
 | 
									    Window                 window,
 | 
				
			||||||
				    int                    revert_to,
 | 
									    int                    revert_to,
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "gdk.h"          /* For gdk_flush() */
 | 
					#include "gdk.h"          /* For gdk_flush() */
 | 
				
			||||||
#include "gdkx.h"
 | 
					#include "gdkx.h"
 | 
				
			||||||
 | 
					#include "gdkasync.h"
 | 
				
			||||||
#include "gdkdnd.h"
 | 
					#include "gdkdnd.h"
 | 
				
			||||||
#include "gdkproperty.h"
 | 
					#include "gdkproperty.h"
 | 
				
			||||||
#include "gdkprivate-x11.h"
 | 
					#include "gdkprivate-x11.h"
 | 
				
			||||||
@ -101,23 +102,18 @@ static GdkFilterReturn motif_dnd_filter (GdkXEvent *xev,
 | 
				
			|||||||
static GdkFilterReturn xdnd_enter_filter    (GdkXEvent *xev,
 | 
					static GdkFilterReturn xdnd_enter_filter    (GdkXEvent *xev,
 | 
				
			||||||
					     GdkEvent  *event,
 | 
										     GdkEvent  *event,
 | 
				
			||||||
					     gpointer   data);
 | 
										     gpointer   data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
static GdkFilterReturn xdnd_leave_filter    (GdkXEvent *xev,
 | 
					static GdkFilterReturn xdnd_leave_filter    (GdkXEvent *xev,
 | 
				
			||||||
					     GdkEvent  *event,
 | 
										     GdkEvent  *event,
 | 
				
			||||||
					     gpointer   data);
 | 
										     gpointer   data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
static GdkFilterReturn xdnd_position_filter (GdkXEvent *xev,
 | 
					static GdkFilterReturn xdnd_position_filter (GdkXEvent *xev,
 | 
				
			||||||
					     GdkEvent  *event,
 | 
										     GdkEvent  *event,
 | 
				
			||||||
					     gpointer   data);
 | 
										     gpointer   data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
static GdkFilterReturn xdnd_status_filter   (GdkXEvent *xev,
 | 
					static GdkFilterReturn xdnd_status_filter   (GdkXEvent *xev,
 | 
				
			||||||
					     GdkEvent  *event,
 | 
										     GdkEvent  *event,
 | 
				
			||||||
					     gpointer   data);
 | 
										     gpointer   data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
static GdkFilterReturn xdnd_finished_filter (GdkXEvent *xev,
 | 
					static GdkFilterReturn xdnd_finished_filter (GdkXEvent *xev,
 | 
				
			||||||
					     GdkEvent  *event,
 | 
										     GdkEvent  *event,
 | 
				
			||||||
					     gpointer   data);
 | 
										     gpointer   data);
 | 
				
			||||||
 | 
					 | 
				
			||||||
static GdkFilterReturn xdnd_drop_filter     (GdkXEvent *xev,
 | 
					static GdkFilterReturn xdnd_drop_filter     (GdkXEvent *xev,
 | 
				
			||||||
					     GdkEvent  *event,
 | 
										     GdkEvent  *event,
 | 
				
			||||||
					     gpointer   data);
 | 
										     gpointer   data);
 | 
				
			||||||
@ -133,6 +129,18 @@ static void gdk_drag_context_finalize   (GObject              *object);
 | 
				
			|||||||
static gpointer parent_class = NULL;
 | 
					static gpointer parent_class = NULL;
 | 
				
			||||||
static GList *contexts;
 | 
					static GList *contexts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const static struct {
 | 
				
			||||||
 | 
					  const char *atom_name;
 | 
				
			||||||
 | 
					  GdkFilterFunc func;
 | 
				
			||||||
 | 
					} xdnd_filters[] = {
 | 
				
			||||||
 | 
					  { "XdndEnter",    xdnd_enter_filter },
 | 
				
			||||||
 | 
					  { "XdndLeave",    xdnd_leave_filter },
 | 
				
			||||||
 | 
					  { "XdndPosition", xdnd_position_filter },
 | 
				
			||||||
 | 
					  { "XdndStatus",   xdnd_status_filter },
 | 
				
			||||||
 | 
					  { "XdndFinished", xdnd_finished_filter },
 | 
				
			||||||
 | 
					  { "XdndDrop",     xdnd_drop_filter },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
						      
 | 
				
			||||||
GType
 | 
					GType
 | 
				
			||||||
gdk_drag_context_get_type (void)
 | 
					gdk_drag_context_get_type (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -2090,26 +2098,114 @@ xdnd_set_actions (GdkDragContext *context)
 | 
				
			|||||||
  private->xdnd_actions = context->actions;
 | 
					  private->xdnd_actions = context->actions;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*************************************************************
 | 
					static void
 | 
				
			||||||
 * xdnd_send_xevent:
 | 
					send_xevent_async_cb (Window   window,
 | 
				
			||||||
 *     Like gdk_send_event, but if the target is the root
 | 
							      gboolean success,
 | 
				
			||||||
 *     window, sets an event mask of ButtonPressMask, otherwise
 | 
							      gpointer data)
 | 
				
			||||||
 *     an event mask of 0.
 | 
					{
 | 
				
			||||||
 *   arguments:
 | 
					  GdkDragContext *context = data;
 | 
				
			||||||
 *     
 | 
					  GDK_NOTE (DND,
 | 
				
			||||||
 *   results:
 | 
						    g_message ("Got async callback for #%lx, success = %d",
 | 
				
			||||||
 *************************************************************/
 | 
							       window, success));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* On failure, we immediately continue with the protocol
 | 
				
			||||||
 | 
					   * so we don't end up blocking for a timeout
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  if (!success &&
 | 
				
			||||||
 | 
					      context->dest_window &&
 | 
				
			||||||
 | 
					      window == GDK_WINDOW_XID (context->dest_window))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      GdkEvent temp_event;
 | 
				
			||||||
 | 
					      GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      g_object_unref (context->dest_window);
 | 
				
			||||||
 | 
					      context->dest_window = NULL;
 | 
				
			||||||
 | 
					      context->action = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      private->drag_status = GDK_DRAG_STATUS_DRAG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      temp_event.dnd.type = GDK_DRAG_STATUS;
 | 
				
			||||||
 | 
					      temp_event.dnd.window = context->source_window;
 | 
				
			||||||
 | 
					      temp_event.dnd.send_event = TRUE;
 | 
				
			||||||
 | 
					      temp_event.dnd.context = context;
 | 
				
			||||||
 | 
					      temp_event.dnd.time = GDK_CURRENT_TIME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      gdk_event_put (&temp_event);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_object_unref (context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GdkDisplay *
 | 
				
			||||||
 | 
					gdk_drag_context_get_display (GdkDragContext *context)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (context->source_window)
 | 
				
			||||||
 | 
					    return GDK_DRAWABLE_DISPLAY (context->source_window);
 | 
				
			||||||
 | 
					  else if (context->dest_window)
 | 
				
			||||||
 | 
					    return GDK_DRAWABLE_DISPLAY (context->dest_window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  g_assert_not_reached ();
 | 
				
			||||||
 | 
					  return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					send_xevent_async (GdkDragContext *context,
 | 
				
			||||||
 | 
							   Window          window, 
 | 
				
			||||||
 | 
							   gboolean        propagate,
 | 
				
			||||||
 | 
							   glong           event_mask,
 | 
				
			||||||
 | 
							   XEvent         *event_send)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  GdkDisplay *display = gdk_drag_context_get_display (context);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  g_object_ref (context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _gdk_send_xevent_async (display, window, propagate, event_mask, event_send,
 | 
				
			||||||
 | 
								  send_xevent_async_cb, context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static gboolean
 | 
					static gboolean
 | 
				
			||||||
xdnd_send_xevent (GdkDisplay *display, 
 | 
					xdnd_send_xevent (GdkDragContext *context,
 | 
				
			||||||
		  Window      window, 
 | 
							  GdkWindow      *window, 
 | 
				
			||||||
		  gboolean        propagate,
 | 
							  gboolean        propagate,
 | 
				
			||||||
		  XEvent         *event_send)
 | 
							  XEvent         *event_send)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (_gdk_x11_display_is_root_window (display, window))
 | 
					  GdkDisplay *display = gdk_drag_context_get_display (context);
 | 
				
			||||||
    return _gdk_send_xevent (display, window, propagate, ButtonPressMask, event_send);
 | 
					  Window xwindow;
 | 
				
			||||||
 | 
					  glong event_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* We short-circuit messages to ourselves */
 | 
				
			||||||
 | 
					  if (gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN &&
 | 
				
			||||||
 | 
					      event_send->xany.type == ClientMessage)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      gint i;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      for (i = 0; i < G_N_ELEMENTS (xdnd_filters); i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						  if (gdk_x11_get_xatom_by_name_for_display (display, xdnd_filters[i].atom_name) ==
 | 
				
			||||||
 | 
						      event_send->xclient.message_type)
 | 
				
			||||||
 | 
						    {
 | 
				
			||||||
 | 
						      GdkEvent temp_event;
 | 
				
			||||||
 | 
						      temp_event.any.window = window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						      if  ((*xdnd_filters[i].func) (event_send, &temp_event, NULL) == GDK_FILTER_TRANSLATE)
 | 
				
			||||||
 | 
							gdk_event_put (&temp_event);
 | 
				
			||||||
 | 
						      
 | 
				
			||||||
 | 
						      return TRUE;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xwindow = GDK_WINDOW_XWINDOW (window);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (_gdk_x11_display_is_root_window (display, xwindow))
 | 
				
			||||||
 | 
					    event_mask = ButtonPressMask;
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    return _gdk_send_xevent (display, window, propagate, 0, event_send);
 | 
					    event_mask = 0;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  send_xevent_async (context, xwindow, propagate, event_mask, event_send);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -2154,8 +2250,7 @@ xdnd_send_enter (GdkDragContext *context)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!xdnd_send_xevent (display,
 | 
					  if (!xdnd_send_xevent (context, context->dest_window,
 | 
				
			||||||
			 GDK_DRAWABLE_XID (context->dest_window),
 | 
					 | 
				
			||||||
			 FALSE, &xev))
 | 
								 FALSE, &xev))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      GDK_NOTE (DND, 
 | 
					      GDK_NOTE (DND, 
 | 
				
			||||||
@ -2186,8 +2281,7 @@ xdnd_send_leave (GdkDragContext *context)
 | 
				
			|||||||
  xev.xclient.data.l[3] = 0;
 | 
					  xev.xclient.data.l[3] = 0;
 | 
				
			||||||
  xev.xclient.data.l[4] = 0;
 | 
					  xev.xclient.data.l[4] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!xdnd_send_xevent (display,
 | 
					  if (!xdnd_send_xevent (context, context->dest_window,
 | 
				
			||||||
			 GDK_DRAWABLE_XID (context->dest_window),
 | 
					 | 
				
			||||||
			 FALSE, &xev))
 | 
								 FALSE, &xev))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      GDK_NOTE (DND, 
 | 
					      GDK_NOTE (DND, 
 | 
				
			||||||
@ -2217,8 +2311,7 @@ xdnd_send_drop (GdkDragContext *context, guint32 time)
 | 
				
			|||||||
  xev.xclient.data.l[3] = 0;
 | 
					  xev.xclient.data.l[3] = 0;
 | 
				
			||||||
  xev.xclient.data.l[4] = 0;
 | 
					  xev.xclient.data.l[4] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!xdnd_send_xevent (display,
 | 
					  if (!xdnd_send_xevent (context, context->dest_window,
 | 
				
			||||||
			 GDK_DRAWABLE_XID (context->dest_window),
 | 
					 | 
				
			||||||
			 FALSE, &xev))
 | 
								 FALSE, &xev))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      GDK_NOTE (DND, 
 | 
					      GDK_NOTE (DND, 
 | 
				
			||||||
@ -2252,8 +2345,7 @@ xdnd_send_motion (GdkDragContext *context,
 | 
				
			|||||||
  xev.xclient.data.l[3] = time;
 | 
					  xev.xclient.data.l[3] = time;
 | 
				
			||||||
  xev.xclient.data.l[4] = xdnd_action_to_atom (display, action);
 | 
					  xev.xclient.data.l[4] = xdnd_action_to_atom (display, action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!xdnd_send_xevent (display,
 | 
					  if (!xdnd_send_xevent (context, context->dest_window,
 | 
				
			||||||
			 GDK_DRAWABLE_XID (context->dest_window),
 | 
					 | 
				
			||||||
			 FALSE, &xev))
 | 
								 FALSE, &xev))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      GDK_NOTE (DND, 
 | 
					      GDK_NOTE (DND, 
 | 
				
			||||||
@ -2700,36 +2792,21 @@ xdnd_drop_filter (GdkXEvent *xev,
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
_gdk_dnd_init (GdkDisplay *display)
 | 
					_gdk_dnd_init (GdkDisplay *display)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  int i;
 | 
				
			||||||
  init_byte_order ();
 | 
					  init_byte_order ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gdk_display_add_client_message_filter (
 | 
					  gdk_display_add_client_message_filter (
 | 
				
			||||||
	display,
 | 
						display,
 | 
				
			||||||
	gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE),
 | 
						gdk_atom_intern ("_MOTIF_DRAG_AND_DROP_MESSAGE", FALSE),
 | 
				
			||||||
	motif_dnd_filter, NULL);
 | 
						motif_dnd_filter, NULL);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  for (i = 0; i < G_N_ELEMENTS (xdnd_filters); i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
      gdk_display_add_client_message_filter (
 | 
					      gdk_display_add_client_message_filter (
 | 
				
			||||||
	display,
 | 
						display,
 | 
				
			||||||
	gdk_atom_intern ("XdndEnter", FALSE),
 | 
						gdk_atom_intern (xdnd_filters[i].atom_name, FALSE),
 | 
				
			||||||
	xdnd_enter_filter, NULL);
 | 
						xdnd_filters[i].func, NULL);
 | 
				
			||||||
  gdk_display_add_client_message_filter (
 | 
					    }
 | 
				
			||||||
	display,				     
 | 
					 | 
				
			||||||
	gdk_atom_intern ("XdndLeave", FALSE),
 | 
					 | 
				
			||||||
	xdnd_leave_filter, NULL);
 | 
					 | 
				
			||||||
  gdk_display_add_client_message_filter (
 | 
					 | 
				
			||||||
	display,
 | 
					 | 
				
			||||||
	gdk_atom_intern ("XdndPosition", FALSE),
 | 
					 | 
				
			||||||
	xdnd_position_filter, NULL);
 | 
					 | 
				
			||||||
  gdk_display_add_client_message_filter (
 | 
					 | 
				
			||||||
	display,
 | 
					 | 
				
			||||||
	gdk_atom_intern ("XdndStatus", FALSE),
 | 
					 | 
				
			||||||
	xdnd_status_filter, NULL);
 | 
					 | 
				
			||||||
  gdk_display_add_client_message_filter (
 | 
					 | 
				
			||||||
	display,
 | 
					 | 
				
			||||||
	gdk_atom_intern ("XdndFinished", FALSE),
 | 
					 | 
				
			||||||
	xdnd_finished_filter, NULL);
 | 
					 | 
				
			||||||
  gdk_display_add_client_message_filter (
 | 
					 | 
				
			||||||
	display,				     
 | 
					 | 
				
			||||||
	gdk_atom_intern ("XdndDrop", FALSE),
 | 
					 | 
				
			||||||
	xdnd_drop_filter, NULL);
 | 
					 | 
				
			||||||
}		      
 | 
					}		      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Source side */
 | 
					/* Source side */
 | 
				
			||||||
@ -3321,8 +3398,7 @@ gdk_drag_status (GdkDragContext   *context,
 | 
				
			|||||||
      xev.xclient.data.l[3] = 0;
 | 
					      xev.xclient.data.l[3] = 0;
 | 
				
			||||||
      xev.xclient.data.l[4] = xdnd_action_to_atom (display, action);
 | 
					      xev.xclient.data.l[4] = xdnd_action_to_atom (display, action);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      if (!xdnd_send_xevent (display,
 | 
					      if (!xdnd_send_xevent (context, context->source_window,
 | 
				
			||||||
			     GDK_DRAWABLE_XID (context->source_window),
 | 
					 | 
				
			||||||
			     FALSE, &xev))
 | 
								     FALSE, &xev))
 | 
				
			||||||
	GDK_NOTE (DND, 
 | 
						GDK_NOTE (DND, 
 | 
				
			||||||
		  g_message ("Send event to %lx failed",
 | 
							  g_message ("Send event to %lx failed",
 | 
				
			||||||
@ -3421,8 +3497,7 @@ gdk_drop_finish (GdkDragContext   *context,
 | 
				
			|||||||
      xev.xclient.data.l[3] = 0;
 | 
					      xev.xclient.data.l[3] = 0;
 | 
				
			||||||
      xev.xclient.data.l[4] = 0;
 | 
					      xev.xclient.data.l[4] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (!xdnd_send_xevent (display,
 | 
					      if (!xdnd_send_xevent (context, context->source_window,
 | 
				
			||||||
			     GDK_DRAWABLE_XID (context->source_window),
 | 
					 | 
				
			||||||
			     FALSE, &xev))
 | 
								     FALSE, &xev))
 | 
				
			||||||
	GDK_NOTE (DND, 
 | 
						GDK_NOTE (DND, 
 | 
				
			||||||
		  g_message ("Send event to %lx failed",
 | 
							  g_message ("Send event to %lx failed",
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user