X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fgdk.c;h=87d12ea46931ef4d0908544cdc61611d59d416f8;hb=2fb74b135baeeb7b2363e099d61ac953c1467404;hp=6b5f4021f51bac2e1979652f5845158da60dfebb;hpb=a391196ba51da34253593712e8bf4552c04f19e5;p=~andy%2Fgtk diff --git a/gdk/gdk.c b/gdk/gdk.c index 6b5f4021f..87d12ea46 100644 --- a/gdk/gdk.c +++ b/gdk/gdk.c @@ -2,4404 +2,528 @@ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ -#include "../config.h" - -/* If you don't want to use gdk's signal handlers define this */ -/* #define I_NEED_TO_ACTUALLY_DEBUG_MY_PROGRAMS 1 */ - -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_XIM -#include -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#endif /* HAVE_SYS_SELECT_H_ */ - -#define XLIB_ILLEGAL_ACCESS -#include -#include -#include -#include -#include -#ifdef USE_XIM -#include -#endif -#include -#include "gdk.h" -#include "gdkprivate.h" -#include "gdkinput.h" -#include "gdkx.h" -#include "gdkkeysyms.h" -#include "gdki18n.h" - -#ifndef X_GETTIMEOFDAY -#define X_GETTIMEOFDAY(tv) gettimeofday (tv, NULL) -#endif /* X_GETTIMEOFDAY */ - - -#define DOUBLE_CLICK_TIME 250 -#define TRIPLE_CLICK_TIME 500 -#define DOUBLE_CLICK_DIST 5 -#define TRIPLE_CLICK_DIST 5 - - -#ifndef NO_FD_SET -# define SELECT_MASK fd_set -#else -# ifndef _AIX - typedef long fd_mask; -# endif -# if defined(_IBMR2) -# define SELECT_MASK void -# else -# define SELECT_MASK int -# endif -#endif - - -typedef struct _GdkInput GdkInput; -typedef struct _GdkPredicate GdkPredicate; - -struct _GdkInput -{ - gint tag; - gint source; - GdkInputCondition condition; - GdkInputFunction function; - gpointer data; - GdkDestroyNotify destroy; -}; - -struct _GdkPredicate -{ - GdkEventFunc func; - gpointer data; -}; - -/* - * Private function declarations - */ - -static GdkEvent *gdk_event_new (void); -static gint gdk_event_wait (void); -static gint gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters); -static gint gdk_event_translate (GdkEvent *event, - XEvent *xevent); -#if 0 -static Bool gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg); -#endif -static void gdk_synthesize_click (GdkEvent *event, - gint nclicks); - -static void gdk_dnd_drag_begin (GdkWindow *initial_window); -static void gdk_dnd_drag_enter (Window dest); -static void gdk_dnd_drag_leave (Window dest); -static void gdk_dnd_drag_end (Window dest, - GdkPoint coords); -static GdkAtom gdk_dnd_check_types (GdkWindow *window, - XEvent *xevent); -#ifdef DEBUG_DND -static void gdk_print_atom (GdkAtom anatom); -#endif - -/* - * old junk from offix, we might use it though so leave it - */ -Window gdk_get_client_window (Display *dpy, - Window win); -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y); -#endif -static void gdk_exit_func (void); -static int gdk_x_error (Display *display, - XErrorEvent *error); -static int gdk_x_io_error (Display *display); -static RETSIGTYPE gdk_signal (int signum); - - -#ifdef USE_XIM -static guint gdk_im_va_count (va_list list); -static XVaNestedList gdk_im_va_to_nested (va_list list, - guint count); - -static GdkIM gdk_im_get (void); -static gint gdk_im_open (XrmDatabase db, - gchar* res_name, - gchar* rec_class); -static void gdk_im_close (void); -static void gdk_ic_cleanup (void); - -#endif /* USE_XIM */ - -/* Private variable declarations - */ -static int initialized = 0; /* 1 if the library is initialized, - * 0 otherwise. - */ -static int connection_number = 0; /* The file descriptor number of our - * connection to the X server. This - * is used so that we may determine - * when events are pending by using - * the "select" system call. - */ - - -static struct timeval start; /* The time at which the library was - * last initialized. - */ -static struct timeval timer; /* Timeout interval to use in the call - * to "select". This is used in - * conjunction with "timerp" to create - * a maximum time to wait for an event - * to arrive. - */ -static struct timeval *timerp; /* The actual timer passed to "select" - * This may be NULL, in which case - * "select" will block until an event - * arrives. - */ -static guint32 timer_val; /* The timeout length as specified by - * the user in milliseconds. - */ -static GList *inputs; /* A list of the input file descriptors - * that we care about. Each list node - * contains a GdkInput struct that describes - * when we are interested in the specified - * file descriptor. That is, when it is - * available for read, write or has an - * exception pending. - */ -static guint32 button_click_time[2]; /* The last 2 button click times. Used - * to determine if the latest button click - * is part of a double or triple click. - */ -static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses. - * Also used to determine if the latest button - * click is part of a double or triple click. - */ -static guint button_number[2]; /* The last 2 buttons to be pressed. - */ -static GdkWindowPrivate *xgrab_window = NULL; /* Window that currently holds the - * x pointer grab - */ - -#ifdef USE_XIM -static gint xim_using; /* using XIM Protocol if TRUE */ -static GdkIM xim_im; /* global IM */ -static XIMStyles* xim_styles; /* im supports these styles */ -static XIMStyle xim_best_allowed_style; -static GdkICPrivate *xim_ic; /* currently using IC */ -static GdkWindow* xim_window; /* currently using Widow */ -static GList* xim_ic_list; - -#endif - -static GList *putback_events = NULL; - -static gulong base_id; -static gint autorepeat; - -#ifdef G_ENABLE_DEBUG -static GDebugKey gdk_debug_keys[] = { - {"events", GDK_DEBUG_EVENTS}, - {"misc", GDK_DEBUG_MISC}, - {"dnd", GDK_DEBUG_DND}, - {"color-context", GDK_DEBUG_COLOR_CONTEXT}, - {"xim", GDK_DEBUG_XIM} -}; - -static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey); - -#endif /* G_ENABLE_DEBUG */ - -/* - *-------------------------------------------------------------- - * gdk_init - * - * Initialize the library for use. - * - * Arguments: - * "argc" is the number of arguments. - * "argv" is an array of strings. - * - * Results: - * "argc" and "argv" are modified to reflect any arguments - * which were not handled. (Such arguments should either - * be handled by the application or dismissed). - * - * Side effects: - * The library is initialized. - * - *-------------------------------------------------------------- - */ - -void -gdk_init (int *argc, - char ***argv) -{ - XKeyboardState keyboard_state; - gint synchronize; - gint i, j, k; - XClassHint *class_hint; - gint argc_orig = *argc; - gchar **argv_orig; - - argv_orig = g_malloc ((argc_orig + 1) * sizeof (char*)); - for (i = 0; i < argc_orig; i++) - argv_orig[i] = g_strdup ((*argv)[i]); - argv_orig[argc_orig] = NULL; - - X_GETTIMEOFDAY (&start); - -#ifndef I_NEED_TO_ACTUALLY_DEBUG_MY_PROGRAMS - signal (SIGHUP, gdk_signal); - signal (SIGINT, gdk_signal); - signal (SIGQUIT, gdk_signal); - signal (SIGBUS, gdk_signal); - signal (SIGSEGV, gdk_signal); - signal (SIGPIPE, gdk_signal); - signal (SIGTERM, gdk_signal); -#endif - - gdk_display_name = NULL; - - XSetErrorHandler (gdk_x_error); - XSetIOErrorHandler (gdk_x_io_error); - - synchronize = FALSE; - -#ifdef G_ENABLE_DEBUG - { - gchar *debug_string = getenv("GDK_DEBUG"); - if (debug_string != NULL) - gdk_debug_flags = g_parse_debug_string (debug_string, - gdk_debug_keys, - gdk_ndebug_keys); - } -#endif /* G_ENABLE_DEBUG */ - - if (argc && argv) - { - if (*argc > 0) - { - gchar *d; - - d = strrchr((*argv)[0],'/'); - if (d != NULL) - gdk_progname = g_strdup (d + 1); - else - gdk_progname = g_strdup ((*argv)[0]); - GDK_NOTE (MISC, - g_print ("Gdk: progname: \"%s\"\n", gdk_progname)); - } - - for (i = 1; i < *argc;) - { -#ifdef G_ENABLE_DEBUG - if ((strcmp ("--gdk-debug", (*argv)[i]) == 0) || - (strncmp ("--gdk-debug=", (*argv)[i], 12) == 0)) - { - gchar *equal_pos = strchr ((*argv)[i], '='); - - if (equal_pos != NULL) - { - gdk_debug_flags |= g_parse_debug_string (equal_pos+1, - gdk_debug_keys, - gdk_ndebug_keys); - } - else if ((i + 1) < *argc && (*argv)[i + 1]) - { - gdk_debug_flags |= g_parse_debug_string ((*argv)[i+1], - gdk_debug_keys, - gdk_ndebug_keys); - (*argv)[i] = NULL; - i += 1; - } - (*argv)[i] = NULL; - } - else if ((strcmp ("--gdk-no-debug", (*argv)[i]) == 0) || - (strncmp ("--gdk-no-debug=", (*argv)[i], 15) == 0)) - { - gchar *equal_pos = strchr ((*argv)[i], '='); - - if (equal_pos != NULL) - { - gdk_debug_flags &= ~g_parse_debug_string (equal_pos+1, - gdk_debug_keys, - gdk_ndebug_keys); - } - else if ((i + 1) < *argc && (*argv)[i + 1]) - { - gdk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1], - gdk_debug_keys, - gdk_ndebug_keys); - (*argv)[i] = NULL; - i += 1; - } - (*argv)[i] = NULL; - } - else -#endif /* G_ENABLE_DEBUG */ - if (strcmp ("--display", (*argv)[i]) == 0) - { - (*argv)[i] = NULL; - - if ((i + 1) < *argc && (*argv)[i + 1]) - { - gdk_display_name = g_strdup ((*argv)[i + 1]); - (*argv)[i + 1] = NULL; - i += 1; - } - } - else if (strcmp ("--sync", (*argv)[i]) == 0) - { - (*argv)[i] = NULL; - synchronize = TRUE; - } - else if (strcmp ("--no-xshm", (*argv)[i]) == 0) - { - (*argv)[i] = NULL; - gdk_use_xshm = FALSE; - } - else if (strcmp ("--name", (*argv)[i]) == 0) - { - if ((i + 1) < *argc && (*argv)[i + 1]) - { - (*argv)[i++] = NULL; - gdk_progname = (*argv)[i]; - (*argv)[i] = NULL; - } - } - else if (strcmp ("--class", (*argv)[i]) == 0) - { - if ((i + 1) < *argc && (*argv)[i + 1]) - { - (*argv)[i++] = NULL; - gdk_progclass = (*argv)[i]; - (*argv)[i] = NULL; - } - } -#ifdef XINPUT_GXI - else if (strcmp ("--gxid_host", (*argv)[i]) == 0) - { - if ((i + 1) < *argc && (*argv)[i + 1]) - { - (*argv)[i++] = NULL; - gdk_input_gxid_host = ((*argv)[i]); - (*argv)[i] = NULL; - } - } - else if (strcmp ("--gxid_port", (*argv)[i]) == 0) - { - if ((i + 1) < *argc && (*argv)[i + 1]) - { - (*argv)[i++] = NULL; - gdk_input_gxid_port = atoi ((*argv)[i]); - (*argv)[i] = NULL; - } - } -#endif -#ifdef USE_XIM - else if (strcmp ("--xim-preedit", (*argv)[i]) == 0) - { - if ((i + 1) < *argc && (*argv)[i + 1]) - { - (*argv)[i++] = NULL; - if (strcmp ("none", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditNone); - else if (strcmp ("nothing", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditNothing); - else if (strcmp ("area", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditArea); - else if (strcmp ("position", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditPosition); - else if (strcmp ("callbacks", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMPreeditCallbacks); - } - } - else if (strcmp ("--xim-status", (*argv)[i]) == 0) - { - if ((i + 1) < *argc && (*argv)[i + 1]) - { - (*argv)[i++] = NULL; - if (strcmp ("none", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusNone); - else if (strcmp ("nothing", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusNothing); - else if (strcmp ("area", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusArea); - else if (strcmp ("callbacks", (*argv)[i]) == 0) - gdk_im_set_best_style (GdkIMStatusCallbacks); - } - } -#endif - - i += 1; - } - - for (i = 1; i < *argc; i++) - { - for (k = i; k < *argc; k++) - if ((*argv)[k] != NULL) - break; - - if (k > i) - { - k -= i; - for (j = i + k; j < *argc; j++) - (*argv)[j-k] = (*argv)[j]; - *argc -= k; - } - } - } - else - { - gdk_progname = ""; - } - - gdk_display = XOpenDisplay (gdk_display_name); - if (!gdk_display) - { - g_warning ("cannot open display: %s", XDisplayName (gdk_display_name)); - exit(1); - } - - /* This is really crappy. We have to look into the display structure - * to find the base resource id. This is only needed for recording - * and playback of events. - */ - /* base_id = RESOURCE_BASE; */ - base_id = 0; - GDK_NOTE (EVENTS, g_print ("base id: %lu\n", base_id)); - - connection_number = ConnectionNumber (gdk_display); - GDK_NOTE (MISC, - g_print ("Gdk: connection number: %d\n", connection_number)); - - if (synchronize) - XSynchronize (gdk_display, True); - - gdk_screen = DefaultScreen (gdk_display); - gdk_root_window = RootWindow (gdk_display, gdk_screen); - - gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window, - 10, 10, 10, 10, 0, 0 , 0); - class_hint = XAllocClassHint(); - class_hint->res_name = gdk_progname; - if (gdk_progclass == NULL) - { - gdk_progclass = g_strdup (gdk_progname); - gdk_progclass[0] = toupper (gdk_progclass[0]); - } - class_hint->res_class = gdk_progclass; - XSetClassHint(gdk_display, gdk_leader_window, class_hint); - XSetCommand(gdk_display, gdk_leader_window, argv_orig, argc_orig); - XFree (class_hint); - - for (i = 0; i < argc_orig; i++) - g_free(argv_orig[i]); - g_free(argv_orig); - - gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True); - gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True); - gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True); - gdk_wm_window_protocols[0] = gdk_wm_delete_window; - gdk_wm_window_protocols[1] = gdk_wm_take_focus; - gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False); - - gdk_dnd.gdk_XdeEnter = gdk_atom_intern("_XDE_ENTER", FALSE); - gdk_dnd.gdk_XdeLeave = gdk_atom_intern("_XDE_LEAVE", FALSE); - gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE); - gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE); - gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE); - gdk_dnd.c->gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity); - gdk_dnd.c->gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart); - - XGetKeyboardControl (gdk_display, &keyboard_state); - autorepeat = keyboard_state.global_auto_repeat; - - timer.tv_sec = 0; - timer.tv_usec = 0; - timerp = NULL; - - button_click_time[0] = 0; - button_click_time[1] = 0; - button_window[0] = NULL; - button_window[1] = NULL; - button_number[0] = -1; - button_number[1] = -1; - - if (ATEXIT (gdk_exit_func)) - g_warning ("unable to register exit function"); - - gdk_visual_init (); - gdk_window_init (); - gdk_image_init (); - gdk_input_init (); - -#ifdef USE_XIM - /* initialize XIM Protocol variables */ - xim_using = FALSE; - xim_im = NULL; - xim_styles = NULL; - if (!(xim_best_allowed_style & GdkIMPreeditMask)) - gdk_im_set_best_style (GdkIMPreeditCallbacks); - if (!(xim_best_allowed_style & GdkIMStatusMask)) - gdk_im_set_best_style (GdkIMStatusCallbacks); - xim_ic = NULL; - xim_window = (GdkWindow*)NULL; - - gdk_im_open (NULL, NULL, NULL); -#endif - - initialized = 1; -} - -/* - *-------------------------------------------------------------- - * gdk_exit - * - * Restores the library to an un-itialized state and exits - * the program using the "exit" system call. - * - * Arguments: - * "errorcode" is the error value to pass to "exit". - * - * Results: - * Allocated structures are freed and the program exits - * cleanly. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void -gdk_exit (int errorcode) -{ - /* de-initialisation is done by the gdk_exit_funct(), - no need to do this here (Alex J.) */ - exit (errorcode); -} - -/* - *-------------------------------------------------------------- - * gdk_set_locale - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gchar* -gdk_set_locale (void) -{ - if (!setlocale (LC_ALL,"")) - g_print ("locale not supported by C library\n"); - - if (!XSupportsLocale ()) - { - g_print ("locale not supported by Xlib, locale set to C\n"); - setlocale (LC_ALL, "C"); - } - - if (!XSetLocaleModifiers ("")) - { - g_print ("can not set locale modifiers\n"); - } - - return setlocale (LC_ALL,NULL); -} - -/* - *-------------------------------------------------------------- - * gdk_events_pending - * - * Returns the number of events pending on the queue. - * These events have already been read from the server - * connection. - * - * Arguments: - * - * Results: - * Returns the number of events on XLib's event queue. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_events_pending (void) -{ - gint result; - GList *tmp_list; - - result = XPending (gdk_display); - - tmp_list = putback_events; - while (tmp_list) - { - result++; - tmp_list = tmp_list->next; - } - - return result; -} - -/* - *-------------------------------------------------------------- - * gdk_event_get_graphics_expose - * - * Waits for a GraphicsExpose or NoExpose event - * - * Arguments: - * - * Results: - * For GraphicsExpose events, returns a pointer to the event - * converted into a GdkEvent Otherwise, returns NULL. - * - * Side effects: - * - *-------------------------------------------------------------- */ - -static Bool -graphics_expose_predicate (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkWindowPrivate *private = (GdkWindowPrivate *)arg; - - g_return_val_if_fail (private != NULL, False); - - if ((xevent->xany.window == private->xwindow) && - ((xevent->xany.type == GraphicsExpose) || - (xevent->xany.type == NoExpose))) - return True; - else - return False; -} - -GdkEvent * -gdk_event_get_graphics_expose (GdkWindow *window) -{ - XEvent xevent; - GdkEvent *event; - - g_return_val_if_fail (window != NULL, NULL); - - XIfEvent (gdk_display, &xevent, graphics_expose_predicate, (XPointer)window); - - if (xevent.xany.type == GraphicsExpose) - { - event = gdk_event_new (); - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - -/* - *-------------------------------------------------------------- - * gdk_event_get - * - * Gets the next event. - * - * Arguments: - * - * Results: - * If an event was received that we care about, returns - * a pointer to that event, to be freed with gdk_event_free. - * Otherwise, returns NULL. This function will also return - * before an event is received if the timeout interval - * runs out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -GdkEvent * -gdk_event_get (void) -{ - GdkEvent *event; - GList *temp_list; - XEvent xevent; - -#if 0 - if (pred) - { - temp_list = putback_events; - while (temp_list) - { - temp_event = temp_list->data; - - if ((* pred) (temp_event, data)) - { - if (event) - *event = *temp_event; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free (temp_list); - return TRUE; - } - - temp_list = temp_list->next; - } - - event_pred.func = pred; - event_pred.data = data; - - if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) & event_pred)) - if (event) - return gdk_event_translate (event, &xevent); - } - else -#endif - if (putback_events) - { - event = putback_events->data; - - temp_list = putback_events; - putback_events = g_list_remove_link (putback_events, temp_list); - g_list_free_1 (temp_list); - - return event; - } - - /* Wait for an event to occur or the timeout to elapse. - * If an event occurs "gdk_event_wait" will return TRUE. - * If the timeout elapses "gdk_event_wait" will return - * FALSE. - */ - if (gdk_event_wait ()) - { - /* If we get here we can rest assurred that an event - * has occurred. Read it. - */ -#ifdef USE_XIM - gint filter_status; - if (xim_using && xim_window) - do - { /* don't dispatch events used by IM */ - XNextEvent (gdk_display, &xevent); - filter_status = XFilterEvent (&xevent, - GDK_WINDOW_XWINDOW (xim_window)); - } while (filter_status == True); - else - XNextEvent (gdk_display, &xevent); -#else - XNextEvent (gdk_display, &xevent); -#endif - event = gdk_event_new (); - - event->any.type = GDK_NOTHING; - event->any.window = NULL; - event->any.send_event = FALSE; - event->any.send_event = xevent.xany.send_event; - - if (gdk_event_translate (event, &xevent)) - return event; - else - gdk_event_free (event); - } - - return NULL; -} - -void -gdk_event_put (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_if_fail (event != NULL); - - new_event = gdk_event_copy (event); - - putback_events = g_list_prepend (putback_events, new_event); -} - -/* - *-------------------------------------------------------------- - * gdk_event_copy - * - * Copy a event structure into new storage. - * - * Arguments: - * "event" is the event struct to copy. - * - * Results: - * A new event structure. Free it with gdk_event_free. - * - * Side effects: - * The reference count of the window in the event is increased. - * - *-------------------------------------------------------------- - */ - -static GMemChunk *event_chunk; - -static GdkEvent* -gdk_event_new (void) -{ - GdkEvent *new_event; - - if (event_chunk == NULL) - event_chunk = g_mem_chunk_new ("events", - sizeof (GdkEvent), - 4096, - G_ALLOC_AND_FREE); - - new_event = g_chunk_new (GdkEvent, event_chunk); - - return new_event; -} - -GdkEvent* -gdk_event_copy (GdkEvent *event) -{ - GdkEvent *new_event; - - g_return_val_if_fail (event != NULL, NULL); - - new_event = gdk_event_new (); - - *new_event = *event; - gdk_window_ref (new_event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - new_event->key.string = g_strdup (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_ref (event->crossing.subwindow); - break; - - case GDK_DROP_DATA_AVAIL: - new_event->dropdataavailable.data_type = g_strdup (event->dropdataavailable.data_type); - new_event->dropdataavailable.data = g_malloc (event->dropdataavailable.data_numbytes); - memcpy (new_event->dropdataavailable.data, - event->dropdataavailable.data, - event->dropdataavailable.data_numbytes); - break; - - default: - break; - } - - return new_event; -} - -/* - *-------------------------------------------------------------- - * gdk_event_free - * - * Free a event structure obtained from gdk_event_copy. Do not use - * with other event structures. - * - * Arguments: - * "event" is the event struct to free. - * - * Results: - * - * Side effects: - * The reference count of the window in the event is decreased and - * might be freed, too. - * - *-------------------------------------------------------------- */ - -void -gdk_event_free (GdkEvent *event) -{ - g_assert (event_chunk != NULL); - g_return_if_fail (event != NULL); - - if (event->any.window) - gdk_window_unref (event->any.window); - - switch (event->any.type) - { - case GDK_KEY_PRESS: - case GDK_KEY_RELEASE: - g_free (event->key.string); - break; - - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - if (event->crossing.subwindow != NULL) - gdk_window_unref (event->crossing.subwindow); - break; - - case GDK_DROP_DATA_AVAIL: - g_free (event->dropdataavailable.data_type); - g_free (event->dropdataavailable.data); - break; - - case GDK_DRAG_REQUEST: - g_free (event->dragrequest.data_type); - break; - - default: - break; - } - - g_mem_chunk_free (event_chunk, event); -} - -/* - *-------------------------------------------------------------- - * gdk_set_show_events - * - * Turns on/off the showing of events. - * - * Arguments: - * "show_events" is a boolean describing whether or - * not to show the events gdk receives. - * - * Results: - * - * Side effects: - * When "show_events" is TRUE, calls to "gdk_event_get" - * will output debugging informatin regarding the event - * received to stdout. - * - *-------------------------------------------------------------- - */ - -void -gdk_set_show_events (int show_events) -{ - if (show_events) - gdk_debug_flags |= GDK_DEBUG_EVENTS; - else - gdk_debug_flags &= ~GDK_DEBUG_EVENTS; -} - -void -gdk_set_use_xshm (gint use_xshm) -{ - gdk_use_xshm = use_xshm; -} - -gint -gdk_get_show_events (void) -{ - return gdk_debug_flags & GDK_DEBUG_EVENTS; -} - -gint -gdk_get_use_xshm (void) -{ - return gdk_use_xshm; -} - -/* - *-------------------------------------------------------------- - * gdk_time_get - * - * Get the number of milliseconds since the library was - * initialized. - * - * Arguments: - * - * Results: - * The time since the library was initialized is returned. - * This time value is accurate to milliseconds even though - * a more accurate time down to the microsecond could be - * returned. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -guint32 -gdk_time_get (void) -{ - struct timeval end; - struct timeval elapsed; - guint32 milliseconds; - - X_GETTIMEOFDAY (&end); - - if (start.tv_usec > end.tv_usec) - { - end.tv_usec += 1000000; - end.tv_sec--; - } - elapsed.tv_sec = end.tv_sec - start.tv_sec; - elapsed.tv_usec = end.tv_usec - start.tv_usec; - - milliseconds = (elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000); - - return milliseconds; -} - -/* - *-------------------------------------------------------------- - * gdk_timer_get - * - * Returns the current timer. - * - * Arguments: - * - * Results: - * Returns the current timer interval. This interval is - * in units of milliseconds. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -guint32 -gdk_timer_get (void) -{ - return timer_val; -} - -/* - *-------------------------------------------------------------- - * gdk_timer_set - * - * Sets the timer interval. - * - * Arguments: - * "milliseconds" is the new value for the timer. - * - * Results: - * - * Side effects: - * Calls to "gdk_event_get" will last for a maximum - * of time of "milliseconds". However, a value of 0 - * milliseconds will cause "gdk_event_get" to block - * indefinately until an event is received. - * - *-------------------------------------------------------------- - */ - -void -gdk_timer_set (guint32 milliseconds) -{ - timer_val = milliseconds; - timer.tv_sec = milliseconds / 1000; - timer.tv_usec = (milliseconds % 1000) * 1000; - -} - -void -gdk_timer_enable (void) -{ - timerp = &timer; -} - -void -gdk_timer_disable (void) -{ - timerp = NULL; -} - -gint -gdk_input_add_full (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data, - GdkDestroyNotify destroy) -{ - static gint next_tag = 1; - GList *list; - GdkInput *input; - gint tag; - - tag = 0; - list = inputs; - - while (list) - { - input = list->data; - list = list->next; - - if ((input->source == source) && (input->condition == condition)) - { - if (input->destroy) - (input->destroy) (input->data); - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - } - } - - if (!tag) - { - input = g_new (GdkInput, 1); - input->tag = next_tag++; - input->source = source; - input->condition = condition; - input->function = function; - input->data = data; - input->destroy = destroy; - tag = input->tag; - - inputs = g_list_prepend (inputs, input); - } - - return tag; -} - -gint -gdk_input_add (gint source, - GdkInputCondition condition, - GdkInputFunction function, - gpointer data) -{ - return gdk_input_add_interp (source, condition, function, data, NULL); -} - -void -gdk_input_remove (gint tag) -{ - GList *list; - GList *temp_list; - GdkInput *input; - - list = inputs; - while (list) - { - input = list->data; - - if (input->tag == tag) - { - if (input->destroy) - (input->destroy) (input->data); - - temp_list = list; - - if (list->next) - list->next->prev = list->prev; - if (list->prev) - list->prev->next = list->next; - if (inputs == list) - inputs = list->next; - - temp_list->next = NULL; - temp_list->prev = NULL; - - g_free (temp_list->data); - g_list_free (temp_list); - break; - } - - list = list->next; - } -} - -/* - *-------------------------------------------------------------- - * gdk_pointer_grab - * - * Grabs the pointer to a specific window - * - * Arguments: - * "window" is the window which will receive the grab - * "owner_events" specifies whether events will be reported as is, - * or relative to "window" - * "event_mask" masks only interesting events - * "confine_to" limits the cursor movement to the specified window - * "cursor" changes the cursor for the duration of the grab - * "time" specifies the time - * - * Results: - * - * Side effects: - * requires a corresponding call to gdk_pointer_ungrab - * - *-------------------------------------------------------------- - */ - -gint -gdk_pointer_grab (GdkWindow * window, - gint owner_events, - GdkEventMask event_mask, - GdkWindow * confine_to, - GdkCursor * cursor, - guint32 time) -{ - /* From gdkwindow.c */ - extern int nevent_masks; - extern int event_mask_table[]; - - gint return_val; - GdkWindowPrivate *window_private; - GdkWindowPrivate *confine_to_private; - GdkCursorPrivate *cursor_private; - guint xevent_mask; - Window xwindow; - Window xconfine_to; - Cursor xcursor; - int i; - - g_return_val_if_fail (window != NULL, 0); - - window_private = (GdkWindowPrivate*) window; - confine_to_private = (GdkWindowPrivate*) confine_to; - cursor_private = (GdkCursorPrivate*) cursor; - - xwindow = window_private->xwindow; - - if (!confine_to || confine_to_private->destroyed) - xconfine_to = None; - else - xconfine_to = confine_to_private->xwindow; - - if (!cursor) - xcursor = None; - else - xcursor = cursor_private->xcursor; - - - xevent_mask = 0; - for (i = 0; i < nevent_masks; i++) - { - if (event_mask & (1 << (i + 1))) - xevent_mask |= event_mask_table[i]; - } - - if (((GdkWindowPrivate *)window)->extension_events && - gdk_input_vtable.grab_pointer) - return_val = gdk_input_vtable.grab_pointer (window, - owner_events, - event_mask, - confine_to, - time); - else - return_val = Success; - - if (return_val == Success) - { - if (!window_private->destroyed) - return_val = XGrabPointer (window_private->xdisplay, - xwindow, - owner_events, - xevent_mask, - GrabModeAsync, GrabModeAsync, - xconfine_to, - xcursor, - time); - else - return_val = AlreadyGrabbed; - } - - if (return_val == GrabSuccess) - xgrab_window = window_private; - - return return_val; -} - -/* - *-------------------------------------------------------------- - * gdk_pointer_ungrab - * - * Releases any pointer grab - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void -gdk_pointer_ungrab (guint32 time) -{ - if (gdk_input_vtable.ungrab_pointer) - gdk_input_vtable.ungrab_pointer (time); - - XUngrabPointer (gdk_display, time); - xgrab_window = NULL; -} - -/* - *-------------------------------------------------------------- - * gdk_pointer_is_grabbed - * - * Tell wether there is an active x pointer grab in effect - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_pointer_is_grabbed (void) -{ - return xgrab_window != NULL; -} - -/* - *-------------------------------------------------------------- - * gdk_keyboard_grab - * - * Grabs the keyboard to a specific window - * - * Arguments: - * "window" is the window which will receive the grab - * "owner_events" specifies whether events will be reported as is, - * or relative to "window" - * "time" specifies the time - * - * Results: - * - * Side effects: - * requires a corresponding call to gdk_keyboard_ungrab - * - *-------------------------------------------------------------- - */ - -gint -gdk_keyboard_grab (GdkWindow * window, - gint owner_events, - guint32 time) -{ - GdkWindowPrivate *window_private; - Window xwindow; - - g_return_val_if_fail (window != NULL, 0); - - window_private = (GdkWindowPrivate*) window; - xwindow = window_private->xwindow; - - if (!window_private->destroyed) - return XGrabKeyboard (window_private->xdisplay, - xwindow, - owner_events, - GrabModeAsync, GrabModeAsync, - time); - else - return AlreadyGrabbed; -} - -/* - *-------------------------------------------------------------- - * gdk_keyboard_ungrab - * - * Releases any keyboard grab - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void -gdk_keyboard_ungrab (guint32 time) -{ - XUngrabKeyboard (gdk_display, time); -} - -/* - *-------------------------------------------------------------- - * gdk_screen_width - * - * Return the width of the screen. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_screen_width (void) -{ - gint return_val; - - return_val = DisplayWidth (gdk_display, gdk_screen); - - return return_val; -} - -/* - *-------------------------------------------------------------- - * gdk_screen_height - * - * Return the height of the screen. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_screen_height (void) -{ - gint return_val; - - return_val = DisplayHeight (gdk_display, gdk_screen); - - return return_val; -} - -/* - *-------------------------------------------------------------- - * gdk_screen_width_mm - * - * Return the width of the screen in millimeters. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_screen_width_mm (void) -{ - gint return_val; - - return_val = DisplayWidthMM (gdk_display, gdk_screen); - - return return_val; -} - -/* - *-------------------------------------------------------------- - * gdk_screen_height - * - * Return the height of the screen in millimeters. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -gint -gdk_screen_height_mm (void) -{ - gint return_val; - - return_val = DisplayHeightMM (gdk_display, gdk_screen); - - return return_val; -} - -void -gdk_key_repeat_disable (void) -{ - XAutoRepeatOff (gdk_display); -} - -void -gdk_key_repeat_restore (void) -{ - if (autorepeat) - XAutoRepeatOn (gdk_display); - else - XAutoRepeatOff (gdk_display); -} - - -/* - *-------------------------------------------------------------- - * gdk_flush - * - * Flushes the Xlib output buffer and then waits - * until all requests have been received and processed - * by the X server. The only real use for this function - * is in dealing with XShm. - * - * Arguments: - * - * Results: - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void gdk_flush (void) -{ - XSync (gdk_display, False); -} - - -void -gdk_beep (void) -{ - XBell(gdk_display, 100); -} - - -/* - *-------------------------------------------------------------- - * gdk_event_wait - * - * Waits until an event occurs or the timer runs out. - * - * Arguments: - * - * Results: - * Returns TRUE if an event is ready to be read and FALSE - * if the timer ran out. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static gint -gdk_event_wait (void) -{ - GList *list; - GdkInput *input; - GdkInputCondition condition; - SELECT_MASK readfds; - SELECT_MASK writefds; - SELECT_MASK exceptfds; - int max_input; - int nfd; - - /* If there are no events pending we will wait for an event. - * The time we wait is dependant on the "timer". If no timer - * has been specified then we'll block until an event arrives. - * If a timer has been specified we'll block until an event - * arrives or the timer expires. (This is all done using the - * "select" system call). - */ - - if (XPending (gdk_display) == 0) - { - FD_ZERO (&readfds); - FD_ZERO (&writefds); - FD_ZERO (&exceptfds); - - FD_SET (connection_number, &readfds); - max_input = connection_number; - - list = inputs; - while (list) - { - input = list->data; - list = list->next; - - if (input->condition & GDK_INPUT_READ) - FD_SET (input->source, &readfds); - if (input->condition & GDK_INPUT_WRITE) - FD_SET (input->source, &writefds); - if (input->condition & GDK_INPUT_EXCEPTION) - FD_SET (input->source, &exceptfds); - - max_input = MAX (max_input, input->source); - } - -#ifdef USE_PTHREADS - if (gdk_using_threads) - { - gdk_select_waiting = TRUE; - - FD_SET (gdk_threads_pipe[0], &readfds); - max_input = MAX (max_input, gdk_threads_pipe[0]); - gdk_threads_leave (); - } -#endif - - nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp); - -#ifdef USE_PTHREADS - if (gdk_using_threads) - { - gchar c; - gdk_threads_enter (); - gdk_select_waiting = FALSE; - - if (FD_ISSET (gdk_threads_pipe[0], &readfds)) - read (gdk_threads_pipe[0], &c, 1); - } -#endif - - timerp = NULL; - timer_val = 0; - - if (nfd > 0) - { - if (FD_ISSET (connection_number, &readfds)) - { - if (XPending (gdk_display) == 0) - { - if (nfd == 1) - { - XNoOp (gdk_display); - XFlush (gdk_display); - } - return FALSE; - } - else - return TRUE; - } - - list = inputs; - while (list) - { - input = list->data; - list = list->next; - - condition = 0; - if (FD_ISSET (input->source, &readfds)) - condition |= GDK_INPUT_READ; - if (FD_ISSET (input->source, &writefds)) - condition |= GDK_INPUT_WRITE; - if (FD_ISSET (input->source, &exceptfds)) - condition |= GDK_INPUT_EXCEPTION; - - if (condition && input->function) - (* input->function) (input->data, input->source, condition); - } - } - } - else - return TRUE; - - return FALSE; -} - -static gint -gdk_event_apply_filters (XEvent *xevent, - GdkEvent *event, - GList *filters) -{ - GdkEventFilter *filter; - GList *tmp_list; - GdkFilterReturn result; - - tmp_list = filters; - - while (tmp_list) - { - filter = (GdkEventFilter *)tmp_list->data; - - result = (*filter->function)(xevent, event, filter->data); - if (result != GDK_FILTER_CONTINUE) - return result; - - tmp_list = tmp_list->next; - } - - return GDK_FILTER_CONTINUE; -} - -static gint -gdk_event_translate (GdkEvent *event, - XEvent *xevent) -{ - - GdkWindow *window; - GdkWindowPrivate *window_private; - static XComposeStatus compose; - KeySym keysym; - int charcount; -#ifdef USE_XIM - static gchar* buf = NULL; - static gint buf_len= 0; -#else - char buf[16]; -#endif - gint return_val; - - return_val = FALSE; - - /* We need to play catch-up with the dnd motion events */ - if(gdk_dnd.drag_really && xevent->type == MotionNotify) - while (XCheckTypedEvent(xevent->xany.display,MotionNotify,xevent)); - - /* Find the GdkWindow that this event occurred in. - * All events occur in some GdkWindow (otherwise, why - * would we be receiving them). It really is an error - * to receive an event for which we cannot find the - * corresponding GdkWindow. We handle events with window=None - * specially - they are generated by XFree86's XInput under - * some circumstances. - */ - - if ((xevent->xany.window == None) && - gdk_input_vtable.window_none_event) - { - return_val = gdk_input_vtable.window_none_event (event,xevent); - - if (return_val >= 0) /* was handled */ - return return_val; - else - return_val = FALSE; - } - - window = gdk_window_lookup (xevent->xany.window); - window_private = (GdkWindowPrivate *) window; - - if (window != NULL) - gdk_window_ref (window); - else if(gdk_null_window_warnings) /* Special purpose programs that - get events for other windows may - want to disable this */ - g_warning ("%#lx -> NULL\n", xevent->xany.window); - - /* Check for filters for this window */ - - { - GdkFilterReturn result; - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - if (result != GDK_FILTER_CONTINUE) - { - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - } - - /* We do a "manual" conversion of the XEvent to a - * GdkEvent. The structures are mostly the same so - * the conversion is fairly straightforward. We also - * optionally print debugging info regarding events - * received. - */ - /* Addendum: - * During drag & drop you get events where the pointer is - * in other windows. Need to just do finer-grained checking - */ - switch (xevent->type) - { - case KeyPress: - /* Lookup the string corresponding to the given keysym. - */ -#ifdef USE_XIM - if (buf_len == 0) - { - buf_len = 128; - buf = g_new (gchar, buf_len); - } - keysym = GDK_VoidSymbol; - - if (xim_using == TRUE && xim_ic) - { - Status status; - - /* Clear keyval. Depending on status, may not be set */ - charcount = XmbLookupString(xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - &keysym, &status); - if (status == XBufferOverflow) - { /* retry */ - /* alloc adequate size of buffer */ - GDK_NOTE (XIM, - g_print("XIM: overflow (required %i)\n", charcount)); - - while (buf_len <= charcount) - buf_len *= 2; - buf = (gchar *) g_realloc (buf, buf_len); - - charcount = XmbLookupString (xim_ic->xic, - &xevent->xkey, buf, buf_len-1, - &keysym, &status); - } - if (status == XLookupNone) - { - return_val = FALSE; - break; - } - } - else - charcount = XLookupString (&xevent->xkey, buf, buf_len, - &keysym, &compose); -#else - charcount = XLookupString (&xevent->xkey, buf, 16, - &keysym, &compose); -#endif - event->key.keyval = keysym; - - if (charcount > 0 && buf[charcount-1] == '\0') - charcount --; - else - buf[charcount] = '\0'; - - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - { - g_print ("key press:\twindow: %ld key: %12s %d\n", - xevent->xkey.window - base_id, - event->key.keyval ? XKeysymToString (event->key.keyval) : "(none)", - event->key.keyval); - if (charcount > 0) - g_print ("\t\tlength: %4d string: \"%s\"\n", - charcount, buf); - } -#endif /* G_ENABLE_DEBUG */ - - event->key.type = GDK_KEY_PRESS; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.string = g_strdup (buf); - event->key.length = charcount; - - return_val = window_private && !window_private->destroyed; - - if (!return_val) - g_free (event->key.string); - - break; - - case KeyRelease: - /* Lookup the string corresponding to the given keysym. - */ - keysym = GDK_VoidSymbol; - charcount = XLookupString (&xevent->xkey, buf, 16, - &keysym, &compose); - event->key.keyval = keysym; - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("key release:\t\twindow: %ld key: %12s %d\n", - xevent->xkey.window - base_id, - XKeysymToString (event->key.keyval), - event->key.keyval)); - - event->key.type = GDK_KEY_RELEASE; - event->key.window = window; - event->key.time = xevent->xkey.time; - event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.length = 0; - event->key.string = NULL; - - return_val = window_private && !window_private->destroyed; - break; - - case ButtonPress: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("button press[%d]:\t\twindow: %ld x,y: %d %d button: %d\n", - window_private?window_private->dnd_drag_enabled:0, - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - break; - - event->button.type = GDK_BUTTON_PRESS; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) && - (event->button.window == button_window[1]) && - (event->button.button == button_number[1])) - { - gdk_synthesize_click (event, 3); - - button_click_time[1] = 0; - button_click_time[0] = 0; - button_window[1] = NULL; - button_window[0] = 0; - button_number[1] = -1; - button_number[0] = -1; - } - else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) && - (event->button.window == button_window[0]) && - (event->button.button == button_number[0])) - { - gdk_synthesize_click (event, 2); - - button_click_time[1] = button_click_time[0]; - button_click_time[0] = event->button.time; - button_window[1] = button_window[0]; - button_window[0] = event->button.window; - button_number[1] = button_number[0]; - button_number[0] = event->button.button; - } - else - { - button_click_time[1] = 0; - button_click_time[0] = event->button.time; - button_window[1] = NULL; - button_window[0] = event->button.window; - button_number[1] = -1; - button_number[0] = event->button.button; - } - if(window_private - && window_private->dnd_drag_enabled - && !gdk_dnd.drag_perhaps - && event->button.button == 1 - && !gdk_dnd.drag_really) - { - gdk_dnd.drag_perhaps = 1; - gdk_dnd.dnd_drag_start.x = xevent->xbutton.x_root; - gdk_dnd.dnd_drag_start.y = xevent->xbutton.y_root; - gdk_dnd.real_sw = window_private; - - if(gdk_dnd.drag_startwindows) - { - g_free(gdk_dnd.drag_startwindows); - gdk_dnd.drag_startwindows = NULL; - } - gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0; - gdk_dnd.dnd_grabbed = FALSE; - - { - /* Set motion mask for first DnD'd window, since it - will be the one that is actually dragged */ - XWindowAttributes dnd_winattr; - XSetWindowAttributes dnd_setwinattr; - - /* We need to get motion events while the button is down, so - we can know whether to really start dragging or not... */ - XGetWindowAttributes(gdk_display, (Window)window_private->xwindow, - &dnd_winattr); - - window_private->dnd_drag_savedeventmask = dnd_winattr.your_event_mask; - dnd_setwinattr.event_mask = - window_private->dnd_drag_eventmask = ButtonMotionMask | ButtonPressMask | ButtonReleaseMask | - EnterWindowMask | LeaveWindowMask | ExposureMask; - XChangeWindowAttributes(gdk_display, window_private->xwindow, - CWEventMask, &dnd_setwinattr); - } - } - return_val = window_private && !window_private->destroyed; - break; - - case ButtonRelease: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("button release[%d]:\twindow: %ld x,y: %d %d button: %d\n", - window_private?window_private->dnd_drag_enabled:0, - xevent->xbutton.window - base_id, - xevent->xbutton.x, xevent->xbutton.y, - xevent->xbutton.button)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - break; - - event->button.type = GDK_BUTTON_RELEASE; - event->button.window = window; - event->button.time = xevent->xbutton.time; - event->button.x = xevent->xbutton.x; - event->button.y = xevent->xbutton.y; - event->button.x_root = (gfloat)xevent->xbutton.x_root; - event->button.y_root = (gfloat)xevent->xbutton.y_root; - event->button.pressure = 0.5; - event->button.xtilt = 0; - event->button.ytilt = 0; - event->button.state = (GdkModifierType) xevent->xbutton.state; - event->button.button = xevent->xbutton.button; - event->button.source = GDK_SOURCE_MOUSE; - event->button.deviceid = GDK_CORE_POINTER; - - gdk_dnd.last_drop_time = xevent->xbutton.time; - if(gdk_dnd.drag_perhaps) - { - { - XSetWindowAttributes attrs; - /* Reset event mask to pre-drag value, assuming event_mask - doesn't change during drag */ - attrs.event_mask = gdk_dnd.real_sw->dnd_drag_savedeventmask; - XChangeWindowAttributes(gdk_display, gdk_dnd.real_sw->xwindow, - CWEventMask, &attrs); - } - - if (gdk_dnd.dnd_grabbed) - { - gdk_dnd_display_drag_cursor(-2, - -2, - FALSE, TRUE); - XUngrabPointer(gdk_display, CurrentTime); - gdk_dnd.dnd_grabbed = FALSE; - } - - if(gdk_dnd.drag_really) - { - GdkPoint foo; - foo.x = xevent->xbutton.x_root; - foo.y = xevent->xbutton.y_root; - - if(gdk_dnd.dnd_drag_target != None) - gdk_dnd_drag_end(gdk_dnd.dnd_drag_target, foo); - gdk_dnd.drag_really = 0; - - gdk_dnd.drag_numwindows = 0; - if(gdk_dnd.drag_startwindows) - { - g_free(gdk_dnd.drag_startwindows); - gdk_dnd.drag_startwindows = NULL; - } - - gdk_dnd.real_sw = NULL; - } - - gdk_dnd.drag_perhaps = 0; - gdk_dnd.dnd_drag_start.x = gdk_dnd.dnd_drag_start.y = 0; - gdk_dnd.dnd_drag_dropzone.x = gdk_dnd.dnd_drag_dropzone.y = 0; - gdk_dnd.dnd_drag_dropzone.width = gdk_dnd.dnd_drag_dropzone.height = 0; - gdk_dnd.dnd_drag_curwin = None; - return_val = window_private?TRUE:FALSE; - } else - return_val = window_private && !window_private->destroyed; - break; - - case MotionNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s d:%d r%d\n", - xevent->xmotion.window - base_id, - xevent->xmotion.x, xevent->xmotion.y, - (xevent->xmotion.is_hint) ? "true" : "false", - gdk_dnd.drag_perhaps, gdk_dnd.drag_really)); - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_ignore_core) - break; - - event->motion.type = GDK_MOTION_NOTIFY; - event->motion.window = window; - event->motion.time = xevent->xmotion.time; - event->motion.x = xevent->xmotion.x; - event->motion.y = xevent->xmotion.y; - event->motion.x_root = (gfloat)xevent->xmotion.x_root; - event->motion.y_root = (gfloat)xevent->xmotion.y_root; - event->motion.pressure = 0.5; - event->motion.xtilt = 0; - event->motion.ytilt = 0; - event->motion.state = (GdkModifierType) xevent->xmotion.state; - event->motion.is_hint = xevent->xmotion.is_hint; - event->motion.source = GDK_SOURCE_MOUSE; - event->motion.deviceid = GDK_CORE_POINTER; - -#define IS_IN_ZONE(cx, cy) (cx >= gdk_dnd.dnd_drag_dropzone.x \ - && cy >= gdk_dnd.dnd_drag_dropzone.y \ - && cx < (gdk_dnd.dnd_drag_dropzone.x + gdk_dnd.dnd_drag_dropzone.width) \ - && cy < (gdk_dnd.dnd_drag_dropzone.y + gdk_dnd.dnd_drag_dropzone.height)) - - if(gdk_dnd.drag_perhaps && gdk_dnd.drag_really - /* && event->motion.is_hint */ /* HINTME */) - { - /* First, we have to find what window the motion was in... */ - /* XXX there has to be a better way to do this, perhaps with - XTranslateCoordinates or XQueryTree - I don't know how, - and this sort of works */ - static Window lastwin = None, curwin = None; -#if 0 - Window twin; -#endif - Window childwin = gdk_root_window; - int x, y, ox, oy; - - /* Interlude - display cursor for the drag ASAP */ - gdk_dnd_display_drag_cursor(xevent->xmotion.x_root, - xevent->xmotion.y_root, - gdk_dnd.dnd_drag_target?TRUE:FALSE, - FALSE); - - lastwin = curwin; - curwin = gdk_root_window; - ox = x = xevent->xmotion.x_root; - oy = y = xevent->xmotion.y_root; -#if 1 - curwin = gdk_window_xid_at_coords(xevent->xmotion.x_root, - xevent->xmotion.y_root, - gdk_dnd.c->xids,TRUE); - XTranslateCoordinates(gdk_display, gdk_root_window, curwin, - x, y, &x, &y, &childwin); -#else - while(childwin != None) - { - ox = x; oy = y; - curwin = childwin; - XTranslateCoordinates(gdk_display, curwin, curwin, - x, y, &x, &y, &childwin); - if(childwin != None) - { - XTranslateCoordinates(gdk_display, curwin, childwin, - x, y, &x, &y, &twin); - } - } -#endif - GDK_NOTE (DND, - g_print("Drag is now in window %#lx, lastwin was %#lx, ddc = %#lx\n", - curwin, lastwin, gdk_dnd.dnd_drag_curwin)); - if(curwin != gdk_dnd.dnd_drag_curwin && curwin != lastwin) - { - /* We have left one window and entered another - (do leave & enter bits) */ - if(gdk_dnd.dnd_drag_curwin != None) - gdk_dnd_drag_leave(gdk_dnd.dnd_drag_curwin); - gdk_dnd.dnd_drag_curwin = curwin; - gdk_dnd_drag_enter(gdk_dnd.dnd_drag_curwin); - gdk_dnd.dnd_drag_dropzone.x = gdk_dnd.dnd_drag_dropzone.y = 0; - gdk_dnd.dnd_drag_dropzone.width = gdk_dnd.dnd_drag_dropzone.height = 0; - gdk_dnd.dnd_drag_target = None; - GDK_NOTE (DND, - g_print("curwin = %#lx, lastwin = %#lx, dnd_drag_curwin = %#lx\n", - curwin, lastwin, gdk_dnd.dnd_drag_curwin)); - - gdk_dnd_display_drag_cursor(xevent->xmotion.x_root, - xevent->xmotion.y_root, - FALSE, TRUE); - } - else if(gdk_dnd.dnd_drag_dropzone.width > 0 - && gdk_dnd.dnd_drag_dropzone.height > 0 - && curwin == gdk_dnd.dnd_drag_curwin) - { - /* Handle all that dropzone stuff - thanks John ;-) */ - if (gdk_dnd.dnd_drag_target != None) - { - gboolean in_zone = IS_IN_ZONE(xevent->xmotion.x_root, - xevent->xmotion.y_root); - gboolean old_in_zone = IS_IN_ZONE(gdk_dnd.dnd_drag_oldpos.x, - gdk_dnd.dnd_drag_oldpos.y); - - if (!in_zone && old_in_zone) - { - /* We were in the drop zone and moved out */ - gdk_dnd.dnd_drag_target = None; - gdk_dnd_drag_leave(curwin); - gdk_dnd_display_drag_cursor(xevent->xmotion.x_root, - xevent->xmotion.y_root, - FALSE, TRUE); - } - else if (!in_zone && !old_in_zone) - { - /* We were outside drop zone but in the window - - have to send enter events */ - gdk_dnd_drag_enter(curwin); - gdk_dnd.dnd_drag_curwin = curwin; - gdk_dnd.dnd_drag_dropzone.x = gdk_dnd.dnd_drag_dropzone.y = 0; - gdk_dnd.dnd_drag_target = None; - } - } - } /* else - dnd_drag_curwin = None; */ - return_val = FALSE; - } - else - return_val = window_private && !window_private->destroyed; - break; - - case EnterNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("enter notify:\t\twindow: %ld detail: %d subwin: %ld\n", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, - xevent->xcrossing.subwindow - base_id)); - - /* Tell XInput stuff about it if appropriate */ - if (window_private && - (window_private->extension_events != 0) && - gdk_input_vtable.enter_event) - gdk_input_vtable.enter_event (&xevent->xcrossing, window); - - event->crossing.type = GDK_ENTER_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.x_root = xevent->xcrossing.x_root; - event->crossing.y_root = xevent->xcrossing.y_root; - - /* Translate the crossing mode into Gdk terms. - */ - switch (xevent->xcrossing.mode) - { - case NotifyNormal: - event->crossing.mode = GDK_CROSSING_NORMAL; - break; - case NotifyGrab: - event->crossing.mode = GDK_CROSSING_GRAB; - break; - case NotifyUngrab: - event->crossing.mode = GDK_CROSSING_UNGRAB; - break; - }; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - -#ifdef G_ENABLE_DEBUG - if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps) - { - g_print("We may[%d] have a drag into %#lx = %#lx\n", - gdk_dnd.drag_really, - xevent->xcrossing.window, gdk_dnd.real_sw->xwindow); - } -#endif /* G_ENABLE_DEBUG */ - - if (gdk_dnd.drag_perhaps && gdk_dnd.drag_really && - (xevent->xcrossing.window == gdk_dnd.real_sw->xwindow)) - { -#if 0 - gdk_dnd.drag_really = 0; - - GDK_NOTE (DND, g_print("Ungrabbed\n")); - - gdk_dnd.drag_numwindows = 0; - g_free(gdk_dnd.drag_startwindows); - gdk_dnd.drag_startwindows = NULL; - /* We don't want to ungrab the pointer here, or we'll - * start getting spurious enter/leave events */ -#endif -#if 0 - XChangeActivePointerGrab (gdk_display, 0, None, CurrentTime); -#endif - } - - return_val = window_private && !window_private->destroyed; - break; - - case LeaveNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("leave notify:\t\twindow: %ld detail: %d subwin: %ld\n", - xevent->xcrossing.window - base_id, - xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id)); - - event->crossing.type = GDK_LEAVE_NOTIFY; - event->crossing.window = window; - - /* If the subwindow field of the XEvent is non-NULL, then - * lookup the corresponding GdkWindow. - */ - if (xevent->xcrossing.subwindow != None) - event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow); - else - event->crossing.subwindow = NULL; - - event->crossing.time = xevent->xcrossing.time; - event->crossing.x = xevent->xcrossing.x; - event->crossing.y = xevent->xcrossing.y; - event->crossing.x_root = xevent->xcrossing.x_root; - event->crossing.y_root = xevent->xcrossing.y_root; - - /* Translate the crossing mode into Gdk terms. - */ - switch (xevent->xcrossing.mode) - { - case NotifyNormal: - event->crossing.mode = GDK_CROSSING_NORMAL; - break; - case NotifyGrab: - event->crossing.mode = GDK_CROSSING_GRAB; - break; - case NotifyUngrab: - event->crossing.mode = GDK_CROSSING_UNGRAB; - break; - }; - - /* Translate the crossing detail into Gdk terms. - */ - switch (xevent->xcrossing.detail) - { - case NotifyInferior: - event->crossing.detail = GDK_NOTIFY_INFERIOR; - break; - case NotifyAncestor: - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - break; - case NotifyVirtual: - event->crossing.detail = GDK_NOTIFY_VIRTUAL; - break; - case NotifyNonlinear: - event->crossing.detail = GDK_NOTIFY_NONLINEAR; - break; - case NotifyNonlinearVirtual: - event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; - break; - default: - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - break; - } - - event->crossing.focus = xevent->xcrossing.focus; - event->crossing.state = xevent->xcrossing.state; - -#ifdef G_ENABLE_DEBUG - if ((gdk_debug_flags & GDK_DEBUG_DND) & gdk_dnd.drag_perhaps) - { - g_print("We may[%d] have a drag out of %#lx = %#lx\n", - gdk_dnd.drag_really, - xevent->xcrossing.window, gdk_dnd.real_sw->xwindow); - } -#endif /* G_ENABLE_DEBUG */ - if (gdk_dnd.drag_perhaps && !gdk_dnd.drag_really && - (xevent->xcrossing.window == gdk_dnd.real_sw->xwindow)) - { - gboolean xgpret; - gdk_dnd_drag_addwindow((GdkWindow *) gdk_dnd.real_sw); - gdk_dnd_drag_begin((GdkWindow *) gdk_dnd.real_sw); - xgpret = - XGrabPointer(gdk_display, gdk_dnd.real_sw->xwindow, False, - ButtonMotionMask | PointerMotionMask | - /* PointerMotionHintMask | */ /* HINTME */ - ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, None, - None, CurrentTime); -#ifdef G_ENABLE_DEBUG - GDK_NOTE(DND, g_print("xgpret = %d\n", xgpret)); -#endif - gdk_dnd.dnd_grabbed = TRUE; - gdk_dnd.drag_really = 1; - gdk_dnd_display_drag_cursor(xevent->xmotion.x_root, - xevent->xmotion.y_root, - FALSE, TRUE); - } - - return_val = window_private && !window_private->destroyed; - break; - - case FocusIn: - case FocusOut: - /* We only care about focus events that indicate that _this_ - * window (not a ancestor or child) got or lost the focus - */ - switch (xevent->xfocus.detail) - { - case NotifyAncestor: - case NotifyInferior: - case NotifyNonlinear: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("focus %s:\t\twindow: %ld\n", - (xevent->xany.type == FocusIn) ? "in" : "out", - xevent->xfocus.window - base_id)); - - event->focus_change.type = GDK_FOCUS_CHANGE; - event->focus_change.window = window; - event->focus_change.in = (xevent->xany.type == FocusIn); - - return_val = window_private && !window_private->destroyed; - break; - default: - ; - } - break; - - case KeymapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("keymap notify\n")); - - /* Not currently handled */ - break; - - case Expose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d\n", - xevent->xexpose.window - base_id, xevent->xexpose.count, - xevent->xexpose.x, xevent->xexpose.y, - xevent->xexpose.width, xevent->xexpose.height)); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xexpose.x; - event->expose.area.y = xevent->xexpose.y; - event->expose.area.width = xevent->xexpose.width; - event->expose.area.height = xevent->xexpose.height; - event->expose.count = xevent->xexpose.count; - - return_val = window_private && !window_private->destroyed; - break; - - case GraphicsExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("graphics expose:\tdrawable: %ld\n", - xevent->xgraphicsexpose.drawable - base_id)); - - event->expose.type = GDK_EXPOSE; - event->expose.window = window; - event->expose.area.x = xevent->xgraphicsexpose.x; - event->expose.area.y = xevent->xgraphicsexpose.y; - event->expose.area.width = xevent->xgraphicsexpose.width; - event->expose.area.height = xevent->xgraphicsexpose.height; - event->expose.count = xevent->xexpose.count; - - return_val = window_private && !window_private->destroyed; - break; - - case NoExpose: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("no expose:\t\tdrawable: %ld\n", - xevent->xnoexpose.drawable - base_id)); - - event->no_expose.type = GDK_NO_EXPOSE; - event->no_expose.window = window; - - return_val = window_private && !window_private->destroyed; - break; - - case VisibilityNotify: - /* Print debugging info. - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & GDK_DEBUG_EVENTS) - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - g_print ("visibility notify:\twindow: %ld none\n", - xevent->xvisibility.window - base_id); - break; - case VisibilityPartiallyObscured: - g_print ("visibility notify:\twindow: %ld partial\n", - xevent->xvisibility.window - base_id); - break; - case VisibilityUnobscured: - g_print ("visibility notify:\twindow: %ld full\n", - xevent->xvisibility.window - base_id); - break; - } -#endif /* G_ENABLE_DEBUG */ - - event->visibility.type = GDK_VISIBILITY_NOTIFY; - event->visibility.window = window; - - switch (xevent->xvisibility.state) - { - case VisibilityFullyObscured: - event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED; - break; - - case VisibilityPartiallyObscured: - event->visibility.state = GDK_VISIBILITY_PARTIAL; - break; - - case VisibilityUnobscured: - event->visibility.state = GDK_VISIBILITY_UNOBSCURED; - break; - } - - return_val = window_private && !window_private->destroyed; - break; - - case CreateNotify: - /* Not currently handled */ - break; - - case DestroyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("destroy notify:\twindow: %ld\n", - xevent->xdestroywindow.window - base_id)); - - event->any.type = GDK_DESTROY; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - - if(window && window_private->xwindow != GDK_ROOT_WINDOW()) - gdk_window_destroy_notify (window); - break; - - case UnmapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("unmap notify:\t\twindow: %ld\n", - xevent->xmap.window - base_id)); - - event->any.type = GDK_UNMAP; - event->any.window = window; - - if (xgrab_window == window_private) - xgrab_window = NULL; - - return_val = window_private && !window_private->destroyed; - break; - - case MapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("map notify:\t\twindow: %ld\n", - xevent->xmap.window - base_id)); - - event->any.type = GDK_MAP; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - break; - - case ReparentNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("reparent notify:\twindow: %ld\n", - xevent->xreparent.window - base_id)); - - /* Not currently handled */ - break; - - case ConfigureNotify: - /* Print debugging info. - */ - while ((XPending (gdk_display) > 0) && - XCheckTypedWindowEvent(gdk_display, xevent->xany.window, - ConfigureNotify, xevent)) - { - GdkFilterReturn result; - - GDK_NOTE (EVENTS, - g_print ("configure notify discarded:\twindow: %ld\n", - xevent->xconfigure.window - base_id)); - - result = gdk_event_apply_filters (xevent, event, - window_private - ?window_private->filters - :gdk_default_filters); - - /* If the result is GDK_FILTER_REMOVE, there will be - * trouble, but anybody who filtering the Configure events - * better know what they are doing - */ - if (result != GDK_FILTER_CONTINUE) - { - return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; - } - - /*XSync (gdk_display, 0);*/ - } - - - GDK_NOTE (EVENTS, - g_print ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d\n", - xevent->xconfigure.window - base_id, - xevent->xconfigure.x, - xevent->xconfigure.y, - xevent->xconfigure.width, - xevent->xconfigure.height, - xevent->xconfigure.border_width, - xevent->xconfigure.above - base_id, - xevent->xconfigure.override_redirect)); - - if (window_private) - { - if ((window_private->extension_events != 0) && - gdk_input_vtable.configure_event) - gdk_input_vtable.configure_event (&xevent->xconfigure, window); - - if (window_private->window_type != GDK_WINDOW_CHILD) - { - event->configure.type = GDK_CONFIGURE; - event->configure.window = window; - event->configure.width = xevent->xconfigure.width; - event->configure.height = xevent->xconfigure.height; - - if (!xevent->xconfigure.x && - !xevent->xconfigure.y && - !window_private->destroyed) - { - gint tx = 0; - gint ty = 0; - Window child_window = 0; - - if (!XTranslateCoordinates (window_private->xdisplay, - window_private->xwindow, - gdk_root_window, - 0, 0, - &tx, &ty, - &child_window)) - g_warning ("GdkWindow %ld doesn't share root windows display?", - window_private->xwindow - base_id); - event->configure.x = tx; - event->configure.y = ty; - } - else - { - event->configure.x = xevent->xconfigure.x; - event->configure.y = xevent->xconfigure.y; - } - window_private->x = event->configure.x; - window_private->y = event->configure.y; - window_private->width = xevent->xconfigure.width; - window_private->height = xevent->xconfigure.height; - if (window_private->resize_count > 1) - window_private->resize_count -= 1; - - return_val = !window_private->destroyed; - } - } - break; - - case PropertyNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("property notify:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - event->property.type = GDK_PROPERTY_NOTIFY; - event->property.window = window; - event->property.atom = xevent->xproperty.atom; - event->property.time = xevent->xproperty.time; - event->property.state = xevent->xproperty.state; - - return_val = window_private && !window_private->destroyed; - break; - - case SelectionClear: - GDK_NOTE (EVENTS, - g_print ("selection clear:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_CLEAR; - event->selection.window = window; - event->selection.selection = xevent->xselectionclear.selection; - event->selection.time = xevent->xselectionclear.time; - - return_val = window_private && !window_private->destroyed; - break; - - case SelectionRequest: - GDK_NOTE (EVENTS, - g_print ("selection request:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - event->selection.type = GDK_SELECTION_REQUEST; - event->selection.window = window; - event->selection.selection = xevent->xselectionrequest.selection; - event->selection.target = xevent->xselectionrequest.target; - event->selection.property = xevent->xselectionrequest.property; - event->selection.requestor = xevent->xselectionrequest.requestor; - event->selection.time = xevent->xselectionrequest.time; - - return_val = window_private && !window_private->destroyed; - break; - - case SelectionNotify: - GDK_NOTE (EVENTS, - g_print ("selection notify:\twindow: %ld\n", - xevent->xproperty.window - base_id)); - - - event->selection.type = GDK_SELECTION_NOTIFY; - event->selection.window = window; - event->selection.selection = xevent->xselection.selection; - event->selection.target = xevent->xselection.target; - event->selection.property = xevent->xselection.property; - event->selection.time = xevent->xselection.time; - - return_val = window_private && !window_private->destroyed; - break; - - case ColormapNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("colormap notify:\twindow: %ld\n", - xevent->xcolormap.window - base_id)); - - /* Not currently handled */ - break; - - case ClientMessage: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("client message:\twindow: %ld\n", - xevent->xclient.window - base_id)); - - /* Client messages are the means of the window manager - * communicating with a program. We'll first check to - * see if this is really the window manager talking - * to us. - */ - if (xevent->xclient.message_type == gdk_wm_protocols) - { - if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window) - { - /* The delete window request specifies a window - * to delete. We don't actually destroy the - * window because "it is only a request". (The - * window might contain vital data that the - * program does not want destroyed). Instead - * the event is passed along to the program, - * which should then destroy the window. - */ - - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("delete window:\t\twindow: %ld\n", - xevent->xclient.window - base_id)); - - event->any.type = GDK_DELETE; - event->any.window = window; - - return_val = window_private && !window_private->destroyed; - } - else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus) - { - } - } - else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter) - { - Atom reptype = 0; - - event->dropenter.u.allflags = xevent->xclient.data.l[1]; - - GDK_NOTE (DND, g_print ("GDK_DROP_ENTER [%d][%d]\n", - window_private->dnd_drop_enabled, event->dropenter.u.flags.sendreply)); - return_val = FALSE; - - /* Now figure out if we really want this drop... - * If someone is trying funky clipboard stuff, ignore - */ - if (window_private - && window_private->dnd_drop_enabled - && event->dropenter.u.flags.sendreply - && (reptype = gdk_dnd_check_types (window, xevent))) - { - XEvent replyev; - - replyev.xclient.type = ClientMessage; - replyev.xclient.window = xevent->xclient.data.l[0]; - replyev.xclient.format = 32; - replyev.xclient.message_type = gdk_dnd.gdk_XdeRequest; - replyev.xclient.data.l[0] = window_private->xwindow; - - event->dragrequest.u.allflags = 0; - event->dragrequest.u.flags.protocol_version = - DND_PROTOCOL_VERSION; - event->dragrequest.u.flags.willaccept = 1; - event->dragrequest.u.flags.delete_data = - (window_private->dnd_drop_destructive_op) ? 1 : 0; - - replyev.xclient.data.l[1] = event->dragrequest.u.allflags; - replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0; - replyev.xclient.data.l[4] = reptype; - - if (!gdk_send_xevent (replyev.xclient.window, False, - NoEventMask, &replyev)) - GDK_NOTE (DND, g_print("Sending XdeRequest to %#lx failed\n", - replyev.xclient.window)); - - event->any.type = GDK_DROP_ENTER; - event->any.window = window; - event->dropenter.requestor = replyev.xclient.window; - event->dropenter.u.allflags = xevent->xclient.data.l[1]; - - GDK_NOTE (DND, g_print("We sent a GDK_DROP_ENTER on to Gtk\n")); - return_val = TRUE; - } - } - else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeLeave) - { -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND)) - g_print ("GDK_DROP_LEAVE\n"); -#endif - - if (window_private && window_private->dnd_drop_enabled) - { - event->dropleave.type = GDK_DROP_LEAVE; - event->dropleave.window = window; - event->dropleave.requestor = xevent->xclient.data.l[0]; - event->dropleave.u.allflags = xevent->xclient.data.l[1]; - return_val = TRUE; - } - else - return_val = FALSE; - } - else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeRequest) - { - /* - * make sure to only handle requests from the window the cursor is - * over - */ -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND)) - g_print ("GDK_DRAG_REQUEST\n"); -#endif - event->dragrequest.u.allflags = xevent->xclient.data.l[1]; - return_val = FALSE; - - if (window && gdk_dnd.drag_really && - xevent->xclient.data.l[0] == gdk_dnd.dnd_drag_curwin && - event->dragrequest.u.flags.sendreply == 0) - { - /* Got request - do we need to ask user? */ - if (!event->dragrequest.u.flags.willaccept - && event->dragrequest.u.flags.senddata) - { - /* Yes we do :) */ - event->dragrequest.type = GDK_DRAG_REQUEST; - event->dragrequest.window = window; - event->dragrequest.requestor = xevent->xclient.data.l[0]; - event->dragrequest.isdrop = 0; - event->dragrequest.drop_coords.x = - event->dragrequest.drop_coords.y = 0; - return_val = TRUE; - } - else if (event->dragrequest.u.flags.willaccept) - { - window_private->dnd_drag_destructive_op = - event->dragrequest.u.flags.delete_data; - window_private->dnd_drag_accepted = 1; - window_private->dnd_drag_data_type = - xevent->xclient.data.l[4]; - - gdk_dnd.dnd_drag_target = gdk_dnd.dnd_drag_curwin; - gdk_dnd_display_drag_cursor(-1, -1, TRUE, TRUE); - } - gdk_dnd.dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535; - gdk_dnd.dnd_drag_dropzone.y = - (xevent->xclient.data.l[2] >> 16) & 65535; - gdk_dnd.dnd_drag_dropzone.width = xevent->xclient.data.l[3] & 65535; - gdk_dnd.dnd_drag_dropzone.height = - (xevent->xclient.data.l[3] >> 16) & 65535; - } - } - else if(xevent->xclient.message_type == gdk_dnd.gdk_XdeDataAvailable) - { - gint tmp_int; Atom tmp_atom; - gulong tmp_long; - guchar *tmp_charptr; - -#ifdef G_ENABLE_DEBUG - if (gdk_debug_flags & (GDK_DEBUG_EVENTS | GDK_DEBUG_DND)) - g_print("GDK_DROP_DATA_AVAIL\n"); -#endif - event->dropdataavailable.u.allflags = xevent->xclient.data.l[1]; - event->dropdataavailable.timestamp = xevent->xclient.data.l[4]; - event->dropdataavailable.coords.x = - xevent->xclient.data.l[3] & 0xffff; - event->dropdataavailable.coords.y = - (xevent->xclient.data.l[3] >> 16) & 0xffff; - if(window - /* No preview of data ATM */ - && event->dropdataavailable.u.flags.isdrop) - { - event->dropdataavailable.type = GDK_DROP_DATA_AVAIL; - event->dropdataavailable.window = window; - event->dropdataavailable.requestor = xevent->xclient.data.l[0]; - event->dropdataavailable.data_type = - gdk_atom_name(xevent->xclient.data.l[2]); - if(XGetWindowProperty (gdk_display, - event->dropdataavailable.requestor, - xevent->xclient.data.l[2], - 0, LONG_MAX - 1, - False, XA_PRIMARY, &tmp_atom, - &tmp_int, - &event->dropdataavailable.data_numbytes, - &tmp_long, - &tmp_charptr) - != Success) - { - g_warning("XGetWindowProperty on %#x may have failed\n", - event->dropdataavailable.requestor); - event->dropdataavailable.data = NULL; - } - else - { - GDK_NOTE (DND, g_print("XGetWindowProperty got us %ld bytes\n", - event->dropdataavailable.data_numbytes)); - event->dropdataavailable.data = - g_malloc (event->dropdataavailable.data_numbytes); - memcpy (event->dropdataavailable.data, - tmp_charptr, event->dropdataavailable.data_numbytes); - XFree(tmp_charptr); - return_val = TRUE; - } - return_val = TRUE; - } - } - else - { - /* Send unknown ClientMessage's on to Gtk for it to use */ - event->client.type = GDK_CLIENT_EVENT; - event->client.window = window; - event->client.message_type = xevent->xclient.message_type; - event->client.data_format = xevent->xclient.format; - memcpy(&event->client.data, &xevent->xclient.data, - sizeof(event->client.data)); - if(window) - return_val = TRUE; - else - return_val = FALSE; - } - if(window_private) - return_val = return_val && !window_private->destroyed; - break; - - case MappingNotify: - /* Print debugging info. - */ - GDK_NOTE (EVENTS, - g_print ("mapping notify\n")); - - /* Let XLib know that there is a new keyboard mapping. - */ - XRefreshKeyboardMapping (&xevent->xmapping); - break; - - default: - /* something else - (e.g., a Xinput event) */ - - if (window_private && - (window_private->extension_events != 0) && - gdk_input_vtable.other_event) - return_val = gdk_input_vtable.other_event(event, xevent, window); - else - return_val = FALSE; - - return_val = return_val && !window_private->destroyed; - - break; - } - - if (return_val) - { - if (event->any.window) - gdk_window_ref (event->any.window); - if (((event->any.type == GDK_ENTER_NOTIFY) || - (event->any.type == GDK_LEAVE_NOTIFY)) && - (event->crossing.subwindow != NULL)) - gdk_window_ref (event->crossing.subwindow); - } - else - { - /* Mark this event as having no resources to be freed */ - event->any.window = NULL; - event->any.type = GDK_NOTHING; - } - - if (window) - gdk_window_unref (window); - - return return_val; -} - -#if 0 -static Bool -gdk_event_get_type (Display *display, - XEvent *xevent, - XPointer arg) -{ - GdkEvent event; - GdkPredicate *pred; - - if (gdk_event_translate (&event, xevent)) - { - pred = (GdkPredicate*) arg; - return (* pred->func) (&event, pred->data); - } - - return FALSE; -} -#endif - -static void -gdk_synthesize_click (GdkEvent *event, - gint nclicks) -{ - GdkEvent temp_event; - - g_return_if_fail (event != NULL); - - temp_event = *event; - temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; - - gdk_event_put (&temp_event); -} - -/* - *-------------------------------------------------------------- - * gdk_exit_func - * - * This is the "atexit" function that makes sure the - * library gets a chance to cleanup. - * - * Arguments: - * - * Results: - * - * Side effects: - * The library is un-initialized and the program exits. - * - *-------------------------------------------------------------- - */ - -static void -gdk_exit_func (void) -{ - static gboolean in_gdk_exit_func = FALSE; - - /* This is to avoid an infinite loop if a program segfaults in - an atexit() handler (and yes, it does happen, especially if a program - has trounced over memory too badly for even g_print to work) */ - if(in_gdk_exit_func == TRUE) return; - in_gdk_exit_func = TRUE; - - if (initialized) - { -#ifdef USE_XIM - /* cleanup IC */ - gdk_ic_cleanup (); - /* close IM */ - gdk_im_close (); -#endif - gdk_image_exit (); - gdk_input_exit (); - gdk_key_repeat_restore (); - - XCloseDisplay (gdk_display); - initialized = 0; - } -} - -/* - *-------------------------------------------------------------- - * gdk_x_error - * - * The X error handling routine. - * - * Arguments: - * "display" is the X display the error orignated from. - * "error" is the XErrorEvent that we are handling. - * - * Results: - * Either we were expecting some sort of error to occur, - * in which case we set the "gdk_error_code" flag, or this - * error was unexpected, in which case we will print an - * error message and exit. (Since trying to continue will - * most likely simply lead to more errors). - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static int -gdk_x_error (Display *display, - XErrorEvent *error) -{ - char buf[64]; - - if (gdk_error_warnings) - { - XGetErrorText (display, error->error_code, buf, 63); - g_error ("%s\n serial %ld error_code %d request_code %d minor_code %d\n", - buf, - error->serial, - error->error_code, - error->request_code, - error->minor_code); - } - - gdk_error_code = -1; - return 0; -} - -/* - *-------------------------------------------------------------- - * gdk_x_io_error - * - * The X I/O error handling routine. - * - * Arguments: - * "display" is the X display the error orignated from. - * - * Results: - * An X I/O error basically means we lost our connection - * to the X server. There is not much we can do to - * continue, so simply print an error message and exit. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static int -gdk_x_io_error (Display *display) -{ - g_error ("an x io error occurred"); - return 0; -} - -/* - *-------------------------------------------------------------- - * gdk_signal - * - * The signal handler. - * - * Arguments: - * "sig_num" is the number of the signal we received. - * - * Results: - * The signals we catch are all fatal. So we simply build - * up a nice little error message and print it and exit. - * If in the process of doing so another signal is received - * we notice that we are already exiting and simply kill - * our process. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -static RETSIGTYPE -gdk_signal (int sig_num) -{ - static int caught_fatal_sig = 0; - char *sig; - - if (caught_fatal_sig) - kill (getpid (), sig_num); - caught_fatal_sig = 1; - - switch (sig_num) - { - case SIGHUP: - sig = "sighup"; - break; - case SIGINT: - sig = "sigint"; - break; - case SIGQUIT: - sig = "sigquit"; - break; - case SIGBUS: - sig = "sigbus"; - break; - case SIGSEGV: - sig = "sigsegv"; - break; - case SIGPIPE: - sig = "sigpipe"; - break; - case SIGTERM: - sig = "sigterm"; - break; - default: - sig = "unknown signal"; - break; - } - - g_print ("\n** ERROR **: %s caught\n", sig); -#ifdef G_ENABLE_DEBUG - abort (); -#else /* !G_ENABLE_DEBUG */ - gdk_exit (1); -#endif /* !G_ENABLE_DEBUG */ -} - -static void -gdk_dnd_drag_begin (GdkWindow *initial_window) -{ - GdkEvent tev; - - GDK_NOTE(DND, g_print("------- STARTING DRAG from %p\n", initial_window)); - - tev.type = GDK_DRAG_BEGIN; - tev.dragbegin.window = initial_window; - tev.dragbegin.u.allflags = 0; - tev.dragbegin.u.flags.protocol_version = DND_PROTOCOL_VERSION; - - gdk_event_put (&tev); -} - -static void -gdk_dnd_drag_enter (Window dest) -{ - XEvent sev; - GdkEventDropEnter tev; - int i; - GdkWindowPrivate *wp; - - sev.xclient.type = ClientMessage; - sev.xclient.format = 32; - sev.xclient.message_type = gdk_dnd.gdk_XdeEnter; - sev.xclient.window = dest; - - tev.u.allflags = 0; - tev.u.flags.protocol_version = DND_PROTOCOL_VERSION; - tev.u.flags.sendreply = 1; - for (i = 0; i < gdk_dnd.drag_numwindows; i++) - { - wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i]; - if (wp->dnd_drag_data_numtypesavail) - { - sev.xclient.data.l[0] = wp->xwindow; - tev.u.flags.extended_typelist = (wp->dnd_drag_data_numtypesavail > 3)?1:0; - sev.xclient.data.l[1] = tev.u.allflags; - sev.xclient.data.l[2] = wp->dnd_drag_data_typesavail[0]; - if (wp->dnd_drag_data_numtypesavail > 1) - { - sev.xclient.data.l[3] = wp->dnd_drag_data_typesavail[1]; - if (wp->dnd_drag_data_numtypesavail > 2) - { - sev.xclient.data.l[4] = wp->dnd_drag_data_typesavail[2]; - } - else - sev.xclient.data.l[4] = None; - } - else - sev.xclient.data.l[3] = sev.xclient.data.l[4] = None; - if (!gdk_send_xevent (dest, False, StructureNotifyMask, &sev)) - GDK_NOTE (DND, g_print("Sending XdeEnter to %#lx failed\n", - dest)); - } - - } -} - - -#ifdef USE_XIM - -/* The following routines duplicate functionality in Xlib to - * translate from varargs to X's internal opaque XVaNestedList. - * - * If all vendors have stuck close to the reference implementation, - * then we should hopefully be OK. - */ - -/* This needs to match XIMArg as defined in Xlcint.h exactly */ - -typedef struct { - gchar *name; - gpointer value; -} GdkImArg; - -/************************************************************* - * gdk_im_va_count: - * Counts the number of name/value pairs in the vararg list - * - * arguments: - * - * results: - *************************************************************/ - -static guint -gdk_im_va_count (va_list list) -{ - gint count = 0; - gchar *name; - - name = va_arg (list, gchar *); - while (name) - { - count++; - (void)va_arg (list, gpointer); - name = va_arg (list, gchar *); - } - - return count; -} - -/************************************************************* - * gdk_im_va_to_nested: - * Given a varargs list and the result of gdk_im_va_count, - * create a XVaNestedList. - * - * arguments: - * - * results: - *************************************************************/ - -static XVaNestedList -gdk_im_va_to_nested (va_list list, guint count) -{ - GdkImArg *result; - GdkImArg *arg; - - gchar *name; - - if (count == 0) - return NULL; - - result = g_new (GdkImArg, count+1); - arg = result; - - name = va_arg (list, gchar *); - while (name) - { - arg->name = name; - arg->value = va_arg (list, gpointer); - arg++; - name = va_arg (list, gchar *); - } - - arg->name = NULL; - - return (XVaNestedList)result; -} - -/* - *-------------------------------------------------------------- - * gdk_im_begin - * - * Begin using input method with XIM Protocol(X11R6 standard) - * - * Arguments: - * "ic" is the "Input Context" which is created by gtk_ic_new. - * The input area is specified with "window". - * - * Results: - * The gdk's event handling routine is switched to XIM based routine. - * XIM based routine uses XFilterEvent to get rid of events used by IM, - * and uses XmbLookupString instead of XLookupString. - * - * Side effects: - * - *-------------------------------------------------------------- - */ - -void -gdk_im_begin (GdkIC ic, GdkWindow* window) -{ - GdkICPrivate *private; - Window xwin; - - g_return_if_fail (ic != NULL); - g_return_if_fail (window); - - private = (GdkICPrivate *) ic; - - xim_using = TRUE; - xim_ic = private; - xim_window = window; - if (gdk_im_ready()) - { - XGetICValues (private->xic, XNFocusWindow, &xwin, NULL); - if (xwin != GDK_WINDOW_XWINDOW(window)) - XSetICValues (private->xic, XNFocusWindow, - GDK_WINDOW_XWINDOW(window), NULL); - if (private != xim_ic) - XSetICFocus (private->xic); - } -} /* - *-------------------------------------------------------------- - * gdk_im_end - * - * End using input method with XIM Protocol(X11R6 standard) - * - * Arguments: - * - * Results: - * The gdk's event handling routine is switched to normal routine. - * User should call this function before ic and window will be destroyed. - * - * Side effects: - * - *-------------------------------------------------------------- + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ -void -gdk_im_end (void) -{ - xim_using = FALSE; - xim_ic = NULL; - xim_window = NULL; -} - -static GdkIM -gdk_im_get (void) -{ - return xim_im; -} - -static GdkIMStyle -gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2) -{ - GdkIMStyle s1, s2, u; - - if (style1 == 0) return style2; - if (style2 == 0) return style1; - if ((style1 & (GdkIMPreeditMask | GdkIMStatusMask)) - == (style2 & (GdkIMPreeditMask | GdkIMStatusMask))) - return style1; - - s1 = style1 & GdkIMPreeditMask; - s2 = style2 & GdkIMPreeditMask; - u = s1 | s2; - if (s1 != s2) { - if (u & GdkIMPreeditCallbacks) - return (s1 == GdkIMPreeditCallbacks)? style1:style2; - else if (u & GdkIMPreeditPosition) - return (s1 == GdkIMPreeditPosition)? style1:style2; - else if (u & GdkIMPreeditArea) - return (s1 == GdkIMPreeditArea)? style1:style2; - else if (u & GdkIMPreeditNothing) - return (s1 == GdkIMPreeditNothing)? style1:style2; - } else { - s1 = style1 & GdkIMStatusMask; - s2 = style2 & GdkIMStatusMask; - u = s1 | s2; - if ( u & GdkIMStatusCallbacks) - return (s1 == GdkIMStatusCallbacks)? style1:style2; - else if ( u & GdkIMStatusArea) - return (s1 == GdkIMStatusArea)? style1:style2; - else if ( u & GdkIMStatusNothing) - return (s1 == GdkIMStatusNothing)? style1:style2; - else if ( u & GdkIMStatusNone) - return (s1 == GdkIMStatusNone)? style1:style2; - } - return 0; /* Get rid of stupid warning */ -} - -GdkIMStyle -gdk_im_decide_style (GdkIMStyle supported_style) -{ - gint i; - GdkIMStyle style, tmp; - - g_return_val_if_fail (xim_styles != NULL, 0); - - style = 0; - for (i=0; icount_styles; i++) - { - tmp = xim_styles->supported_styles[i]; - if (tmp == (tmp & supported_style & xim_best_allowed_style)) - style = gdk_im_choose_better_style (style, tmp); - } - return style; -} - -GdkIMStyle -gdk_im_set_best_style (GdkIMStyle style) -{ - if (style & GdkIMPreeditMask) - { - xim_best_allowed_style &= ~GdkIMPreeditMask; - - xim_best_allowed_style |= GdkIMPreeditNone; - if (!(style & GdkIMPreeditNone)) - { - xim_best_allowed_style |= GdkIMPreeditNothing; - if (!(style & GdkIMPreeditNothing)) - { - xim_best_allowed_style |= GdkIMPreeditArea; - if (!(style & GdkIMPreeditArea)) - { - xim_best_allowed_style |= GdkIMPreeditPosition; - if (!(style & GdkIMPreeditPosition)) - xim_best_allowed_style |= GdkIMPreeditCallbacks; - } - } - } - } - if (style & GdkIMStatusMask) - { - xim_best_allowed_style &= ~GdkIMStatusMask; - - xim_best_allowed_style |= GdkIMStatusNone; - if (!(style & GdkIMStatusNone)) - { - xim_best_allowed_style |= GdkIMStatusNothing; - if (!(style & GdkIMStatusNothing)) - { - xim_best_allowed_style |= GdkIMStatusArea; - if (!(style & GdkIMStatusArea)) - xim_best_allowed_style |= GdkIMStatusCallbacks; - } - } - } - - return xim_best_allowed_style; -} - -static gint -gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class) -{ - xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class); - if (xim_im == NULL) - { - GDK_NOTE (XIM, g_warning ("Unable to open open IM.")); - return FALSE; - } - XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL); - - return TRUE; -} - -static void -gdk_im_close (void) -{ - if (xim_im) - { - XCloseIM (xim_im); - xim_im = NULL; - } - if (xim_styles) - { - XFree (xim_styles); - xim_styles = NULL; - } -} - -gint -gdk_im_ready (void) -{ - return (xim_im != NULL); -} - -GdkIC -gdk_ic_new (GdkWindow* client_window, - GdkWindow* focus_window, - GdkIMStyle style, ...) -{ - va_list list; - GdkICPrivate *private; - XVaNestedList preedit_attr = NULL; - guint count; - - g_return_val_if_fail (client_window != NULL, NULL); - g_return_val_if_fail (focus_window != NULL, NULL); - g_return_val_if_fail (gdk_im_ready(), NULL); - - private = g_new (GdkICPrivate, 1); - - va_start (list, style); - count = gdk_im_va_count (list); - va_end (list); - - va_start (list, style); - preedit_attr = gdk_im_va_to_nested (list, count); - va_end (list); - - private->style = gdk_im_decide_style (style); - if (private->style != style) - { - g_warning ("can not create input context with specified input style."); - g_free (private); - return NULL; - } - - private->xic = XCreateIC(gdk_im_get (), - XNInputStyle, style, - XNClientWindow, GDK_WINDOW_XWINDOW (client_window), - XNFocusWindow, GDK_WINDOW_XWINDOW (focus_window), - preedit_attr? XNPreeditAttributes : NULL, preedit_attr, - NULL); - - g_free (preedit_attr); - - if (!private->xic) - { - g_free (private); - return NULL; - } - - xim_ic_list = g_list_append (xim_ic_list, private); - return private; -} - -void -gdk_ic_destroy (GdkIC ic) -{ - GdkICPrivate *private; - - g_return_if_fail (ic != NULL); - - private = (GdkICPrivate *) ic; - - if (xim_ic == private) - gdk_im_end (); - - XDestroyIC (private->xic); - xim_ic_list = g_list_remove (xim_ic_list, private); - g_free (private); -} - -GdkIMStyle -gdk_ic_get_style (GdkIC ic) -{ - GdkICPrivate *private; - - g_return_val_if_fail (ic != NULL, 0); - - private = (GdkICPrivate *) ic; - - return private->style; -} - -void -gdk_ic_set_values (GdkIC ic, ...) -{ - va_list list; - XVaNestedList args; - GdkICPrivate *private; - guint count; - - g_return_if_fail (ic != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, ic); - count = gdk_im_va_count (list); - va_end (list); - - va_start (list, ic); - args = gdk_im_va_to_nested (list, count); - va_end (list); - - XSetICValues (private->xic, XNVaNestedList, args, NULL); - - g_free (args); -} - -void -gdk_ic_get_values (GdkIC ic, ...) -{ - va_list list; - XVaNestedList args; - GdkICPrivate *private; - guint count; - - g_return_if_fail (ic != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, ic); - count = gdk_im_va_count (list); - va_end (list); - - va_start (list, ic); - args = gdk_im_va_to_nested (list, count); - va_end (list); - - XGetICValues (private->xic, XNVaNestedList, args, NULL); - - g_free (args); -} - -void -gdk_ic_set_attr (GdkIC ic, const char *target, ...) -{ - va_list list; - XVaNestedList attr; - GdkICPrivate *private; - guint count; - - g_return_if_fail (ic != NULL); - g_return_if_fail (target != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, target); - count = gdk_im_va_count (list); - va_end (list); - - va_start (list, target); - attr = gdk_im_va_to_nested (list, count); - va_end (list); - - XSetICValues (private->xic, target, attr, NULL); - - g_free (attr); -} - -void -gdk_ic_get_attr (GdkIC ic, const char *target, ...) -{ - va_list list; - XVaNestedList attr; - GdkICPrivate *private; - guint count; - - g_return_if_fail (ic != NULL); - g_return_if_fail (target != NULL); - - private = (GdkICPrivate *) ic; - - va_start (list, target); - count = gdk_im_va_count (list); - va_end (list); - - va_start (list, target); - attr = gdk_im_va_to_nested (list, count); - va_end (list); - - XGetICValues (private->xic, target, attr, NULL); - - g_free (attr); -} - -GdkEventMask -gdk_ic_get_events (GdkIC ic) -{ - GdkEventMask mask; - glong xmask; - glong bit; - GdkICPrivate *private; - gint i; - - /* From gdkwindow.c */ - extern int nevent_masks; - extern int event_mask_table[]; - - g_return_val_if_fail (ic != NULL, 0); - - private = (GdkICPrivate *) ic; - - if (XGetICValues (private->xic, XNFilterEvents, &xmask, NULL) != NULL) - { - GDK_NOTE (XIM, g_warning ("Call to XGetICValues: %s failed", XNFilterEvents)); - return 0; - } - - mask = 0; - for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1) - if (xmask & event_mask_table [i]) - { - mask |= bit; - xmask &= ~ event_mask_table [i]; - } +#include "config.h" - if (xmask) - g_warning ("ic requires events not supported by the application (%#04lx)", xmask); - - return mask; -} +#include +#include -static void -gdk_ic_cleanup (void) -{ - GList* node; - gint destroyed; - GdkICPrivate *private; +#include "gdk.h" +#include "gdkinternals.h" - destroyed = 0; - for (node = xim_ic_list; node != NULL; node = node->next) - { - if (node->data) - { - private = (GdkICPrivate *) (node->data); - XDestroyIC (private->xic); - g_free (private); - destroyed++; - } - } -#ifdef G_ENABLE_DEBUG - if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0) - { - g_warning ("Cleaned up %i IC(s)\n", destroyed); - } -#endif /* G_ENABLE_DEBUG */ - g_list_free(xim_ic_list); - xim_ic_list = NULL; -} +#ifndef HAVE_XCONVERTCASE +#include "gdkkeysyms.h" +#endif -#else /* !USE_XIM */ +typedef struct _GdkPredicate GdkPredicate; -void -gdk_im_begin (GdkIC ic, GdkWindow* window) +struct _GdkPredicate { -} + GdkEventFunc func; + gpointer data; +}; -void -gdk_im_end (void) -{ -} +/* Private variable declarations + */ +static int gdk_initialized = 0; /* 1 if the library is initialized, + * 0 otherwise. + */ -GdkIMStyle -gdk_im_decide_style (GdkIMStyle supported_style) -{ - return GdkIMPreeditNone | GdkIMStatusNone; -} +static gchar *gdk_progclass = NULL; +static gint gdk_argc = 0; +static gchar **gdk_argv = NULL; -GdkIMStyle -gdk_im_set_best_style (GdkIMStyle style) -{ - return GdkIMPreeditNone | GdkIMStatusNone; -} +#ifdef G_ENABLE_DEBUG +static const GDebugKey gdk_debug_keys[] = { + {"events", GDK_DEBUG_EVENTS}, + {"misc", GDK_DEBUG_MISC}, + {"dnd", GDK_DEBUG_DND}, + {"xim", GDK_DEBUG_XIM}, + {"nograbs", GDK_DEBUG_NOGRABS}, + {"colormap", GDK_DEBUG_COLORMAP}, + {"gdkrgb", GDK_DEBUG_GDKRGB}, + {"gc", GDK_DEBUG_GC}, + {"pixmap", GDK_DEBUG_PIXMAP}, + {"image", GDK_DEBUG_IMAGE}, + {"input", GDK_DEBUG_INPUT}, + {"cursor", GDK_DEBUG_CURSOR}, + {"multihead", GDK_DEBUG_MULTIHEAD}, +}; -gint -gdk_im_ready (void) -{ - return FALSE; -} +static const int gdk_ndebug_keys = G_N_ELEMENTS (gdk_debug_keys); -GdkIC -gdk_ic_new (GdkWindow* client_window, - GdkWindow* focus_window, - GdkIMStyle style, ...) -{ - return NULL; -} +#endif /* G_ENABLE_DEBUG */ -void -gdk_ic_destroy (GdkIC ic) +static GdkArgContext * +gdk_arg_context_new (gpointer cb_data) { -} + GdkArgContext *result = g_new (GdkArgContext, 1); + result->tables = g_ptr_array_new (); + result->cb_data = cb_data; -GdkIMStyle -gdk_ic_get_style (GdkIC ic) -{ - return GdkIMPreeditNone | GdkIMStatusNone; + return result; } -void -gdk_ic_set_values (GdkIC ic, ...) +static void +gdk_arg_context_destroy (GdkArgContext *context) { + g_ptr_array_free (context->tables, TRUE); + g_free (context); } -void -gdk_ic_get_values (GdkIC ic, ...) +static void +gdk_arg_context_add_table (GdkArgContext *context, GdkArgDesc *table) { + g_ptr_array_add (context->tables, table); } -void -gdk_ic_set_attr (GdkIC ic, const char *target, ...) +static void +gdk_arg_context_parse (GdkArgContext *context, gint *argc, gchar ***argv) { -} + int i, j, k; -void -gdk_ic_get_attr (GdkIC ic, const char *target, ...) -{ + /* Save a copy of the original argc and argv */ + if (argc && argv) + { + for (i = 1; i < *argc; i++) + { + char *arg; + + if (!(*argv)[i][0] == '-' && (*argv)[i][1] == '-') + continue; + + arg = (*argv)[i] + 2; + + /* '--' terminates list of arguments */ + if (arg == 0) + { + (*argv)[i] = NULL; + break; + } + + for (j = 0; j < context->tables->len; j++) + { + GdkArgDesc *table = context->tables->pdata[j]; + for (k = 0; table[k].name; k++) + { + switch (table[k].type) + { + case GDK_ARG_STRING: + case GDK_ARG_CALLBACK: + case GDK_ARG_INT: + { + int len = strlen (table[k].name); + + if (strncmp (arg, table[k].name, len) == 0 && + (arg[len] == '=' || arg[len] == 0)) + { + char *value = NULL; + + (*argv)[i] = NULL; + + if (arg[len] == '=') + value = arg + len + 1; + else if (i < *argc - 1) + { + value = (*argv)[i + 1]; + (*argv)[i+1] = NULL; + i++; + } + else + value = ""; + + switch (table[k].type) + { + case GDK_ARG_STRING: + *(gchar **)table[k].location = g_strdup (value); + break; + case GDK_ARG_INT: + *(gint *)table[k].location = atoi (value); + break; + case GDK_ARG_CALLBACK: + (*table[k].callback)(table[k].name, value, context->cb_data); + break; + default: + ; + } + + goto next_arg; + } + break; + } + case GDK_ARG_BOOL: + case GDK_ARG_NOBOOL: + if (strcmp (arg, table[k].name) == 0) + { + (*argv)[i] = NULL; + + *(gboolean *)table[k].location = (table[k].type == GDK_ARG_BOOL) ? TRUE : FALSE; + goto next_arg; + } + } + } + } + next_arg: + ; + } + + for (i = 1; i < *argc; i++) + { + for (k = i; k < *argc; k++) + if ((*argv)[k] != NULL) + break; + + if (k > i) + { + k -= i; + for (j = i + k; j < *argc; j++) + (*argv)[j-k] = (*argv)[j]; + *argc -= k; + } + } + } } -GdkEventMask -gdk_ic_get_events (GdkIC ic) +#ifdef G_ENABLE_DEBUG +static void +gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data) { - return 0; + _gdk_debug_flags |= g_parse_debug_string (value, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); } -#endif /* USE_XIM */ - -#ifdef X_LOCALE - -gint -_g_mbtowc (wchar_t *wstr, const char *str, size_t len) +static void +gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data) { - static wchar_t wcs[MB_CUR_MAX + 1]; - static gchar mbs[MB_CUR_MAX + 1]; - - wcs[0] = (wchar_t) NULL; - mbs[0] = '\0'; - - /* The last argument isn't a mistake. The X locale code trims - * the input string to the length of the output string! - */ - len = _Xmbstowcs (wcs, str, (lenxwindow; - if (!gdk_send_xevent (dest, False, StructureNotifyMask, &sev)) - GDK_NOTE (DND, g_print("Sending XdeLeave to %#lx failed\n", - dest)); - wp->dnd_drag_accepted = 0; - } + gdk_set_program_class (value); } -/* - * when a drop occurs, we go through the list of windows being dragged and - * tell them that it has occurred, so that they can set things up and reply - * to 'dest' window - */ static void -gdk_dnd_drag_end (Window dest, - GdkPoint coords) +gdk_arg_name_cb (const char *key, const char *value, gpointer user_data) { - GdkWindowPrivate *wp; - GdkEvent tev; - int i; + g_set_prgname (value); +} - tev.dragrequest.type = GDK_DRAG_REQUEST; - tev.dragrequest.drop_coords = coords; - tev.dragrequest.requestor = dest; - tev.dragrequest.u.allflags = 0; - tev.dragrequest.u.flags.protocol_version = DND_PROTOCOL_VERSION; - tev.dragrequest.isdrop = 1; +static GdkArgDesc gdk_args[] = { + { "class" , GDK_ARG_CALLBACK, NULL, gdk_arg_class_cb }, + { "name", GDK_ARG_CALLBACK, NULL, gdk_arg_name_cb }, + { "display", GDK_ARG_STRING, &_gdk_display_name, (GdkArgFunc)NULL }, + { "screen", GDK_ARG_INT, &_gdk_screen_number, (GdkArgFunc)NULL }, - for (i = 0; i < gdk_dnd.drag_numwindows; i++) - { - wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i]; - if (wp->dnd_drag_accepted) - { - tev.dragrequest.window = (GdkWindow *) wp; - tev.dragrequest.u.flags.delete_data = wp->dnd_drag_destructive_op; - tev.dragrequest.timestamp = gdk_dnd.last_drop_time; - tev.dragrequest.data_type = - gdk_atom_name(wp->dnd_drag_data_type); +#ifdef G_ENABLE_DEBUG + { "gdk-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_debug_cb }, + { "gdk-no-debug", GDK_ARG_CALLBACK, NULL, gdk_arg_no_debug_cb }, +#endif /* G_ENABLE_DEBUG */ + { NULL } +}; - gdk_event_put(&tev); - } - } -} -static GdkAtom -gdk_dnd_check_types (GdkWindow *window, - XEvent *xevent) +/** + * _gdk_get_command_line_args: + * @argv: location to store argv pointer + * @argc: location + * + * Retrieve the command line arguments passed to gdk_init(). + * The returned argv pointer points to static storage ; no + * copy is made. + **/ +void +_gdk_get_command_line_args (int *argc, + char ***argv) { - GdkWindowPrivate *wp = (GdkWindowPrivate *) window; - int i, j; - GdkEventDropEnter event; + *argc = gdk_argc; + *argv = gdk_argv; +} - g_return_val_if_fail(window != NULL, 0); - g_return_val_if_fail(xevent != NULL, 0); - g_return_val_if_fail(xevent->type == ClientMessage, 0); - g_return_val_if_fail(xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter, 0); +/** + * gdk_parse_args: + * @argc: the number of command line arguments. + * @argv: the array of command line arguments. + * + * Parse command line arguments, and store for future + * use by calls to gdk_display_open(). + * + * Any arguments used by GDK are removed from the array and @argc and @argv are + * updated accordingly. + * + * You shouldn't call this function explicitely if you are using + * gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check(). + * + * Since: 2.2 + **/ +void +gdk_parse_args (int *argc, + char ***argv) +{ + GdkArgContext *arg_context; + gint i; - if(wp->dnd_drop_data_numtypesavail <= 0 || - !wp->dnd_drop_data_typesavail) - return 0; + if (gdk_initialized) + return; - for (i = 2; i <= 4; i++) - { - for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++) - { - if (xevent->xclient.data.l[i] == wp->dnd_drop_data_typesavail[j]) - return xevent->xclient.data.l[i]; - } - } + gdk_initialized = TRUE; - /* Now we get the extended type list if it's available */ - event.u.allflags = xevent->xclient.data.l[1]; - if (event.u.flags.extended_typelist) + if (argc && argv) { - Atom *exttypes, realtype; - gulong nitems, nbar; - gint realfmt; - - if (XGetWindowProperty(gdk_display, xevent->xclient.data.l[0], - gdk_dnd.gdk_XdeTypelist, 0L, LONG_MAX - 1, - False, AnyPropertyType, &realtype, &realfmt, - &nitems, &nbar, (unsigned char **) &exttypes) - != Success) - return 0; - - if (realfmt != (sizeof(Atom) * 8)) - { - g_warning("XdeTypelist property had format of %d instead of the expected %ld, on window %#lx\n", - realfmt, (glong)sizeof(Atom) * 8, xevent->xclient.data.l[0]); - return 0; - } + gdk_argc = *argc; + + gdk_argv = g_malloc ((gdk_argc + 1) * sizeof (char*)); + for (i = 0; i < gdk_argc; i++) + gdk_argv[i] = g_strdup ((*argv)[i]); + gdk_argv[gdk_argc] = NULL; - for (i = 0; i <= nitems; i++) + if (*argc > 0) { - for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++) - { - if (exttypes[i] == wp->dnd_drop_data_typesavail[j]) - { - XFree (exttypes); - return exttypes[i]; - } - } + gchar *d; + + d = strrchr((*argv)[0], G_DIR_SEPARATOR); + if (d != NULL) + g_set_prgname (d + 1); + else + g_set_prgname ((*argv)[0]); } - XFree (exttypes); } - return 0; -} - -/* - * used for debugging only - */ -#ifdef DEBUG_DND -static void -gdk_print_atom (GdkAtom anatom) -{ - gchar *tmpstr = NULL; - tmpstr = (anatom!=None)?gdk_atom_name(anatom):"(none)"; - g_print("Atom %lu has name %s\n", anatom, tmpstr); - if(tmpstr) - g_free(tmpstr); -} -#endif - -/* - * used only by below routine and itself - */ -static Window -getchildren (Display *dpy, - Window win, - Atom WM_STATE) -{ - Window root, parent, *children, inf = 0; - Atom type = None; - unsigned int nchildren, i; - int format; - unsigned long nitems, after; - unsigned char *data; - - if (XQueryTree(dpy, win, &root, &parent, &children, &nchildren) == 0) - return 0; - - for (i = 0; !inf && (i < nchildren); i++) + else { - XGetWindowProperty (dpy, children[i], WM_STATE, 0, 0, False, - AnyPropertyType, &type, &format, &nitems, - &after, &data); - if (type != 0) - inf = children[i]; - XFree(data); + g_set_prgname (""); } - for (i = 0; !inf && (i < nchildren); i++) - inf = getchildren (dpy, children[i], WM_STATE); + /* We set the fallback program class here, rather than lazily in + * gdk_get_program_class, since we don't want -name to override it. + */ + gdk_progclass = g_strdup (g_get_prgname ()); + if (gdk_progclass[0]) + gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]); + +#ifdef G_ENABLE_DEBUG + { + gchar *debug_string = getenv("GDK_DEBUG"); + if (debug_string != NULL) + _gdk_debug_flags = g_parse_debug_string (debug_string, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); + } +#endif /* G_ENABLE_DEBUG */ + + arg_context = gdk_arg_context_new (NULL); + gdk_arg_context_add_table (arg_context, gdk_args); + gdk_arg_context_add_table (arg_context, _gdk_windowing_args); + gdk_arg_context_parse (arg_context, argc, argv); + gdk_arg_context_destroy (arg_context); + + GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ())); - if (children != None) - XFree ((char *) children); + g_type_init (); - return inf; + /* Do any setup particular to the windowing system + */ + _gdk_windowing_init (argc, argv); } -/* - * find a window with WM_STATE, else return win itself, as per ICCCM +/** + * gdk_get_display_arg_name: + * + * Gets the display name specified in the command line arguments passed + * to gdk_init() or gdk_parse_args(), if any. * - * modification of the XmuClientWindow() routine from X11R6.3 + * Returns: the display name, if specified explicitely, otherwise %NULL + * this string is owned by GTK+ and must not be modified or freed. + * + * Since: 2.2 */ -Window -gdk_get_client_window (Display *dpy, - Window win) +G_CONST_RETURN gchar * +gdk_get_display_arg_name (void) { - Atom WM_STATE; - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; - Window inf; - - if (win == 0) - return DefaultRootWindow(dpy); - - if ((WM_STATE = XInternAtom (dpy, "WM_STATE", True)) == 0) - return win; - - XGetWindowProperty (dpy, win, WM_STATE, 0, 0, False, AnyPropertyType, - &type, &format, &nitems, &after, &data); - if (type) - return win; - - inf = getchildren (dpy, win, WM_STATE); + if (!_gdk_display_arg_name) + { + if (_gdk_screen_number >= 0) + _gdk_display_arg_name = _gdk_windowing_substitute_screen_number (_gdk_display_name, _gdk_screen_number); + else + _gdk_display_arg_name = g_strdup (_gdk_display_name); + } - if (inf == 0) - return win; - else - return inf; + return _gdk_display_arg_name; } -#ifdef WE_HAVE_MOTIF_DROPS_DONE -static GdkWindow * -gdk_drop_get_real_window (GdkWindow *w, - guint16 *x, - guint16 *y) +/** + * gdk_display_open_default_libgtk_only: + * + * Opens the default display specified by command line arguments or + * environment variables, sets it as the default display, and returns + * it. gdk_parse_args must have been called first. If the default + * display has previously been set, simply returns that. An internal + * function that should not be used by applications. + * + * Return value: the default display, if it could be opened, + * otherwise %NULL. + **/ +GdkDisplay * +gdk_display_open_default_libgtk_only (void) { - GdkWindow *retval = w; - GdkWindowPrivate *awin; - GList *children; - gint16 myx = *x, myy = *y; + GdkDisplay *display; - g_return_val_if_fail (w != NULL && x != NULL && y != NULL, NULL); + g_return_val_if_fail (gdk_initialized, NULL); + + display = gdk_display_get_default (); + if (display) + return display; - myx = *x; - myy = *y; + display = gdk_display_open (gdk_get_display_arg_name ()); -descend: - for (children = gdk_window_get_children(retval); - children && children->next; - children = children->next) + if (!display && _gdk_screen_number >= 0) { - awin = (GdkWindowPrivate *) children->data; - if ((myx >= awin->x) && (myy >= awin->y) - && (myx < (awin->x + awin->width)) - && (myy < (awin->y + awin->height))) - { - retval = (GdkWindow *) awin; - myx -= awin->x; - myy -= awin->y; - goto descend; - } + g_free (_gdk_display_arg_name); + _gdk_display_arg_name = g_strdup (_gdk_display_name); + + display = gdk_display_open (_gdk_display_name); } - - *x = myx; - *y = myy; - - return retval; + + if (display) + gdk_display_manager_set_default_display (gdk_display_manager_get (), + display); + + return display; } -#endif - -/* Sends a ClientMessage to all toplevel client windows */ -void -gdk_event_send_clientmessage_toall (GdkEvent *event) -{ - XEvent sev; - Window *ret_children, ret_root, ret_parent, curwin; - unsigned int ret_nchildren; - int i; - - g_return_if_fail(event != NULL); - - /* Set up our event to send, with the exception of its target window */ - sev.xclient.type = ClientMessage; - sev.xclient.display = gdk_display; - sev.xclient.format = event->client.data_format; - sev.xclient.serial = CurrentTime; - memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data)); - sev.xclient.message_type = event->client.message_type; - /* OK, we're all set, now let's find some windows to send this to */ - if(XQueryTree(gdk_display, gdk_root_window, &ret_root, &ret_parent, - &ret_children, &ret_nchildren) != True) - return; +/* + *-------------------------------------------------------------- + * gdk_init_check + * + * Initialize the library for use. + * + * Arguments: + * "argc" is the number of arguments. + * "argv" is an array of strings. + * + * Results: + * "argc" and "argv" are modified to reflect any arguments + * which were not handled. (Such arguments should either + * be handled by the application or dismissed). If initialization + * fails, returns FALSE, otherwise TRUE. + * + * Side effects: + * The library is initialized. + * + *-------------------------------------------------------------- + */ - /* foreach true child window of the root window, send an event to it */ - for(i = 0; i < ret_nchildren; i++) { - curwin = gdk_get_client_window(gdk_display, ret_children[i]); - sev.xclient.window = curwin; - if (!gdk_send_xevent (curwin, False, NoEventMask, &sev)) - GDK_NOTE (MISC, g_print("Gdk: Sending client message %ld to %#lx failed\n", - event->client.message_type, curwin)); - } +gboolean +gdk_init_check (int *argc, + char ***argv) +{ + gdk_parse_args (argc, argv); - XFree(ret_children); + return gdk_display_open_default_libgtk_only () != NULL; } -gchar * -gdk_get_display(void) +void +gdk_init (int *argc, char ***argv) { - return (gchar *)XDisplayName (gdk_display_name); + if (!gdk_init_check (argc, argv)) + { + g_warning ("cannot open display: %s", gdk_get_display_arg_name ()); + exit(1); + } } -gint -gdk_send_xevent (Window window, gboolean propagate, glong event_mask, - XEvent *event_send) -{ - Status result; - - gdk_error_code = 0; - - gdk_error_warnings = 0; - result = XSendEvent (gdk_display, window, propagate, event_mask, event_send); - XSync (gdk_display, False); - gdk_error_warnings = 1; - - return result && (gdk_error_code != -1); -} +/* + *-------------------------------------------------------------- + * gdk_exit + * + * Restores the library to an un-itialized state and exits + * the program using the "exit" system call. + * + * Arguments: + * "errorcode" is the error value to pass to "exit". + * + * Results: + * Allocated structures are freed and the program exits + * cleanly. + * + * Side effects: + * + *-------------------------------------------------------------- + */ -gchar* -gdk_keyval_name (guint keyval) +void +gdk_exit (gint errorcode) { - return XKeysymToString (keyval); + exit (errorcode); } -guint -gdk_keyval_from_name (const gchar *keyval_name) +void +gdk_threads_enter () { - g_return_val_if_fail (keyval_name != NULL, 0); - - return XStringToKeysym (keyval_name); + GDK_THREADS_ENTER (); } -guint -gdk_keyval_to_upper (guint keyval) +void +gdk_threads_leave () { - if (keyval) - { - KeySym lower_val = 0; - KeySym upper_val = 0; - - XConvertCase (keyval, &lower_val, &upper_val); - return upper_val; - } - return 0; + GDK_THREADS_LEAVE (); } -guint -gdk_keyval_to_lower (guint keyval) +/** + * gdk_threads_init: + * + * Initializes GDK so that it can be used from multiple threads + * in conjunction with gdk_threads_enter() and gdk_threads_leave(). + * g_thread_init() must be called previous to this function. + * + * This call must be made before any use of the main loop from + * GTK+; to be safe, call it before gtk_init(). + **/ +void +gdk_threads_init () { - if (keyval) - { - KeySym lower_val = 0; - KeySym upper_val = 0; + if (!g_thread_supported ()) + g_error ("g_thread_init() must be called before gdk_threads_init()"); - XConvertCase (keyval, &lower_val, &upper_val); - return lower_val; - } - return 0; + gdk_threads_mutex = g_mutex_new (); } -gboolean -gdk_keyval_is_upper (guint keyval) +G_CONST_RETURN char * +gdk_get_program_class (void) { - if (keyval) - { - KeySym lower_val = 0; - KeySym upper_val = 0; - - XConvertCase (keyval, &lower_val, &upper_val); - return upper_val == keyval; - } - return TRUE; + return gdk_progclass; } -gboolean -gdk_keyval_is_lower (guint keyval) +void +gdk_set_program_class (const char *program_class) { - if (keyval) - { - KeySym lower_val = 0; - KeySym upper_val = 0; + if (gdk_progclass) + g_free (gdk_progclass); - XConvertCase (keyval, &lower_val, &upper_val); - return lower_val == keyval; - } - return TRUE; + gdk_progclass = g_strdup (program_class); }