1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 #include "../config.h"
20 /* If you don't want to use gdk's signal handlers define this */
21 /* #define I_NEED_TO_ACTUALLY_DEBUG_MY_PROGRAMS 1 */
23 #include <X11/Xlocale.h>
34 #ifdef HAVE_SYS_SELECT_H
35 #include <sys/select.h>
36 #endif /* HAVE_SYS_SELECT_H_ */
38 #define XLIB_ILLEGAL_ACCESS
39 #include <X11/Xatom.h>
42 #include <X11/Xutil.h>
43 #include <X11/Xmu/WinUtil.h>
45 #include <X11/Xresource.h>
47 #include <X11/cursorfont.h>
49 #include "gdkprivate.h"
53 #include "gdkkeysyms.h"
57 #ifndef X_GETTIMEOFDAY
58 #define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL)
59 #endif /* X_GETTIMEOFDAY */
62 #define DOUBLE_CLICK_TIME 250
63 #define TRIPLE_CLICK_TIME 500
64 #define DOUBLE_CLICK_DIST 5
65 #define TRIPLE_CLICK_DIST 5
69 # define SELECT_MASK fd_set
75 # define SELECT_MASK void
77 # define SELECT_MASK int
82 typedef struct _GdkInput GdkInput;
83 typedef struct _GdkPredicate GdkPredicate;
89 GdkInputCondition condition;
90 GdkInputFunction function;
92 GdkDestroyNotify destroy;
102 * Private function declarations
105 static GdkEvent *gdk_event_new (void);
106 static gint gdk_event_wait (void);
107 static gint gdk_event_apply_filters (XEvent *xevent,
110 static gint gdk_event_translate (GdkEvent *event,
113 static Bool gdk_event_get_type (Display *display,
117 static void gdk_synthesize_click (GdkEvent *event,
120 static void gdk_dnd_drag_begin (GdkWindow *initial_window);
121 static void gdk_dnd_drag_enter (Window dest);
122 static void gdk_dnd_drag_leave (Window dest);
123 static void gdk_dnd_drag_end (Window dest,
125 static GdkAtom gdk_dnd_check_types (GdkWindow *window,
128 static void gdk_print_atom (GdkAtom anatom);
132 * old junk from offix, we might use it though so leave it
134 Window gdk_get_client_window (Display *dpy,
136 #ifdef WE_HAVE_MOTIF_DROPS_DONE
137 static GdkWindow * gdk_drop_get_real_window (GdkWindow *w,
141 static void gdk_exit_func (void);
142 static int gdk_x_error (Display *display,
144 static int gdk_x_io_error (Display *display);
145 static RETSIGTYPE gdk_signal (int signum);
149 static GdkIM gdk_im_get (void);
150 static gint gdk_im_open (XrmDatabase db,
153 static void gdk_im_close (void);
154 static void gdk_ic_cleanup (void);
157 /* Private variable declarations
159 static int initialized = 0; /* 1 if the library is initialized,
162 static int connection_number = 0; /* The file descriptor number of our
163 * connection to the X server. This
164 * is used so that we may determine
165 * when events are pending by using
166 * the "select" system call.
170 static struct timeval start; /* The time at which the library was
173 static struct timeval timer; /* Timeout interval to use in the call
174 * to "select". This is used in
175 * conjunction with "timerp" to create
176 * a maximum time to wait for an event
179 static struct timeval *timerp; /* The actual timer passed to "select"
180 * This may be NULL, in which case
181 * "select" will block until an event
184 static guint32 timer_val; /* The timeout length as specified by
185 * the user in milliseconds.
187 static GList *inputs; /* A list of the input file descriptors
188 * that we care about. Each list node
189 * contains a GdkInput struct that describes
190 * when we are interested in the specified
191 * file descriptor. That is, when it is
192 * available for read, write or has an
195 static guint32 button_click_time[2]; /* The last 2 button click times. Used
196 * to determine if the latest button click
197 * is part of a double or triple click.
199 static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses.
200 * Also used to determine if the latest button
201 * click is part of a double or triple click.
203 static guint button_number[2]; /* The last 2 buttons to be pressed.
205 static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds the
210 static gint xim_using; /* using XIM Protocol if TRUE */
211 static GdkIM xim_im; /* global IM */
212 static XIMStyles* xim_styles; /* im supports these styles */
213 static XIMStyle xim_best_allowed_style;
214 static GdkICPrivate *xim_ic; /* currently using IC */
215 static GdkWindow* xim_window; /* currently using Widow */
216 static GList* xim_ic_list;
220 #define OTHER_XEVENT_BUFSIZE 4
221 static XEvent other_xevent[OTHER_XEVENT_BUFSIZE]; /* XEvents passed along to user */
222 static int other_xevent_i = 0;
223 static GList *putback_events = NULL;
225 static gulong base_id;
226 static gint autorepeat;
228 #ifdef G_ENABLE_DEBUG
229 static GDebugKey gdk_debug_keys[] = {
230 {"events", GDK_DEBUG_EVENTS},
231 {"misc", GDK_DEBUG_MISC},
232 {"dnd", GDK_DEBUG_DND},
233 {"color-context", GDK_DEBUG_COLOR_CONTEXT},
234 {"xim", GDK_DEBUG_XIM}
237 static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey);
239 #endif /* G_ENABLE_DEBUG */
242 *--------------------------------------------------------------
245 * Initialize the library for use.
248 * "argc" is the number of arguments.
249 * "argv" is an array of strings.
252 * "argc" and "argv" are modified to reflect any arguments
253 * which were not handled. (Such arguments should either
254 * be handled by the application or dismissed).
257 * The library is initialized.
259 *--------------------------------------------------------------
266 XKeyboardState keyboard_state;
269 XClassHint *class_hint;
270 gint argc_orig = *argc;
273 argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*));
274 for (i = 0; i < argc_orig; i++)
275 argv_orig[i] = g_strdup ((*argv)[i]);
276 argv_orig[argc_orig] = NULL;
278 X_GETTIMEOFDAY (&start);
280 #ifndef I_NEED_TO_ACTUALLY_DEBUG_MY_PROGRAMS
281 signal (SIGHUP, gdk_signal);
282 signal (SIGINT, gdk_signal);
283 signal (SIGQUIT, gdk_signal);
284 signal (SIGBUS, gdk_signal);
285 signal (SIGSEGV, gdk_signal);
286 signal (SIGPIPE, gdk_signal);
287 signal (SIGTERM, gdk_signal);
290 gdk_display_name = NULL;
292 XSetErrorHandler (gdk_x_error);
293 XSetIOErrorHandler (gdk_x_io_error);
297 #ifdef G_ENABLE_DEBUG
299 gchar *debug_string = getenv("GDK_DEBUG");
300 if (debug_string != NULL)
301 gdk_debug_flags = g_parse_debug_string (debug_string,
305 #endif /* G_ENABLE_DEBUG */
310 gdk_progname = (*argv)[0];
312 for (i = 1; i < *argc;)
314 if ((*argv)[i] == NULL)
320 #ifdef G_ENABLE_DEBUG
321 if (strcmp ("--gdk-debug", (*argv)[i]) == 0)
325 if ((i + 1) < *argc && (*argv)[i + 1])
327 gdk_debug_flags |= g_parse_debug_string ((*argv)[i+1],
330 (*argv)[i + 1] = NULL;
334 else if (strcmp ("--gdk-no-debug", (*argv)[i]) == 0)
338 if ((i + 1) < *argc && (*argv)[i + 1])
340 gdk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1],
343 (*argv)[i + 1] = NULL;
347 #endif /* G_ENABLE_DEBUG */
348 else if (strcmp ("--display", (*argv)[i]) == 0)
352 if ((i + 1) < *argc && (*argv)[i + 1])
354 gdk_display_name = g_strdup ((*argv)[i + 1]);
355 (*argv)[i + 1] = NULL;
359 else if (strcmp ("--sync", (*argv)[i]) == 0)
364 else if (strcmp ("--no-xshm", (*argv)[i]) == 0)
367 gdk_use_xshm = FALSE;
369 else if (strcmp ("--name", (*argv)[i]) == 0)
371 if ((i + 1) < *argc && (*argv)[i + 1])
374 gdk_progname = (*argv)[i];
378 else if (strcmp ("--class", (*argv)[i]) == 0)
380 if ((i + 1) < *argc && (*argv)[i + 1])
383 gdk_progclass = (*argv)[i];
388 else if (strcmp ("--gxid_host", (*argv)[i]) == 0)
390 if ((i + 1) < *argc && (*argv)[i + 1])
393 gdk_input_gxid_host = ((*argv)[i]);
397 else if (strcmp ("--gxid_port", (*argv)[i]) == 0)
399 if ((i + 1) < *argc && (*argv)[i + 1])
402 gdk_input_gxid_port = atoi ((*argv)[i]);
408 else if (strcmp ("--xim-preedit", (*argv)[i]) == 0)
410 if ((i + 1) < *argc && (*argv)[i + 1])
413 if (strcmp ("none", (*argv)[i]) == 0)
414 gdk_im_set_best_style (GdkIMPreeditNone);
415 else if (strcmp ("nothing", (*argv)[i]) == 0)
416 gdk_im_set_best_style (GdkIMPreeditNothing);
417 else if (strcmp ("area", (*argv)[i]) == 0)
418 gdk_im_set_best_style (GdkIMPreeditArea);
419 else if (strcmp ("position", (*argv)[i]) == 0)
420 gdk_im_set_best_style (GdkIMPreeditPosition);
421 else if (strcmp ("callbacks", (*argv)[i]) == 0)
422 gdk_im_set_best_style (GdkIMPreeditCallbacks);
425 else if (strcmp ("--xim-status", (*argv)[i]) == 0)
427 if ((i + 1) < *argc && (*argv)[i + 1])
430 if (strcmp ("none", (*argv)[i]) == 0)
431 gdk_im_set_best_style (GdkIMStatusNone);
432 else if (strcmp ("nothing", (*argv)[i]) == 0)
433 gdk_im_set_best_style (GdkIMStatusNothing);
434 else if (strcmp ("area", (*argv)[i]) == 0)
435 gdk_im_set_best_style (GdkIMStatusArea);
436 else if (strcmp ("callbacks", (*argv)[i]) == 0)
437 gdk_im_set_best_style (GdkIMStatusCallbacks);
445 for (i = 1; i < *argc; i++)
447 for (k = i; k < *argc; k++)
448 if ((*argv)[k] != NULL)
454 for (j = i + k; j < *argc; j++)
455 (*argv)[j-k] = (*argv)[j];
462 gdk_progname = "<unknown>";
465 gdk_display = XOpenDisplay (gdk_display_name);
468 g_warning ("cannot open display: %s", XDisplayName (gdk_display_name));
472 /* This is really crappy. We have to look into the display structure
473 * to find the base resource id. This is only needed for recording
474 * and playback of events.
476 /* base_id = RESOURCE_BASE; */
478 GDK_NOTE (EVENTS, g_print ("base id: %lu\n", base_id));
480 connection_number = ConnectionNumber (gdk_display);
482 g_print ("connection number: %d\n", connection_number));
485 XSynchronize (gdk_display, True);
487 gdk_screen = DefaultScreen (gdk_display);
488 gdk_root_window = RootWindow (gdk_display, gdk_screen);
490 gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window,
491 10, 10, 10, 10, 0, 0 , 0);
492 class_hint = XAllocClassHint();
493 class_hint->res_name = gdk_progname;
494 if (gdk_progclass == NULL)
496 gdk_progclass = g_strdup (gdk_progname);
497 gdk_progclass[0] = toupper (gdk_progclass[0]);
499 class_hint->res_class = gdk_progclass;
500 XSetClassHint(gdk_display, gdk_leader_window, class_hint);
501 XSetCommand(gdk_display, gdk_leader_window, argv_orig, argc_orig);
504 for (i = 0; i < argc_orig; i++)
505 g_free(argv_orig[i]);
508 gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True);
509 gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True);
510 gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True);
511 gdk_wm_window_protocols[0] = gdk_wm_delete_window;
512 gdk_wm_window_protocols[1] = gdk_wm_take_focus;
513 gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False);
515 gdk_dnd.gdk_XdeEnter = gdk_atom_intern("_XDE_ENTER", FALSE);
516 gdk_dnd.gdk_XdeLeave = gdk_atom_intern("_XDE_LEAVE", FALSE);
517 gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE);
518 gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE);
519 gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE);
520 gdk_dnd.c->gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
521 gdk_dnd.c->gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
523 XGetKeyboardControl (gdk_display, &keyboard_state);
524 autorepeat = keyboard_state.global_auto_repeat;
530 button_click_time[0] = 0;
531 button_click_time[1] = 0;
532 button_window[0] = NULL;
533 button_window[1] = NULL;
534 button_number[0] = -1;
535 button_number[1] = -1;
537 if (ATEXIT (gdk_exit_func))
538 g_warning ("unable to register exit function");
546 /* initialize XIM Protocol variables */
550 if (!(xim_best_allowed_style & GdkIMPreeditMask))
551 gdk_im_set_best_style (GdkIMPreeditCallbacks);
552 if (!(xim_best_allowed_style & GdkIMStatusMask))
553 gdk_im_set_best_style (GdkIMStatusCallbacks);
555 xim_window = (GdkWindow*)NULL;
557 gdk_im_open (NULL, NULL, NULL);
564 *--------------------------------------------------------------
567 * Restores the library to an un-itialized state and exits
568 * the program using the "exit" system call.
571 * "errorcode" is the error value to pass to "exit".
574 * Allocated structures are freed and the program exits
579 *--------------------------------------------------------------
583 gdk_exit (int errorcode)
585 /* de-initialisation is done by the gdk_exit_funct(),
586 no need to do this here (Alex J.) */
591 *--------------------------------------------------------------
600 *--------------------------------------------------------------
606 if (!setlocale (LC_ALL,""))
607 g_print ("locale not supported by C library\n");
609 if (!XSupportsLocale ())
611 g_print ("locale not supported by Xlib, locale set to C\n");
612 setlocale (LC_ALL, "C");
615 if (!XSetLocaleModifiers (""))
617 g_print ("can not set locale modifiers\n");
620 return setlocale (LC_ALL,NULL);
624 *--------------------------------------------------------------
627 * Returns the number of events pending on the queue.
628 * These events have already been read from the server
634 * Returns the number of events on XLib's event queue.
638 *--------------------------------------------------------------
642 gdk_events_pending ()
647 result = XPending (gdk_display);
649 tmp_list = putback_events;
653 tmp_list = tmp_list->next;
660 *--------------------------------------------------------------
661 * gdk_event_get_graphics_expose
663 * Waits for a GraphicsExpose or NoExpose event
668 * For GraphicsExpose events, returns a pointer to the event
669 * converted into a GdkEvent Otherwise, returns NULL.
673 *-------------------------------------------------------------- */
676 graphics_expose_predicate (Display *display,
680 GdkWindowPrivate *private = (GdkWindowPrivate *)arg;
682 g_return_val_if_fail (private != NULL, False);
684 if ((xevent->xany.window == private->xwindow) &&
685 ((xevent->xany.type == GraphicsExpose) ||
686 (xevent->xany.type == NoExpose)))
693 gdk_event_get_graphics_expose (GdkWindow *window)
698 g_return_val_if_fail (window != NULL, NULL);
700 XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer)window);
702 if (xevent.xany.type == GraphicsExpose)
704 event = gdk_event_new ();
706 if (gdk_event_translate (event, &xevent))
709 gdk_event_free (event);
716 *--------------------------------------------------------------
719 * Gets the next event.
724 * If an event was received that we care about, returns
725 * a pointer to that event, to be freed with gdk_event_free.
726 * Otherwise, returns NULL. This function will also return
727 * before an event is received if the timeout interval
732 *--------------------------------------------------------------
745 temp_list = putback_events;
748 temp_event = temp_list->data;
750 if ((* pred) (temp_event, data))
753 *event = *temp_event;
754 putback_events = g_list_remove_link (putback_events, temp_list);
755 g_list_free (temp_list);
759 temp_list = temp_list->next;
762 event_pred.func = pred;
763 event_pred.data = data;
765 if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) & event_pred))
767 return gdk_event_translate (event, &xevent);
773 event = putback_events->data;
775 temp_list = putback_events;
776 putback_events = g_list_remove_link (putback_events, temp_list);
777 g_list_free_1 (temp_list);
782 /* Wait for an event to occur or the timeout to elapse.
783 * If an event occurs "gdk_event_wait" will return TRUE.
784 * If the timeout elapses "gdk_event_wait" will return
787 if (gdk_event_wait ())
789 /* If we get here we can rest assurred that an event
790 * has occurred. Read it.
794 if (xim_using && xim_window)
796 { /* don't dispatch events used by IM */
797 XNextEvent (gdk_display, &xevent);
798 filter_status = XFilterEvent (&xevent,
799 GDK_WINDOW_XWINDOW (xim_window));
800 } while (filter_status == True);
802 XNextEvent (gdk_display, &xevent);
804 XNextEvent (gdk_display, &xevent);
806 event = gdk_event_new ();
808 event->any.type = GDK_NOTHING;
809 event->any.window = NULL;
810 event->any.send_event = FALSE;
811 event->any.send_event = xevent.xany.send_event;
813 if (gdk_event_translate (event, &xevent))
816 gdk_event_free (event);
823 gdk_event_put (GdkEvent *event)
827 g_return_if_fail (event != NULL);
829 new_event = gdk_event_copy (event);
831 putback_events = g_list_prepend (putback_events, new_event);
835 *--------------------------------------------------------------
838 * Copy a event structure into new storage.
841 * "event" is the event struct to copy.
844 * A new event structure. Free it with gdk_event_free.
847 * The reference count of the window in the event is increased.
849 *--------------------------------------------------------------
852 static GMemChunk *event_chunk;
859 if (event_chunk == NULL)
860 event_chunk = g_mem_chunk_new ("events",
865 new_event = g_chunk_new (GdkEvent, event_chunk);
871 gdk_event_copy (GdkEvent *event)
875 g_return_val_if_fail (event != NULL, NULL);
877 new_event = gdk_event_new ();
880 gdk_window_ref (new_event->any.window);
882 switch (event->any.type)
885 case GDK_KEY_RELEASE:
886 new_event->key.string = g_strdup (event->key.string);
889 case GDK_ENTER_NOTIFY:
890 case GDK_LEAVE_NOTIFY:
891 if (event->crossing.subwindow != NULL)
892 gdk_window_ref (event->crossing.subwindow);
895 case GDK_DROP_DATA_AVAIL:
896 new_event->dropdataavailable.data_type = g_strdup (event->dropdataavailable.data_type);
897 new_event->dropdataavailable.data = g_malloc (event->dropdataavailable.data_numbytes);
898 memcpy (new_event->dropdataavailable.data,
899 event->dropdataavailable.data,
900 event->dropdataavailable.data_numbytes);
911 *--------------------------------------------------------------
914 * Free a event structure obtained from gdk_event_copy. Do not use
915 * with other event structures.
918 * "event" is the event struct to free.
923 * The reference count of the window in the event is decreased and
924 * might be freed, too.
926 *-------------------------------------------------------------- */
929 gdk_event_free (GdkEvent *event)
931 g_assert (event_chunk != NULL);
932 g_return_if_fail (event != NULL);
934 if (event->any.window)
935 gdk_window_unref (event->any.window);
937 switch (event->any.type)
940 case GDK_KEY_RELEASE:
941 g_free (event->key.string);
944 case GDK_ENTER_NOTIFY:
945 case GDK_LEAVE_NOTIFY:
946 if (event->crossing.subwindow != NULL)
947 gdk_window_unref (event->crossing.subwindow);
950 case GDK_DROP_DATA_AVAIL:
951 g_free (event->dropdataavailable.data_type);
952 g_free (event->dropdataavailable.data);
955 case GDK_DRAG_REQUEST:
956 g_free (event->dragrequest.data_type);
963 g_mem_chunk_free (event_chunk, event);
967 *--------------------------------------------------------------
968 * gdk_set_show_events
970 * Turns on/off the showing of events.
973 * "show_events" is a boolean describing whether or
974 * not to show the events gdk receives.
979 * When "show_events" is TRUE, calls to "gdk_event_get"
980 * will output debugging informatin regarding the event
981 * received to stdout.
983 *--------------------------------------------------------------
987 gdk_set_show_events (int show_events)
990 gdk_debug_flags |= GDK_DEBUG_EVENTS;
992 gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
996 gdk_set_use_xshm (gint use_xshm)
998 gdk_use_xshm = use_xshm;
1002 gdk_get_show_events ()
1004 return gdk_debug_flags & GDK_DEBUG_EVENTS;
1010 return gdk_use_xshm;
1014 *--------------------------------------------------------------
1017 * Get the number of milliseconds since the library was
1023 * The time since the library was initialized is returned.
1024 * This time value is accurate to milliseconds even though
1025 * a more accurate time down to the microsecond could be
1030 *--------------------------------------------------------------
1037 struct timeval elapsed;
1038 guint32 milliseconds;
1040 X_GETTIMEOFDAY (&end);
1042 if (start.tv_usec > end.tv_usec)
1044 end.tv_usec += 1000000;
1047 elapsed.tv_sec = end.tv_sec - start.tv_sec;
1048 elapsed.tv_usec = end.tv_usec - start.tv_usec;
1050 milliseconds = (elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000);
1052 return milliseconds;
1056 *--------------------------------------------------------------
1059 * Returns the current timer.
1064 * Returns the current timer interval. This interval is
1065 * in units of milliseconds.
1069 *--------------------------------------------------------------
1079 *--------------------------------------------------------------
1082 * Sets the timer interval.
1085 * "milliseconds" is the new value for the timer.
1090 * Calls to "gdk_event_get" will last for a maximum
1091 * of time of "milliseconds". However, a value of 0
1092 * milliseconds will cause "gdk_event_get" to block
1093 * indefinately until an event is received.
1095 *--------------------------------------------------------------
1099 gdk_timer_set (guint32 milliseconds)
1101 timer_val = milliseconds;
1102 timer.tv_sec = milliseconds / 1000;
1103 timer.tv_usec = (milliseconds % 1000) * 1000;
1114 gdk_timer_disable ()
1120 gdk_input_add_full (gint source,
1121 GdkInputCondition condition,
1122 GdkInputFunction function,
1124 GdkDestroyNotify destroy)
1126 static gint next_tag = 1;
1139 if ((input->source == source) && (input->condition == condition))
1142 (input->destroy) (input->data);
1143 input->function = function;
1145 input->destroy = destroy;
1152 input = g_new (GdkInput, 1);
1153 input->tag = next_tag++;
1154 input->source = source;
1155 input->condition = condition;
1156 input->function = function;
1158 input->destroy = destroy;
1161 inputs = g_list_prepend (inputs, input);
1168 gdk_input_add (gint source,
1169 GdkInputCondition condition,
1170 GdkInputFunction function,
1173 return gdk_input_add_interp (source, condition, function, data, NULL);
1177 gdk_input_remove (gint tag)
1188 if (input->tag == tag)
1191 (input->destroy) (input->data);
1196 list->next->prev = list->prev;
1198 list->prev->next = list->next;
1200 inputs = list->next;
1202 temp_list->next = NULL;
1203 temp_list->prev = NULL;
1205 g_free (temp_list->data);
1206 g_list_free (temp_list);
1215 *--------------------------------------------------------------
1218 * Grabs the pointer to a specific window
1221 * "window" is the window which will receive the grab
1222 * "owner_events" specifies whether events will be reported as is,
1223 * or relative to "window"
1224 * "event_mask" masks only interesting events
1225 * "confine_to" limits the cursor movement to the specified window
1226 * "cursor" changes the cursor for the duration of the grab
1227 * "time" specifies the time
1232 * requires a corresponding call to gdk_pointer_ungrab
1234 *--------------------------------------------------------------
1238 gdk_pointer_grab (GdkWindow * window,
1240 GdkEventMask event_mask,
1241 GdkWindow * confine_to,
1245 /* From gdkwindow.c */
1246 extern int nevent_masks;
1247 extern int event_mask_table[];
1250 GdkWindowPrivate *window_private;
1251 GdkWindowPrivate *confine_to_private;
1252 GdkCursorPrivate *cursor_private;
1259 g_return_val_if_fail (window != NULL, 0);
1261 window_private = (GdkWindowPrivate*) window;
1262 confine_to_private = (GdkWindowPrivate*) confine_to;
1263 cursor_private = (GdkCursorPrivate*) cursor;
1265 xwindow = window_private->xwindow;
1267 if (!confine_to || confine_to_private->destroyed)
1270 xconfine_to = confine_to_private->xwindow;
1275 xcursor = cursor_private->xcursor;
1279 for (i = 0; i < nevent_masks; i++)
1281 if (event_mask & (1 << (i + 1)))
1282 xevent_mask |= event_mask_table[i];
1285 if (((GdkWindowPrivate *)window)->extension_events &&
1286 gdk_input_vtable.grab_pointer)
1287 return_val = gdk_input_vtable.grab_pointer (window,
1293 return_val = Success;
1295 if (return_val == Success)
1297 if (!window_private->destroyed)
1298 return_val = XGrabPointer (window_private->xdisplay,
1302 GrabModeAsync, GrabModeAsync,
1307 return_val = AlreadyGrabbed;
1310 if (return_val == GrabSuccess)
1311 xgrab_window = window_private;
1317 *--------------------------------------------------------------
1318 * gdk_pointer_ungrab
1320 * Releases any pointer grab
1328 *--------------------------------------------------------------
1332 gdk_pointer_ungrab (guint32 time)
1334 if (gdk_input_vtable.ungrab_pointer)
1335 gdk_input_vtable.ungrab_pointer (time);
1337 XUngrabPointer (gdk_display, time);
1338 xgrab_window = NULL;
1342 *--------------------------------------------------------------
1343 * gdk_pointer_is_grabbed
1345 * Tell wether there is an active x pointer grab in effect
1353 *--------------------------------------------------------------
1357 gdk_pointer_is_grabbed (void)
1359 return xgrab_window != NULL;
1363 *--------------------------------------------------------------
1366 * Grabs the keyboard to a specific window
1369 * "window" is the window which will receive the grab
1370 * "owner_events" specifies whether events will be reported as is,
1371 * or relative to "window"
1372 * "time" specifies the time
1377 * requires a corresponding call to gdk_keyboard_ungrab
1379 *--------------------------------------------------------------
1383 gdk_keyboard_grab (GdkWindow * window,
1387 GdkWindowPrivate *window_private;
1390 g_return_val_if_fail (window != NULL, 0);
1392 window_private = (GdkWindowPrivate*) window;
1393 xwindow = window_private->xwindow;
1395 if (!window_private->destroyed)
1396 return XGrabKeyboard (window_private->xdisplay,
1399 GrabModeAsync, GrabModeAsync,
1402 return AlreadyGrabbed;
1406 *--------------------------------------------------------------
1407 * gdk_keyboard_ungrab
1409 * Releases any keyboard grab
1417 *--------------------------------------------------------------
1421 gdk_keyboard_ungrab (guint32 time)
1423 XUngrabKeyboard (gdk_display, time);
1427 *--------------------------------------------------------------
1430 * Return the width of the screen.
1438 *--------------------------------------------------------------
1446 return_val = DisplayWidth (gdk_display, gdk_screen);
1452 *--------------------------------------------------------------
1455 * Return the height of the screen.
1463 *--------------------------------------------------------------
1467 gdk_screen_height ()
1471 return_val = DisplayHeight (gdk_display, gdk_screen);
1477 gdk_key_repeat_disable ()
1479 XAutoRepeatOff (gdk_display);
1483 gdk_key_repeat_restore ()
1486 XAutoRepeatOn (gdk_display);
1488 XAutoRepeatOff (gdk_display);
1493 *--------------------------------------------------------------
1496 * Flushes the Xlib output buffer and then waits
1497 * until all requests have been received and processed
1498 * by the X server. The only real use for this function
1499 * is in dealing with XShm.
1507 *--------------------------------------------------------------
1512 XSync (gdk_display, False);
1519 XBell(gdk_display, 100);
1524 *--------------------------------------------------------------
1527 * Waits until an event occurs or the timer runs out.
1532 * Returns TRUE if an event is ready to be read and FALSE
1533 * if the timer ran out.
1537 *--------------------------------------------------------------
1545 GdkInputCondition condition;
1546 SELECT_MASK readfds;
1547 SELECT_MASK writefds;
1548 SELECT_MASK exceptfds;
1552 /* If there are no events pending we will wait for an event.
1553 * The time we wait is dependant on the "timer". If no timer
1554 * has been specified then we'll block until an event arrives.
1555 * If a timer has been specified we'll block until an event
1556 * arrives or the timer expires. (This is all done using the
1557 * "select" system call).
1560 if (XPending (gdk_display) == 0)
1563 FD_ZERO (&writefds);
1564 FD_ZERO (&exceptfds);
1566 FD_SET (connection_number, &readfds);
1567 max_input = connection_number;
1575 if (input->condition & GDK_INPUT_READ)
1576 FD_SET (input->source, &readfds);
1577 if (input->condition & GDK_INPUT_WRITE)
1578 FD_SET (input->source, &writefds);
1579 if (input->condition & GDK_INPUT_EXCEPTION)
1580 FD_SET (input->source, &exceptfds);
1582 max_input = MAX (max_input, input->source);
1585 nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp);
1592 if (FD_ISSET (connection_number, &readfds))
1594 if (XPending (gdk_display) == 0)
1598 XNoOp (gdk_display);
1599 XFlush (gdk_display);
1614 if (FD_ISSET (input->source, &readfds))
1615 condition |= GDK_INPUT_READ;
1616 if (FD_ISSET (input->source, &writefds))
1617 condition |= GDK_INPUT_WRITE;
1618 if (FD_ISSET (input->source, &exceptfds))
1619 condition |= GDK_INPUT_EXCEPTION;
1621 if (condition && input->function)
1622 (* input->function) (input->data, input->source, condition);
1633 gdk_event_apply_filters (XEvent *xevent,
1637 GdkEventFilter *filter;
1639 GdkFilterReturn result;
1645 filter = (GdkEventFilter *)tmp_list->data;
1647 result = (*filter->function)(xevent, event, filter->data);
1648 if (result != GDK_FILTER_CONTINUE)
1651 tmp_list = tmp_list->next;
1654 return GDK_FILTER_CONTINUE;
1658 gdk_event_translate (GdkEvent *event,
1663 GdkWindowPrivate *window_private;
1664 XComposeStatus compose;
1667 static gchar* buf = NULL;
1668 static gint buf_len= 0;
1674 /* Are static variables used for this purpose thread-safe? */
1678 /* Find the GdkWindow that this event occurred in.
1679 * All events occur in some GdkWindow (otherwise, why
1680 * would we be receiving them). It really is an error
1681 * to receive an event for which we cannot find the
1682 * corresponding GdkWindow. We handle events with window=None
1683 * specially - they are generated by XFree86's XInput under
1684 * some circumstances.
1687 if ((xevent->xany.window == None) &&
1688 gdk_input_vtable.window_none_event)
1690 return_val = gdk_input_vtable.window_none_event (event,xevent);
1692 if (return_val >= 0) /* was handled */
1698 window = gdk_window_lookup (xevent->xany.window);
1699 window_private = (GdkWindowPrivate *) window;
1702 gdk_window_ref (window);
1703 else if(gdk_null_window_warnings) /* Special purpose programs that
1704 get events for other windows may
1705 want to disable this */
1706 g_warning ("%#lx -> NULL\n", xevent->xany.window);
1708 /* Check for filters for this window */
1711 GdkFilterReturn result;
1712 result = gdk_event_apply_filters (xevent, event,
1714 ?window_private->filters
1715 :gdk_default_filters);
1717 if (result != GDK_FILTER_CONTINUE)
1719 return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1723 /* We do a "manual" conversion of the XEvent to a
1724 * GdkEvent. The structures are mostly the same so
1725 * the conversion is fairly straightforward. We also
1726 * optionally print debugging info regarding events
1730 * During drag & drop you get events where the pointer is
1731 * in other windows. Need to just do finer-grained checking
1733 switch (xevent->type)
1736 /* Lookup the string corresponding to the given keysym.
1742 buf = g_new (gchar, buf_len);
1744 if (xim_using == TRUE && xim_ic)
1748 /* Clear keyval. Depending on status, may not be set */
1749 event->key.keyval = GDK_VoidSymbol;
1750 charcount = XmbLookupString(xim_ic->xic,
1751 &xevent->xkey, buf, buf_len-1,
1752 (KeySym*) &event->key.keyval,
1754 if (status == XBufferOverflow)
1756 /* alloc adequate size of buffer */
1758 g_print("XIM: overflow (required %i)\n", charcount));
1760 while (buf_len <= charcount)
1762 buf = (gchar *) g_realloc (buf, buf_len);
1764 charcount = XmbLookupString (xim_ic->xic,
1765 &xevent->xkey, buf, buf_len-1,
1766 (KeySym*) &event->key.keyval,
1769 if (status == XLookupNone)
1776 charcount = XLookupString (&xevent->xkey, buf, buf_len,
1777 (KeySym*) &event->key.keyval,
1780 charcount = XLookupString (&xevent->xkey, buf, 16,
1781 (KeySym*) &event->key.keyval,
1784 if (charcount > 0 && buf[charcount-1] == '\0')
1787 buf[charcount] = '\0';
1789 /* Print debugging info.
1791 #ifdef G_ENABLE_DEBUG
1792 if (gdk_debug_flags & GDK_DEBUG_EVENTS)
1794 g_print ("key press:\twindow: %ld key: %12s %d\n",
1795 xevent->xkey.window - base_id,
1796 event->key.keyval ? XKeysymToString (event->key.keyval) : "(none)",
1799 g_print ("\t\tlength: %4d string: \"%s\"\n",
1802 #endif /* G_ENABLE_DEBUG */
1804 event->key.type = GDK_KEY_PRESS;
1805 event->key.window = window;
1806 event->key.time = xevent->xkey.time;
1807 event->key.state = (GdkModifierType) xevent->xkey.state;
1808 event->key.string = g_strdup (buf);
1809 event->key.length = charcount;
1811 return_val = window_private && !window_private->destroyed;
1814 g_free (event->key.string);
1819 /* Lookup the string corresponding to the given keysym.
1821 charcount = XLookupString (&xevent->xkey, buf, 16,
1822 (KeySym*) &event->key.keyval,
1825 /* Print debugging info.
1828 g_print ("key release:\t\twindow: %ld key: %12s %d\n",
1829 xevent->xkey.window - base_id,
1830 XKeysymToString (event->key.keyval),
1831 event->key.keyval));
1833 event->key.type = GDK_KEY_RELEASE;
1834 event->key.window = window;
1835 event->key.time = xevent->xkey.time;
1836 event->key.state = (GdkModifierType) xevent->xkey.state;
1837 event->key.length = 0;
1838 event->key.string = NULL;
1840 return_val = window_private && !window_private->destroyed;
1844 /* Print debugging info.
1847 g_print ("button press[%d]:\t\twindow: %ld x,y: %d %d button: %d\n",
1848 window_private?window_private->dnd_drag_enabled:0,
1849 xevent->xbutton.window - base_id,
1850 xevent->xbutton.x, xevent->xbutton.y,
1851 xevent->xbutton.button));
1853 if (window_private &&
1854 (window_private->extension_events != 0) &&
1855 gdk_input_ignore_core)
1858 event->button.type = GDK_BUTTON_PRESS;
1859 event->button.window = window;
1860 event->button.time = xevent->xbutton.time;
1861 event->button.x = xevent->xbutton.x;
1862 event->button.y = xevent->xbutton.y;
1863 event->button.x_root = (gfloat)xevent->xbutton.x_root;
1864 event->button.y_root = (gfloat)xevent->xbutton.y_root;
1865 event->button.pressure = 0.5;
1866 event->button.xtilt = 0;
1867 event->button.ytilt = 0;
1868 event->button.state = (GdkModifierType) xevent->xbutton.state;
1869 event->button.button = xevent->xbutton.button;
1870 event->button.source = GDK_SOURCE_MOUSE;
1871 event->button.deviceid = GDK_CORE_POINTER;
1873 if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
1874 (event->button.window == button_window[1]) &&
1875 (event->button.button == button_number[1]))
1877 gdk_synthesize_click (event, 3);
1879 button_click_time[1] = 0;
1880 button_click_time[0] = 0;
1881 button_window[1] = NULL;
1882 button_window[0] = 0;
1883 button_number[1] = -1;
1884 button_number[0] = -1;
1886 else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
1887 (event->button.window == button_window[0]) &&
1888 (event->button.button == button_number[0]))
1890 gdk_synthesize_click (event, 2);
1892 button_click_time[1] = button_click_time[0];
1893 button_click_time[0] = event->button.time;
1894 button_window[1] = button_window[0];
1895 button_window[0] = event->button.window;
1896 button_number[1] = button_number[0];
1897 button_number[0] = event->button.button;
1901 button_click_time[1] = 0;
1902 button_click_time[0] = event->button.time;
1903 button_window[1] = NULL;
1904 button_window[0] = event->button.window;
1905 button_number[1] = -1;
1906 button_number[0] = event->button.button;
1909 && window_private->dnd_drag_enabled
1910 && !gdk_dnd.drag_perhaps
1911 && event->button.button == 1
1912 && !gdk_dnd.drag_really)
1914 gdk_dnd.drag_perhaps = 1;
1915 gdk_dnd.dnd_drag_start.x = xevent->xbutton.x_root;
1916 gdk_dnd.dnd_drag_start.y = xevent->xbutton.y_root;
1917 gdk_dnd.real_sw = window_private;
1919 if(gdk_dnd.drag_startwindows)
1921 g_free(gdk_dnd.drag_startwindows);
1922 gdk_dnd.drag_startwindows = NULL;
1924 gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
1925 gdk_dnd.dnd_grabbed = FALSE;
1928 /* Set motion mask for first DnD'd window, since it
1929 will be the one that is actually dragged */
1930 XWindowAttributes dnd_winattr;
1931 XSetWindowAttributes dnd_setwinattr;
1933 /* We need to get motion events while the button is down, so
1934 we can know whether to really start dragging or not... */
1935 XGetWindowAttributes(gdk_display, (Window)window_private->xwindow,
1938 window_private->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
1939 dnd_setwinattr.event_mask =
1940 window_private->dnd_drag_eventmask = ButtonMotionMask |
1941 EnterWindowMask | LeaveWindowMask;
1942 XChangeWindowAttributes(gdk_display, window_private->xwindow,
1943 CWEventMask, &dnd_setwinattr);
1946 return_val = window_private && !window_private->destroyed;
1950 /* Print debugging info.
1953 g_print ("button release[%d]:\twindow: %ld x,y: %d %d button: %d\n",
1954 window_private?window_private->dnd_drag_enabled:0,
1955 xevent->xbutton.window - base_id,
1956 xevent->xbutton.x, xevent->xbutton.y,
1957 xevent->xbutton.button));
1959 if (window_private &&
1960 (window_private->extension_events != 0) &&
1961 gdk_input_ignore_core)
1964 event->button.type = GDK_BUTTON_RELEASE;
1965 event->button.window = window;
1966 event->button.time = xevent->xbutton.time;
1967 event->button.x = xevent->xbutton.x;
1968 event->button.y = xevent->xbutton.y;
1969 event->button.x_root = (gfloat)xevent->xbutton.x_root;
1970 event->button.y_root = (gfloat)xevent->xbutton.y_root;
1971 event->button.pressure = 0.5;
1972 event->button.xtilt = 0;
1973 event->button.ytilt = 0;
1974 event->button.state = (GdkModifierType) xevent->xbutton.state;
1975 event->button.button = xevent->xbutton.button;
1976 event->button.source = GDK_SOURCE_MOUSE;
1977 event->button.deviceid = GDK_CORE_POINTER;
1979 gdk_dnd.last_drop_time = xevent->xbutton.time;
1980 if(gdk_dnd.drag_perhaps)
1983 XSetWindowAttributes attrs;
1984 /* Reset event mask to pre-drag value, assuming event_mask
1985 doesn't change during drag */
1986 attrs.event_mask = gdk_dnd.real_sw->dnd_drag_savedeventmask;
1987 XChangeWindowAttributes(gdk_display, gdk_dnd.real_sw->xwindow,
1988 CWEventMask, &attrs);
1991 if (gdk_dnd.dnd_grabbed)
1993 gdk_dnd_display_drag_cursor(-2,
1996 XUngrabPointer(gdk_display, CurrentTime);
1997 gdk_dnd.dnd_grabbed = FALSE;
2000 if(gdk_dnd.drag_really)
2003 foo.x = xevent->xbutton.x_root;
2004 foo.y = xevent->xbutton.y_root;
2006 if(gdk_dnd.dnd_drag_target != None)
2007 gdk_dnd_drag_end(gdk_dnd.dnd_drag_target, foo);
2008 gdk_dnd.drag_really = 0;
2010 gdk_dnd.drag_numwindows = 0;
2011 if(gdk_dnd.drag_startwindows)
2013 g_free(gdk_dnd.drag_startwindows);
2014 gdk_dnd.drag_startwindows = NULL;
2017 gdk_dnd.real_sw = NULL;
2020 gdk_dnd.drag_perhaps = 0;
2021 gdk_dnd.dnd_drag_start.x = gdk_dnd.dnd_drag_start.y = 0;
2022 gdk_dnd.dnd_drag_dropzone.x = gdk_dnd.dnd_drag_dropzone.y = 0;
2023 gdk_dnd.dnd_drag_dropzone.width = gdk_dnd.dnd_drag_dropzone.height = 0;
2024 gdk_dnd.dnd_drag_curwin = None;
2025 return_val = window_private?TRUE:FALSE;
2027 return_val = window_private && !window_private->destroyed;
2031 /* Print debugging info.
2034 g_print ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s d:%d r%d\n",
2035 xevent->xmotion.window - base_id,
2036 xevent->xmotion.x, xevent->xmotion.y,
2037 (xevent->xmotion.is_hint) ? "true" : "false",
2038 gdk_dnd.drag_perhaps, gdk_dnd.drag_really));
2040 if (window_private &&
2041 (window_private->extension_events != 0) &&
2042 gdk_input_ignore_core)
2045 event->motion.type = GDK_MOTION_NOTIFY;
2046 event->motion.window = window;
2047 event->motion.time = xevent->xmotion.time;
2048 event->motion.x = xevent->xmotion.x;
2049 event->motion.y = xevent->xmotion.y;
2050 event->motion.x_root = (gfloat)xevent->xmotion.x_root;
2051 event->motion.y_root = (gfloat)xevent->xmotion.y_root;
2052 event->motion.pressure = 0.5;
2053 event->motion.xtilt = 0;
2054 event->motion.ytilt = 0;
2055 event->motion.state = (GdkModifierType) xevent->xmotion.state;
2056 event->motion.is_hint = xevent->xmotion.is_hint;
2057 event->motion.source = GDK_SOURCE_MOUSE;
2058 event->motion.deviceid = GDK_CORE_POINTER;
2060 #define IS_IN_ZONE(cx, cy) (cx >= gdk_dnd.dnd_drag_dropzone.x \
2061 && cy >= gdk_dnd.dnd_drag_dropzone.y \
2062 && cx < (gdk_dnd.dnd_drag_dropzone.x + gdk_dnd.dnd_drag_dropzone.width) \
2063 && cy < (gdk_dnd.dnd_drag_dropzone.y + gdk_dnd.dnd_drag_dropzone.height))
2065 if(gdk_dnd.drag_perhaps && gdk_dnd.drag_really
2066 /* && event->motion.is_hint */ /* HINTME */)
2068 /* First, we have to find what window the motion was in... */
2069 /* XXX there has to be a better way to do this, perhaps with
2070 XTranslateCoordinates or XQueryTree - I don't know how,
2071 and this sort of works */
2072 static Window lastwin = None, curwin = None;
2076 Window childwin = gdk_root_window;
2079 /* Interlude - display cursor for the drag ASAP */
2080 gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
2081 xevent->xmotion.y_root,
2082 gdk_dnd.dnd_drag_target?TRUE:FALSE,
2086 curwin = gdk_root_window;
2087 ox = x = xevent->xmotion.x_root;
2088 oy = y = xevent->xmotion.y_root;
2090 curwin = gdk_window_xid_at_coords(xevent->xmotion.x_root,
2091 xevent->xmotion.y_root,
2093 XTranslateCoordinates(gdk_display, gdk_root_window, curwin,
2094 x, y, &x, &y, &childwin);
2096 while(childwin != None)
2100 XTranslateCoordinates(gdk_display, curwin, curwin,
2101 x, y, &x, &y, &childwin);
2102 if(childwin != None)
2104 XTranslateCoordinates(gdk_display, curwin, childwin,
2105 x, y, &x, &y, &twin);
2110 g_print("Drag is now in window %#lx, lastwin was %#lx, ddc = %#lx\n",
2111 curwin, lastwin, gdk_dnd.dnd_drag_curwin));
2112 if(curwin != gdk_dnd.dnd_drag_curwin && curwin != lastwin)
2114 /* We have left one window and entered another
2115 (do leave & enter bits) */
2116 if(gdk_dnd.dnd_drag_curwin != None)
2117 gdk_dnd_drag_leave(gdk_dnd.dnd_drag_curwin);
2118 gdk_dnd.dnd_drag_curwin = curwin;
2119 gdk_dnd_drag_enter(gdk_dnd.dnd_drag_curwin);
2120 gdk_dnd.dnd_drag_dropzone.x = gdk_dnd.dnd_drag_dropzone.y = 0;
2121 gdk_dnd.dnd_drag_dropzone.width = gdk_dnd.dnd_drag_dropzone.height = 0;
2122 gdk_dnd.dnd_drag_target = None;
2124 g_print("curwin = %#lx, lastwin = %#lx, dnd_drag_curwin = %#lx\n",
2125 curwin, lastwin, gdk_dnd.dnd_drag_curwin));
2127 gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
2128 xevent->xmotion.y_root,
2131 else if(gdk_dnd.dnd_drag_dropzone.width > 0
2132 && gdk_dnd.dnd_drag_dropzone.height > 0
2133 && curwin == gdk_dnd.dnd_drag_curwin)
2135 /* Handle all that dropzone stuff - thanks John ;-) */
2136 if (gdk_dnd.dnd_drag_target != None)
2138 gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root,
2139 xevent->xmotion.y_root);
2140 gboolean old_in_zone = IS_IN_ZONE(gdk_dnd.dnd_drag_oldpos.x,
2141 gdk_dnd.dnd_drag_oldpos.y);
2143 if (!in_zone && old_in_zone)
2145 /* We were in the drop zone and moved out */
2146 gdk_dnd.dnd_drag_target = None;
2147 gdk_dnd_drag_leave(curwin);
2148 gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
2149 xevent->xmotion.y_root,
2152 else if (!in_zone && !old_in_zone)
2154 /* We were outside drop zone but in the window
2155 - have to send enter events */
2156 gdk_dnd_drag_enter(curwin);
2157 gdk_dnd.dnd_drag_curwin = curwin;
2158 gdk_dnd.dnd_drag_dropzone.x = gdk_dnd.dnd_drag_dropzone.y = 0;
2159 gdk_dnd.dnd_drag_target = None;
2163 dnd_drag_curwin = None; */
2167 return_val = window_private && !window_private->destroyed;
2171 /* Print debugging info.
2174 g_print ("enter notify:\t\twindow: %ld detail: %d subwin: %ld\n",
2175 xevent->xcrossing.window - base_id,
2176 xevent->xcrossing.detail,
2177 xevent->xcrossing.subwindow - base_id));
2179 /* Tell XInput stuff about it if appropriate */
2180 if (window_private &&
2181 (window_private->extension_events != 0) &&
2182 gdk_input_vtable.enter_event)
2183 gdk_input_vtable.enter_event (&xevent->xcrossing, window);
2185 event->crossing.type = GDK_ENTER_NOTIFY;
2186 event->crossing.window = window;
2188 /* If the subwindow field of the XEvent is non-NULL, then
2189 * lookup the corresponding GdkWindow.
2191 if (xevent->xcrossing.subwindow != None)
2192 event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow);
2194 event->crossing.subwindow = NULL;
2196 /* Translate the crossing detail into Gdk terms.
2198 switch (xevent->xcrossing.detail)
2200 case NotifyInferior:
2201 event->crossing.detail = GDK_NOTIFY_INFERIOR;
2203 case NotifyAncestor:
2204 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
2207 event->crossing.detail = GDK_NOTIFY_VIRTUAL;
2209 case NotifyNonlinear:
2210 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
2212 case NotifyNonlinearVirtual:
2213 event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
2216 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2220 #ifdef G_ENABLE_DEBUG
2221 if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps)
2223 g_print("We may[%d] have a drag into %#lx = %#lx\n",
2224 gdk_dnd.drag_really,
2225 xevent->xcrossing.window, gdk_dnd.real_sw->xwindow);
2227 #endif /* G_ENABLE_DEBUG */
2229 if (gdk_dnd.drag_perhaps && gdk_dnd.drag_really &&
2230 (xevent->xcrossing.window == gdk_dnd.real_sw->xwindow))
2232 gdk_dnd.drag_really = 0;
2234 GDK_NOTE (DND, g_print("Ungrabbed\n"));
2236 gdk_dnd.drag_numwindows = 0;
2237 g_free(gdk_dnd.drag_startwindows);
2238 gdk_dnd.drag_startwindows = NULL;
2239 /* We don't want to ungrab the pointer here, or we'll
2240 * start getting spurious enter/leave events */
2242 XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime);
2246 return_val = window_private && !window_private->destroyed;
2250 /* Print debugging info.
2253 g_print ("leave notify:\t\twindow: %ld detail: %d subwin: %ld\n",
2254 xevent->xcrossing.window - base_id,
2255 xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id));
2257 event->crossing.type = GDK_LEAVE_NOTIFY;
2258 event->crossing.window = window;
2260 /* If the subwindow field of the XEvent is non-NULL, then
2261 * lookup the corresponding GdkWindow.
2263 if (xevent->xcrossing.subwindow != None)
2264 event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow);
2266 event->crossing.subwindow = NULL;
2268 /* Translate the crossing detail into Gdk terms.
2270 switch (xevent->xcrossing.detail)
2272 case NotifyInferior:
2273 event->crossing.detail = GDK_NOTIFY_INFERIOR;
2275 case NotifyAncestor:
2276 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
2279 event->crossing.detail = GDK_NOTIFY_VIRTUAL;
2281 case NotifyNonlinear:
2282 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
2284 case NotifyNonlinearVirtual:
2285 event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
2288 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2291 #ifdef G_ENABLE_DEBUG
2292 if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps)
2294 g_print("We may[%d] have a drag out of %#lx = %#lx\n",
2295 gdk_dnd.drag_really,
2296 xevent->xcrossing.window, gdk_dnd.real_sw->xwindow);
2298 #endif /* G_ENABLE_DEBUG */
2299 if (gdk_dnd.drag_perhaps && !gdk_dnd.drag_really &&
2300 (xevent->xcrossing.window == gdk_dnd.real_sw->xwindow))
2303 gdk_dnd_drag_addwindow((GdkWindow *) gdk_dnd.real_sw);
2304 gdk_dnd_drag_begin((GdkWindow *) gdk_dnd.real_sw);
2306 XGrabPointer(gdk_display, gdk_dnd.real_sw->xwindow, False,
2307 ButtonMotionMask | PointerMotionMask |
2308 /* PointerMotionHintMask | */ /* HINTME */
2309 ButtonPressMask | ButtonReleaseMask,
2310 GrabModeAsync, GrabModeAsync, gdk_root_window,
2312 #ifdef G_ENABLE_DEBUG
2313 GDK_NOTE(DND, g_print("xgpret = %d\n", xgpret));
2315 gdk_dnd.dnd_grabbed = TRUE;
2316 gdk_dnd.drag_really = 1;
2317 gdk_dnd_display_drag_cursor(xevent->xmotion.x_root,
2318 xevent->xmotion.y_root,
2322 return_val = window_private && !window_private->destroyed;
2327 /* We only care about focus events that indicate that _this_
2328 * window (not a ancestor or child) got or lost the focus
2330 switch (xevent->xfocus.detail)
2332 case NotifyAncestor:
2333 case NotifyInferior:
2334 case NotifyNonlinear:
2335 /* Print debugging info.
2338 g_print ("focus %s:\t\twindow: %ld\n",
2339 (xevent->xany.type == FocusIn) ? "in" : "out",
2340 xevent->xfocus.window - base_id));
2342 event->focus_change.type = GDK_FOCUS_CHANGE;
2343 event->focus_change.window = window;
2344 event->focus_change.in = (xevent->xany.type == FocusIn);
2346 return_val = window_private && !window_private->destroyed;
2354 /* Print debugging info.
2357 g_print ("keymap notify\n"));
2359 /* Not currently handled */
2363 /* Print debugging info.
2366 g_print ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d\n",
2367 xevent->xexpose.window - base_id, xevent->xexpose.count,
2368 xevent->xexpose.x, xevent->xexpose.y,
2369 xevent->xexpose.width, xevent->xexpose.height));
2371 event->expose.type = GDK_EXPOSE;
2372 event->expose.window = window;
2373 event->expose.area.x = xevent->xexpose.x;
2374 event->expose.area.y = xevent->xexpose.y;
2375 event->expose.area.width = xevent->xexpose.width;
2376 event->expose.area.height = xevent->xexpose.height;
2377 event->expose.count = xevent->xexpose.count;
2379 return_val = window_private && !window_private->destroyed;
2382 case GraphicsExpose:
2383 /* Print debugging info.
2386 g_print ("graphics expose:\tdrawable: %ld\n",
2387 xevent->xgraphicsexpose.drawable - base_id));
2389 event->expose.type = GDK_EXPOSE;
2390 event->expose.window = window;
2391 event->expose.area.x = xevent->xgraphicsexpose.x;
2392 event->expose.area.y = xevent->xgraphicsexpose.y;
2393 event->expose.area.width = xevent->xgraphicsexpose.width;
2394 event->expose.area.height = xevent->xgraphicsexpose.height;
2395 event->expose.count = xevent->xexpose.count;
2397 return_val = window_private && !window_private->destroyed;
2401 /* Print debugging info.
2404 g_print ("no expose:\t\tdrawable: %ld\n",
2405 xevent->xnoexpose.drawable - base_id));
2407 event->no_expose.type = GDK_NO_EXPOSE;
2408 event->no_expose.window = window;
2410 return_val = window_private && !window_private->destroyed;
2413 case VisibilityNotify:
2414 /* Print debugging info.
2416 #ifdef G_ENABLE_DEBUG
2417 if (gdk_debug_flags & GDK_DEBUG_EVENTS)
2418 switch (xevent->xvisibility.state)
2420 case VisibilityFullyObscured:
2421 g_print ("visibility notify:\twindow: %ld none\n",
2422 xevent->xvisibility.window - base_id);
2424 case VisibilityPartiallyObscured:
2425 g_print ("visibility notify:\twindow: %ld partial\n",
2426 xevent->xvisibility.window - base_id);
2428 case VisibilityUnobscured:
2429 g_print ("visibility notify:\twindow: %ld full\n",
2430 xevent->xvisibility.window - base_id);
2433 #endif /* G_ENABLE_DEBUG */
2435 event->visibility.type = GDK_VISIBILITY_NOTIFY;
2436 event->visibility.window = window;
2438 switch (xevent->xvisibility.state)
2440 case VisibilityFullyObscured:
2441 event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED;
2444 case VisibilityPartiallyObscured:
2445 event->visibility.state = GDK_VISIBILITY_PARTIAL;
2448 case VisibilityUnobscured:
2449 event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
2453 return_val = window_private && !window_private->destroyed;
2457 /* Not currently handled */
2461 /* Print debugging info.
2464 g_print ("destroy notify:\twindow: %ld\n",
2465 xevent->xdestroywindow.window - base_id));
2467 event->any.type = GDK_DESTROY;
2468 event->any.window = window;
2470 return_val = window_private && !window_private->destroyed;
2472 gdk_window_destroy_notify (window);
2476 /* Print debugging info.
2479 g_print ("unmap notify:\t\twindow: %ld\n",
2480 xevent->xmap.window - base_id));
2482 event->any.type = GDK_UNMAP;
2483 event->any.window = window;
2485 if (xgrab_window == window_private)
2486 xgrab_window = NULL;
2488 return_val = window_private && !window_private->destroyed;
2492 /* Print debugging info.
2495 g_print ("map notify:\t\twindow: %ld\n",
2496 xevent->xmap.window - base_id));
2498 event->any.type = GDK_MAP;
2499 event->any.window = window;
2501 return_val = window_private && !window_private->destroyed;
2504 case ReparentNotify:
2505 /* Print debugging info.
2508 g_print ("reparent notify:\twindow: %ld\n",
2509 xevent->xreparent.window - base_id));
2511 /* Not currently handled */
2514 case ConfigureNotify:
2515 /* Print debugging info.
2517 while ((XPending (gdk_display) > 0) &&
2518 XCheckTypedWindowEvent(gdk_display, xevent->xany.window,
2519 ConfigureNotify, xevent))
2520 /*XSync (gdk_display, 0)*/;
2523 g_print ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d\n",
2524 xevent->xconfigure.window - base_id,
2525 xevent->xconfigure.x,
2526 xevent->xconfigure.y,
2527 xevent->xconfigure.width,
2528 xevent->xconfigure.height,
2529 xevent->xconfigure.border_width,
2530 xevent->xconfigure.above - base_id,
2531 xevent->xconfigure.override_redirect));
2535 if ((window_private->extension_events != 0) &&
2536 gdk_input_vtable.configure_event)
2537 gdk_input_vtable.configure_event (&xevent->xconfigure, window);
2539 if (window_private->window_type != GDK_WINDOW_CHILD)
2541 event->configure.type = GDK_CONFIGURE;
2542 event->configure.window = window;
2543 event->configure.width = xevent->xconfigure.width;
2544 event->configure.height = xevent->xconfigure.height;
2546 if (!xevent->xconfigure.x &&
2547 !xevent->xconfigure.y)
2551 Window child_window = 0;
2553 if (!XTranslateCoordinates (window_private->xdisplay,
2554 window_private->xwindow,
2559 g_warning ("GdkWindow %ld doesn't share root windows display?",
2560 window_private->xwindow - base_id);
2561 event->configure.x = tx;
2562 event->configure.y = ty;
2566 event->configure.x = xevent->xconfigure.x;
2567 event->configure.y = xevent->xconfigure.y;
2569 window_private->x = event->configure.x;
2570 window_private->y = event->configure.y;
2571 window_private->width = xevent->xconfigure.width;
2572 window_private->height = xevent->xconfigure.height;
2573 if (window_private->resize_count > 1)
2574 window_private->resize_count -= 1;
2576 return_val = !window_private->destroyed;
2581 case PropertyNotify:
2582 /* Print debugging info.
2585 g_print ("property notify:\twindow: %ld\n",
2586 xevent->xproperty.window - base_id));
2588 event->property.type = GDK_PROPERTY_NOTIFY;
2589 event->property.window = window;
2590 event->property.atom = xevent->xproperty.atom;
2591 event->property.time = xevent->xproperty.time;
2592 event->property.state = xevent->xproperty.state;
2594 return_val = window_private && !window_private->destroyed;
2597 case SelectionClear:
2599 g_print ("selection clear:\twindow: %ld\n",
2600 xevent->xproperty.window - base_id));
2602 event->selection.type = GDK_SELECTION_CLEAR;
2603 event->selection.window = window;
2604 event->selection.selection = xevent->xselectionclear.selection;
2605 event->selection.time = xevent->xselectionclear.time;
2607 return_val = window_private && !window_private->destroyed;
2610 case SelectionRequest:
2612 g_print ("selection request:\twindow: %ld\n",
2613 xevent->xproperty.window - base_id));
2615 event->selection.type = GDK_SELECTION_REQUEST;
2616 event->selection.window = window;
2617 event->selection.selection = xevent->xselectionrequest.selection;
2618 event->selection.target = xevent->xselectionrequest.target;
2619 event->selection.property = xevent->xselectionrequest.property;
2620 event->selection.requestor = xevent->xselectionrequest.requestor;
2621 event->selection.time = xevent->xselectionrequest.time;
2623 return_val = window_private && !window_private->destroyed;
2626 case SelectionNotify:
2628 g_print ("selection notify:\twindow: %ld\n",
2629 xevent->xproperty.window - base_id));
2632 event->selection.type = GDK_SELECTION_NOTIFY;
2633 event->selection.window = window;
2634 event->selection.selection = xevent->xselection.selection;
2635 event->selection.target = xevent->xselection.target;
2636 event->selection.property = xevent->xselection.property;
2637 event->selection.time = xevent->xselection.time;
2639 return_val = window_private && !window_private->destroyed;
2642 case ColormapNotify:
2643 /* Print debugging info.
2646 g_print ("colormap notify:\twindow: %ld\n",
2647 xevent->xcolormap.window - base_id));
2649 /* Not currently handled */
2653 /* Print debugging info.
2656 g_print ("client message:\twindow: %ld\n",
2657 xevent->xclient.window - base_id));
2659 /* Client messages are the means of the window manager
2660 * communicating with a program. We'll first check to
2661 * see if this is really the window manager talking
2664 if (xevent->xclient.message_type == gdk_wm_protocols)
2666 if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window)
2668 /* The delete window request specifies a window
2669 * to delete. We don't actually destroy the
2670 * window because "it is only a request". (The
2671 * window might contain vital data that the
2672 * program does not want destroyed). Instead
2673 * the event is passed along to the program,
2674 * which should then destroy the window.
2677 /* Print debugging info.
2680 g_print ("delete window:\t\twindow: %ld\n",
2681 xevent->xclient.window - base_id));
2683 event->any.type = GDK_DELETE;
2684 event->any.window = window;
2686 return_val = window_private && !window_private->destroyed;
2688 else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus)
2692 else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter)
2696 event->dropenter.u.allflags = xevent->xclient.data.l[1];
2698 GDK_NOTE (DND, g_print ("GDK_DROP_ENTER [%d][%d]\n",
2699 window_private->dnd_drop_enabled, event->dropenter.u.flags.sendreply));
2702 /* Now figure out if we really want this drop...
2703 * If someone is trying funky clipboard stuff, ignore
2706 && window_private->dnd_drop_enabled
2707 && event->dropenter.u.flags.sendreply
2708 && (reptype = gdk_dnd_check_types (window, xevent)))
2712 replyev.xclient.type = ClientMessage;
2713 replyev.xclient.window = xevent->xclient.data.l[0];
2714 replyev.xclient.format = 32;
2715 replyev.xclient.message_type = gdk_dnd.gdk_XdeRequest;
2716 replyev.xclient.data.l[0] = window_private->xwindow;
2718 event->dragrequest.u.allflags = 0;
2719 event->dragrequest.u.flags.protocol_version =
2720 DND_PROTOCOL_VERSION;
2721 event->dragrequest.u.flags.willaccept = 1;
2722 event->dragrequest.u.flags.delete_data =
2723 (window_private->dnd_drop_destructive_op) ? 1 : 0;
2725 replyev.xclient.data.l[1] = event->dragrequest.u.allflags;
2726 replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0;
2727 replyev.xclient.data.l[4] = reptype;
2729 if (!gdk_send_xevent (replyev.xclient.window, False,
2730 NoEventMask, &replyev))
2731 GDK_NOTE (DND, g_print("Sending XdeRequest to %#lx failed\n",
2732 replyev.xclient.window));
2734 event->any.type = GDK_DROP_ENTER;
2735 event->any.window = window;
2736 event->dropenter.requestor = replyev.xclient.window;
2737 event->dropenter.u.allflags = xevent->xclient.data.l[1];
2739 GDK_NOTE (DND, g_print("We sent a GDK_DROP_ENTER on to Gtk\n"));
2743 else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeLeave)
2745 #ifdef G_ENABLE_DEBUG
2746 if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND))
2747 g_print ("GDK_DROP_LEAVE\n");
2750 if (window_private && window_private->dnd_drop_enabled)
2752 event->dropleave.type = GDK_DROP_LEAVE;
2753 event->dropleave.window = window;
2754 event->dropleave.requestor = xevent->xclient.data.l[0];
2755 event->dropleave.u.allflags = xevent->xclient.data.l[1];
2761 else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeRequest)
2764 * make sure to only handle requests from the window the cursor is
2767 #ifdef G_ENABLE_DEBUG
2768 if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND))
2769 g_print ("GDK_DRAG_REQUEST\n");
2771 event->dragrequest.u.allflags = xevent->xclient.data.l[1];
2774 if (window && gdk_dnd.drag_really &&
2775 xevent->xclient.data.l[0] == gdk_dnd.dnd_drag_curwin &&
2776 event->dragrequest.u.flags.sendreply == 0)
2778 /* Got request - do we need to ask user? */
2779 if (!event->dragrequest.u.flags.willaccept
2780 && event->dragrequest.u.flags.senddata)
2783 event->dragrequest.type = GDK_DRAG_REQUEST;
2784 event->dragrequest.window = window;
2785 event->dragrequest.requestor = xevent->xclient.data.l[0];
2786 event->dragrequest.isdrop = 0;
2787 event->dragrequest.drop_coords.x =
2788 event->dragrequest.drop_coords.y = 0;
2791 else if (event->dragrequest.u.flags.willaccept)
2793 window_private->dnd_drag_destructive_op =
2794 event->dragrequest.u.flags.delete_data;
2795 window_private->dnd_drag_accepted = 1;
2796 window_private->dnd_drag_data_type =
2797 xevent->xclient.data.l[4];
2799 gdk_dnd.dnd_drag_target = gdk_dnd.dnd_drag_curwin;
2800 gdk_dnd_display_drag_cursor(-1, -1, TRUE, TRUE);
2802 gdk_dnd.dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535;
2803 gdk_dnd.dnd_drag_dropzone.y =
2804 (xevent->xclient.data.l[2] >> 16) & 65535;
2805 gdk_dnd.dnd_drag_dropzone.width = xevent->xclient.data.l[3] & 65535;
2806 gdk_dnd.dnd_drag_dropzone.height =
2807 (xevent->xclient.data.l[3] >> 16) & 65535;
2810 else if(xevent->xclient.message_type == gdk_dnd.gdk_XdeDataAvailable)
2812 gint tmp_int; Atom tmp_atom;
2814 guchar *tmp_charptr;
2816 #ifdef G_ENABLE_DEBUG
2817 if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND))
2818 g_print("GDK_DROP_DATA_AVAIL\n");
2820 event->dropdataavailable.u.allflags = xevent->xclient.data.l[1];
2821 event->dropdataavailable.timestamp = xevent->xclient.data.l[4];
2822 event->dropdataavailable.coords.x =
2823 xevent->xclient.data.l[3] & 0xffff;
2824 event->dropdataavailable.coords.y =
2825 (xevent->xclient.data.l[3] >> 16) & 0xffff;
2827 /* No preview of data ATM */
2828 && event->dropdataavailable.u.flags.isdrop)
2830 event->dropdataavailable.type = GDK_DROP_DATA_AVAIL;
2831 event->dropdataavailable.window = window;
2832 event->dropdataavailable.requestor = xevent->xclient.data.l[0];
2833 event->dropdataavailable.data_type =
2834 gdk_atom_name(xevent->xclient.data.l[2]);
2835 if(XGetWindowProperty (gdk_display,
2836 event->dropdataavailable.requestor,
2837 xevent->xclient.data.l[2],
2839 False, XA_PRIMARY, &tmp_atom,
2841 &event->dropdataavailable.data_numbytes,
2846 g_warning("XGetWindowProperty on %#x may have failed\n",
2847 event->dropdataavailable.requestor);
2848 event->dropdataavailable.data = NULL;
2852 GDK_NOTE (DND, g_print("XGetWindowProperty got us %ld bytes\n",
2853 event->dropdataavailable.data_numbytes));
2854 event->dropdataavailable.data =
2855 g_malloc (event->dropdataavailable.data_numbytes);
2856 memcpy (event->dropdataavailable.data,
2857 tmp_charptr, event->dropdataavailable.data_numbytes);
2866 /* Send unknown ClientMessage's on to Gtk for it to use */
2867 event->client.type = GDK_CLIENT_EVENT;
2868 event->client.window = window;
2869 event->client.message_type = xevent->xclient.message_type;
2870 event->client.data_format = xevent->xclient.format;
2871 memcpy(&event->client.data, &xevent->xclient.data,
2872 sizeof(event->client.data));
2879 return_val = return_val && !window_private->destroyed;
2883 /* Print debugging info.
2886 g_print ("mapping notify\n"));
2888 /* Let XLib know that there is a new keyboard mapping.
2890 XRefreshKeyboardMapping (&xevent->xmapping);
2894 /* something else - (e.g., a Xinput event) */
2896 if (window_private &&
2897 (window_private->extension_events != 0) &&
2898 gdk_input_vtable.other_event)
2899 return_val = gdk_input_vtable.other_event(event, xevent, window);
2903 if (return_val < 0) /* not an XInput event, convert */
2905 event->other.type = GDK_OTHER_EVENT;
2906 event->other.window = window;
2907 event->other.xevent = (GdkXEvent *)&other_xevent[other_xevent_i];
2908 memcpy (&other_xevent[other_xevent_i], xevent, sizeof (XEvent));
2909 other_xevent_i = (other_xevent_i+1) % OTHER_XEVENT_BUFSIZE;
2913 return_val = return_val && !window_private->destroyed;
2920 if (event->any.window)
2921 gdk_window_ref (event->any.window);
2922 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2923 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2924 (event->crossing.subwindow != NULL))
2925 gdk_window_ref (event->crossing.subwindow);
2929 /* Mark this event as having no resources to be freed */
2930 event->any.window = NULL;
2931 event->any.type = GDK_NOTHING;
2935 gdk_window_unref (window);
2942 gdk_event_get_type (Display *display,
2949 if (gdk_event_translate (&event, xevent))
2951 pred = (GdkPredicate*) arg;
2952 return (* pred->func) (&event, pred->data);
2960 gdk_synthesize_click (GdkEvent *event,
2963 GdkEvent temp_event;
2965 g_return_if_fail (event != NULL);
2967 temp_event = *event;
2968 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
2970 gdk_event_put (&temp_event);
2974 *--------------------------------------------------------------
2977 * This is the "atexit" function that makes sure the
2978 * library gets a chance to cleanup.
2985 * The library is un-initialized and the program exits.
2987 *--------------------------------------------------------------
2993 static gboolean in_gdk_exit_func = FALSE;
2995 /* This is to avoid an infinite loop if a program segfaults in
2996 an atexit() handler (and yes, it does happen, especially if a program
2997 has trounced over memory too badly for even g_print to work) */
2998 if(in_gdk_exit_func == TRUE) return;
2999 in_gdk_exit_func = TRUE;
3011 gdk_key_repeat_restore ();
3013 XCloseDisplay (gdk_display);
3019 *--------------------------------------------------------------
3022 * The X error handling routine.
3025 * "display" is the X display the error orignated from.
3026 * "error" is the XErrorEvent that we are handling.
3029 * Either we were expecting some sort of error to occur,
3030 * in which case we set the "gdk_error_code" flag, or this
3031 * error was unexpected, in which case we will print an
3032 * error message and exit. (Since trying to continue will
3033 * most likely simply lead to more errors).
3037 *--------------------------------------------------------------
3041 gdk_x_error (Display *display,
3046 if (gdk_error_warnings)
3048 XGetErrorText (display, error->error_code, buf, 63);
3049 g_error ("%s", buf);
3052 gdk_error_code = -1;
3057 *--------------------------------------------------------------
3060 * The X I/O error handling routine.
3063 * "display" is the X display the error orignated from.
3066 * An X I/O error basically means we lost our connection
3067 * to the X server. There is not much we can do to
3068 * continue, so simply print an error message and exit.
3072 *--------------------------------------------------------------
3076 gdk_x_io_error (Display *display)
3078 g_error ("an x io error occurred");
3083 *--------------------------------------------------------------
3086 * The signal handler.
3089 * "sig_num" is the number of the signal we received.
3092 * The signals we catch are all fatal. So we simply build
3093 * up a nice little error message and print it and exit.
3094 * If in the process of doing so another signal is received
3095 * we notice that we are already exiting and simply kill
3100 *--------------------------------------------------------------
3104 gdk_signal (int sig_num)
3106 static int caught_fatal_sig = 0;
3109 if (caught_fatal_sig)
3110 kill (getpid (), sig_num);
3111 caught_fatal_sig = 1;
3137 sig = "unknown signal";
3141 g_print ("\n** ERROR **: %s caught\n", sig);
3142 #ifdef G_ENABLE_DEBUG
3144 #else /* !G_ENABLE_DEBUG */
3146 #endif /* !G_ENABLE_DEBUG */
3150 gdk_dnd_drag_begin (GdkWindow *initial_window)
3152 GdkEventDragBegin tev;
3153 tev.type = GDK_DRAG_BEGIN;
3154 tev.window = initial_window;
3156 tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
3158 gdk_event_put ((GdkEvent *) &tev);
3162 gdk_dnd_drag_enter (Window dest)
3165 GdkEventDropEnter tev;
3167 GdkWindowPrivate *wp;
3169 sev.xclient.type = ClientMessage;
3170 sev.xclient.format = 32;
3171 sev.xclient.message_type = gdk_dnd.gdk_XdeEnter;
3172 sev.xclient.window = dest;
3175 tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
3176 tev.u.flags.sendreply = 1;
3177 for (i = 0; i < gdk_dnd.drag_numwindows; i++)
3179 wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
3180 if (wp->dnd_drag_data_numtypesavail)
3182 sev.xclient.data.l[0] = wp->xwindow;
3183 tev.u.flags.extended_typelist = (wp->dnd_drag_data_numtypesavail > 3)?1:0;
3184 sev.xclient.data.l[1] = tev.u.allflags;
3185 sev.xclient.data.l[2] = wp->dnd_drag_data_typesavail[0];
3186 if (wp->dnd_drag_data_numtypesavail > 1)
3188 sev.xclient.data.l[3] = wp->dnd_drag_data_typesavail[1];
3189 if (wp->dnd_drag_data_numtypesavail > 2)
3191 sev.xclient.data.l[4] = wp->dnd_drag_data_typesavail[2];
3194 sev.xclient.data.l[4] = None;
3197 sev.xclient.data.l[3] = sev.xclient.data.l[4] = None;
3198 if (!gdk_send_xevent (dest, False, NoEventMask, &sev))
3199 GDK_NOTE (DND, g_print("Sending XdeEnter to %#lx failed\n",
3210 *--------------------------------------------------------------
3213 * Begin using input method with XIM Protocol(X11R6 standard)
3216 * "ic" is the "Input Context" which is created by gtk_ic_new.
3217 * The input area is specified with "window".
3220 * The gdk's event handling routine is switched to XIM based routine.
3221 * XIM based routine uses XFilterEvent to get rid of events used by IM,
3222 * and uses XmbLookupString instead of XLookupString.
3226 *--------------------------------------------------------------
3230 gdk_im_begin (GdkIC ic, GdkWindow* window)
3232 GdkICPrivate *private;
3235 g_return_if_fail (ic != NULL);
3236 g_return_if_fail (window);
3238 private = (GdkICPrivate *) ic;
3242 xim_window = window;
3245 XGetICValues (private->xic, XNFocusWindow, &xwin, NULL);
3246 if (xwin != GDK_WINDOW_XWINDOW(window))
3247 XSetICValues (private->xic, XNFocusWindow,
3248 GDK_WINDOW_XWINDOW(window), NULL);
3249 if (private != xim_ic)
3250 XSetICFocus (private->xic);
3255 *--------------------------------------------------------------
3258 * End using input method with XIM Protocol(X11R6 standard)
3263 * The gdk's event handling routine is switched to normal routine.
3264 * User should call this function before ic and window will be destroyed.
3268 *--------------------------------------------------------------
3286 gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2)
3288 GdkIMStyle s1, s2, u;
3290 if (style1 == 0) return style2;
3291 if (style2 == 0) return style1;
3292 if ((style1 & (GdkIMPreeditMask | GdkIMStatusMask))
3293 == (style2 & (GdkIMPreeditMask | GdkIMStatusMask)))
3296 s1 = style1 & GdkIMPreeditMask;
3297 s2 = style2 & GdkIMPreeditMask;
3300 if (u & GdkIMPreeditCallbacks)
3301 return (s1 == GdkIMPreeditCallbacks)? style1:style2;
3302 else if (u & GdkIMPreeditPosition)
3303 return (s1 == GdkIMPreeditPosition)? style1:style2;
3304 else if (u & GdkIMPreeditArea)
3305 return (s1 == GdkIMPreeditArea)? style1:style2;
3306 else if (u & GdkIMPreeditNothing)
3307 return (s1 == GdkIMPreeditNothing)? style1:style2;
3309 s1 = style1 & GdkIMStatusMask;
3310 s2 = style2 & GdkIMStatusMask;
3312 if ( u & GdkIMStatusCallbacks)
3313 return (s1 == GdkIMStatusCallbacks)? style1:style2;
3314 else if ( u & GdkIMStatusArea)
3315 return (s1 == GdkIMStatusArea)? style1:style2;
3316 else if ( u & GdkIMStatusNothing)
3317 return (s1 == GdkIMStatusNothing)? style1:style2;
3318 else if ( u & GdkIMStatusNone)
3319 return (s1 == GdkIMStatusNone)? style1:style2;
3321 return 0; /* Get rid of stupid warning */
3325 gdk_im_decide_style (GdkIMStyle supported_style)
3328 GdkIMStyle style, tmp;
3330 g_return_val_if_fail (xim_styles != NULL, 0);
3333 for (i=0; i<xim_styles->count_styles; i++)
3335 tmp = xim_styles->supported_styles[i];
3336 if (tmp == (tmp & supported_style & xim_best_allowed_style))
3337 style = gdk_im_choose_better_style (style, tmp);
3343 gdk_im_set_best_style (GdkIMStyle style)
3345 if (style & GdkIMPreeditMask)
3347 xim_best_allowed_style &= ~GdkIMPreeditMask;
3349 xim_best_allowed_style |= GdkIMPreeditNone;
3350 if (!(style & GdkIMPreeditNone))
3352 xim_best_allowed_style |= GdkIMPreeditNothing;
3353 if (!(style & GdkIMPreeditNothing))
3355 xim_best_allowed_style |= GdkIMPreeditArea;
3356 if (!(style & GdkIMPreeditArea))
3358 xim_best_allowed_style |= GdkIMPreeditPosition;
3359 if (!(style & GdkIMPreeditPosition))
3360 xim_best_allowed_style |= GdkIMPreeditCallbacks;
3365 if (style & GdkIMStatusMask)
3367 xim_best_allowed_style &= ~GdkIMStatusMask;
3369 xim_best_allowed_style |= GdkIMStatusNone;
3370 if (!(style & GdkIMStatusNone))
3372 xim_best_allowed_style |= GdkIMStatusNothing;
3373 if (!(style & GdkIMStatusNothing))
3375 xim_best_allowed_style |= GdkIMStatusArea;
3376 if (!(style & GdkIMStatusArea))
3377 xim_best_allowed_style |= GdkIMStatusCallbacks;
3382 return xim_best_allowed_style;
3386 gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class)
3388 xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class);
3391 GDK_NOTE (XIM, g_warning ("Unable to open open IM."));
3394 XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
3417 return (xim_im != NULL);
3421 gdk_ic_new (GdkWindow* client_window,
3422 GdkWindow* focus_window,
3423 GdkIMStyle style, ...)
3426 GdkICPrivate *private;
3427 XVaNestedList preedit_attr;
3429 g_return_val_if_fail (client_window != NULL, NULL);
3430 g_return_val_if_fail (focus_window != NULL, NULL);
3431 g_return_val_if_fail (gdk_im_ready(), NULL);
3433 private = g_new (GdkICPrivate, 1);
3435 va_start (list, style);
3436 preedit_attr = (XVaNestedList) & (va_arg (list, void *));
3439 private->style = gdk_im_decide_style (style);
3440 if (private->style != style)
3442 g_warning ("can not create input context with specified input style.");
3447 private->xic = XCreateIC(gdk_im_get (),
3448 XNInputStyle, style,
3449 XNClientWindow, GDK_WINDOW_XWINDOW (client_window),
3450 XNFocusWindow, GDK_WINDOW_XWINDOW (focus_window),
3451 preedit_attr? XNPreeditAttributes : NULL, preedit_attr,
3459 xim_ic_list = g_list_append (xim_ic_list, private);
3464 gdk_ic_destroy (GdkIC ic)
3466 GdkICPrivate *private;
3468 g_return_if_fail (ic != NULL);
3470 private = (GdkICPrivate *) ic;
3472 if (xim_ic == private)
3475 XDestroyIC (private->xic);
3476 xim_ic_list = g_list_remove (xim_ic_list, private);
3481 gdk_ic_get_style (GdkIC ic)
3483 GdkICPrivate *private;
3485 g_return_val_if_fail (ic != NULL, 0);
3487 private = (GdkICPrivate *) ic;
3489 return private->style;
3493 gdk_ic_set_values (GdkIC ic, ...)
3497 GdkICPrivate *private;
3499 g_return_if_fail (ic != NULL);
3501 private = (GdkICPrivate *) ic;
3503 va_start (list, ic);
3504 args = (XVaNestedList) & (va_arg (list, void *));
3507 XSetICValues (private->xic, XNVaNestedList, args, NULL);
3511 gdk_ic_get_values (GdkIC ic, ...)
3515 GdkICPrivate *private;
3517 g_return_if_fail (ic != NULL);
3519 private = (GdkICPrivate *) ic;
3521 va_start (list, ic);
3522 args = (XVaNestedList) & (va_arg (list, void *));
3525 XGetICValues (private->xic, XNVaNestedList, args, NULL);
3529 gdk_ic_set_attr (GdkIC ic, const char *target, ...)
3533 GdkICPrivate *private;
3535 g_return_if_fail (ic != NULL);
3536 g_return_if_fail (target != NULL);
3538 private = (GdkICPrivate *) ic;
3540 va_start (list, target);
3541 attr = (XVaNestedList) & (va_arg (list, void *));
3544 XSetICValues (private->xic, target, attr, NULL);
3548 gdk_ic_get_attr (GdkIC ic, const char *target, ...)
3552 GdkICPrivate *private;
3554 g_return_if_fail (ic != NULL);
3555 g_return_if_fail (target != NULL);
3557 private = (GdkICPrivate *) ic;
3559 va_start (list, target);
3560 attr = (XVaNestedList) & (va_arg (list, void *));
3563 XGetICValues (private->xic, target, attr, NULL);
3567 gdk_ic_get_events (GdkIC ic)
3572 GdkICPrivate *private;
3575 /* From gdkwindow.c */
3576 extern int nevent_masks;
3577 extern int event_mask_table[];
3579 g_return_val_if_fail (ic != NULL, 0);
3581 private = (GdkICPrivate *) ic;
3583 if (XGetICValues (private->xic, XNFilterEvents, &xmask, NULL) != NULL)
3585 GDK_NOTE (XIM, g_warning ("Call to XGetICValues: %s failed", XNFilterEvents));
3590 for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1)
3591 if (xmask & event_mask_table [i])
3594 xmask &= ~ event_mask_table [i];
3598 g_warning ("ic requires events not supported by the application (%#04lx)", xmask);
3604 gdk_ic_cleanup (void)
3608 GdkICPrivate *private;
3611 for (node = xim_ic_list; node != NULL; node = node->next)
3615 private = (GdkICPrivate *) (node->data);
3616 XDestroyIC (private->xic);
3621 #ifdef G_ENABLE_DEBUG
3622 if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0)
3624 g_warning ("Cleaned up %i IC(s)\n", destroyed);
3626 #endif /* G_ENABLE_DEBUG */
3627 g_list_free(xim_ic_list);
3631 #else /* !USE_XIM */
3634 gdk_im_begin (GdkIC ic, GdkWindow* window)
3644 gdk_im_decide_style (GdkIMStyle supported_style)
3646 return GdkIMPreeditNone | GdkIMStatusNone;
3650 gdk_im_set_best_style (GdkIMStyle style)
3652 return GdkIMPreeditNone | GdkIMStatusNone;
3662 gdk_ic_new (GdkWindow* client_window,
3663 GdkWindow* focus_window,
3664 GdkIMStyle style, ...)
3670 gdk_ic_destroy (GdkIC ic)
3675 gdk_ic_get_style (GdkIC ic)
3677 return GdkIMPreeditNone | GdkIMStatusNone;
3681 gdk_ic_set_values (GdkIC ic, ...)
3686 gdk_ic_get_values (GdkIC ic, ...)
3691 gdk_ic_set_attr (GdkIC ic, const char *target, ...)
3696 gdk_ic_get_attr (GdkIC ic, const char *target, ...)
3701 gdk_ic_get_events (GdkIC ic)
3706 #endif /* USE_XIM */
3711 _g_mbtowc (wchar_t *wstr, const char *str, size_t len)
3713 static wchar_t wcs[MB_CUR_MAX + 1];
3714 static gchar mbs[MB_CUR_MAX + 1];
3716 wcs[0] = (wchar_t) NULL;
3719 len = _Xmbstowcs (wcs, str, (len<MB_CUR_MAX)? len:MB_CUR_MAX);
3722 else if (wcs[0] == (wchar_t) NULL)
3725 len = _Xwctomb (mbs, wcs[0]);
3734 #endif /* X_LOCALE */
3737 gdk_dnd_drag_leave (Window dest)
3740 GdkEventDropLeave tev;
3742 GdkWindowPrivate *wp;
3746 tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
3747 sev.xclient.type = ClientMessage;
3748 sev.xclient.window = dest;
3749 sev.xclient.format = 32;
3750 sev.xclient.message_type = gdk_dnd.gdk_XdeLeave;
3751 sev.xclient.data.l[1] = tev.u.allflags;
3752 for (i = 0; i < gdk_dnd.drag_numwindows; i++)
3754 wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
3755 sev.xclient.data.l[0] = wp->xwindow;
3756 if (!gdk_send_xevent (dest, False, NoEventMask, &sev))
3757 GDK_NOTE (DND, g_print("Sending XdeLeave to %#lx failed\n",
3759 wp->dnd_drag_accepted = 0;
3764 * when a drop occurs, we go through the list of windows being dragged and
3765 * tell them that it has occurred, so that they can set things up and reply
3769 gdk_dnd_drag_end (Window dest,
3772 GdkWindowPrivate *wp;
3773 GdkEventDragRequest tev;
3776 tev.type = GDK_DRAG_REQUEST;
3777 tev.drop_coords = coords;
3778 tev.requestor = dest;
3780 tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
3783 for (i = 0; i < gdk_dnd.drag_numwindows; i++)
3785 wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
3786 if (wp->dnd_drag_accepted)
3788 tev.window = (GdkWindow *) wp;
3789 tev.u.flags.delete_data = wp->dnd_drag_destructive_op;
3790 tev.timestamp = gdk_dnd.last_drop_time;
3792 gdk_atom_name(wp->dnd_drag_data_type);
3794 gdk_event_put((GdkEvent *) &tev);
3800 gdk_dnd_check_types (GdkWindow *window,
3803 GdkWindowPrivate *wp = (GdkWindowPrivate *) window;
3805 GdkEventDropEnter event;
3807 g_return_val_if_fail(window != NULL, 0);
3808 g_return_val_if_fail(xevent != NULL, 0);
3809 g_return_val_if_fail(xevent->type == ClientMessage, 0);
3810 g_return_val_if_fail(xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter, 0);
3812 if(wp->dnd_drop_data_numtypesavail <= 0 ||
3813 !wp->dnd_drop_data_typesavail)
3816 for (i = 2; i <= 4; i++)
3818 for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++)
3820 if (xevent->xclient.data.l[i] == wp->dnd_drop_data_typesavail[j])
3821 return xevent->xclient.data.l[i];
3825 /* Now we get the extended type list if it's available */
3826 event.u.allflags = xevent->xclient.data.l[1];
3827 if (event.u.flags.extended_typelist)
3829 Atom *exttypes, realtype;
3830 gulong nitems, nbar;
3833 if (XGetWindowProperty(gdk_display, xevent->xclient.data.l[0],
3834 gdk_dnd.gdk_XdeTypelist, 0L, LONG_MAX - 1,
3835 False, AnyPropertyType, &realtype, &realfmt,
3836 &nitems, &nbar, (unsigned char **) &exttypes)
3840 if (realfmt != (sizeof(Atom) * 8))
3842 g_warning("XdeTypelist property had format of %d instead of the expected %d, on window %#lx\n",
3843 realfmt, sizeof(Atom) * 8, xevent->xclient.data.l[0]);
3847 for (i = 0; i <= nitems; i++)
3849 for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++)
3851 if (exttypes[i] == wp->dnd_drop_data_typesavail[j])
3864 * used for debugging only
3868 gdk_print_atom (GdkAtom anatom)
3870 gchar *tmpstr = NULL;
3871 tmpstr = (anatom!=None)?gdk_atom_name(anatom):"(none)";
3872 g_print("Atom %lu has name %s\n", anatom, tmpstr);
3879 * used only by below routine and itself
3882 getchildren (Display *dpy,
3886 Window root, parent, *children, inf = 0;
3888 unsigned int nchildren, i;
3890 unsigned long nitems, after;
3891 unsigned char *data;
3893 if (XQueryTree(dpy, win, &root, &parent, &children, &nchildren) == 0)
3896 for (i = 0; !inf && (i < nchildren); i++)
3898 XGetWindowProperty (dpy, children[i], WM_STATE, 0, 0, False,
3899 AnyPropertyType, &type, &format, &nitems,
3906 for (i = 0; !inf && (i < nchildren); i++)
3907 inf = getchildren (dpy, children[i], WM_STATE);
3909 if (children != None)
3910 XFree ((char *) children);
3916 * find a window with WM_STATE, else return win itself, as per ICCCM
3918 * modification of the XmuClientWindow() routine from X11R6.3
3921 gdk_get_client_window (Display *dpy,
3927 unsigned long nitems, after;
3928 unsigned char *data;
3932 return DefaultRootWindow(dpy);
3934 if ((WM_STATE = XInternAtom (dpy, "WM_STATE", True)) == 0)
3937 XGetWindowProperty (dpy, win, WM_STATE, 0, 0, False, AnyPropertyType,
3938 &type, &format, &nitems, &after, &data);
3942 inf = getchildren (dpy, win, WM_STATE);
3950 #ifdef WE_HAVE_MOTIF_DROPS_DONE
3952 gdk_drop_get_real_window (GdkWindow *w,
3956 GdkWindow *retval = w;
3957 GdkWindowPrivate *awin;
3959 gint16 myx = *x, myy = *y;
3961 g_return_val_if_fail(w != NULL && x != NULL && y != NULL, NULL);
3967 for (children = gdk_window_get_children(retval);
3968 children && children->next;
3969 children = children->next)
3971 awin = (GdkWindowPrivate *) children->data;
3972 if ((myx >= awin->x) && (myy >= awin->y)
3973 && (myx < (awin->x + awin->width))
3974 && (myy < (awin->y + awin->height)))
3976 retval = (GdkWindow *) awin;
3990 /* Sends a ClientMessage to all toplevel client windows */
3992 gdk_event_send_clientmessage_toall(GdkEvent *event)
3995 Window *ret_children, ret_root, ret_parent, curwin;
3996 unsigned int ret_nchildren;
3999 g_return_if_fail(event != NULL);
4001 /* Set up our event to send, with the exception of its target window */
4002 sev.xclient.type = ClientMessage;
4003 sev.xclient.display = gdk_display;
4004 sev.xclient.format = event->client.data_format;
4005 sev.xclient.serial = CurrentTime;
4006 memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data));
4007 sev.xclient.message_type = event->client.message_type;
4009 /* OK, we're all set, now let's find some windows to send this to */
4010 if(XQueryTree(gdk_display, gdk_root_window, &ret_root, &ret_parent,
4011 &ret_children, &ret_nchildren) != True)
4014 /* foreach true child window of the root window, send an event to it */
4015 for(i = 0; i < ret_nchildren; i++) {
4016 curwin = gdk_get_client_window(gdk_display, ret_children[i]);
4017 sev.xclient.window = curwin;
4018 if (!gdk_send_xevent (curwin, False, NoEventMask, &sev))
4019 GDK_NOTE (MISC, g_print("Sending client message %ld to %#lx failed\n",
4020 event->client.message_type, curwin));
4023 XFree(ret_children);
4027 gdk_get_display(void)
4029 return (gchar *)XDisplayName (gdk_display_name);
4033 gdk_send_xevent (Window window, gboolean propagate, glong event_mask,
4040 gdk_error_warnings = 0;
4041 result = XSendEvent (gdk_display, window, propagate, event_mask, event_send);
4042 XSync (gdk_display, False);
4043 gdk_error_warnings = 1;
4045 return result && (gdk_error_code != -1);