1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <string.h> /* For memset() */
31 #include "gdkinternals.h"
33 typedef struct _GdkIOClosure GdkIOClosure;
37 GdkInputFunction function;
38 GdkInputCondition condition;
39 GdkDestroyNotify notify;
43 /* Private variable declarations
46 GdkEventFunc _gdk_event_func = NULL; /* Callback for events */
47 gpointer _gdk_event_data = NULL;
48 GDestroyNotify _gdk_event_notify = NULL;
50 /*********************************************
51 * Functions for maintaining the event queue *
52 *********************************************/
55 * _gdk_event_queue_find_first:
56 * @display: a #GdkDisplay
58 * Find the first event on the queue that is not still
61 * Return value: Pointer to the list node for that event, or NULL.
64 _gdk_event_queue_find_first (GdkDisplay *display)
66 GList *tmp_list = display->queued_events;
70 GdkEventPrivate *event = tmp_list->data;
71 if (!(event->flags & GDK_EVENT_PENDING))
74 tmp_list = g_list_next (tmp_list);
81 * _gdk_event_queue_append:
82 * @display: a #GdkDisplay
83 * @event: Event to append.
85 * Appends an event onto the tail of the event queue.
87 * Returns: the newly appended list node.
90 _gdk_event_queue_append (GdkDisplay *display,
93 display->queued_tail = g_list_append (display->queued_tail, event);
95 if (!display->queued_events)
96 display->queued_events = display->queued_tail;
98 display->queued_tail = display->queued_tail->next;
100 return display->queued_tail;
104 * _gdk_event_queue_remove_link:
105 * @display: a #GdkDisplay
106 * @node: node to remove
108 * Removes a specified list node from the event queue.
111 _gdk_event_queue_remove_link (GdkDisplay *display,
115 node->prev->next = node->next;
117 display->queued_events = node->next;
120 node->next->prev = node->prev;
122 display->queued_tail = node->prev;
126 * _gdk_event_unqueue:
127 * @display: a #GdkDisplay
129 * Removes and returns the first event from the event
130 * queue that is not still being filled in.
132 * Return value: the event, or %NULL. Ownership is transferred
136 _gdk_event_unqueue (GdkDisplay *display)
138 GdkEvent *event = NULL;
141 tmp_list = _gdk_event_queue_find_first (display);
145 event = tmp_list->data;
146 _gdk_event_queue_remove_link (display, tmp_list);
147 g_list_free_1 (tmp_list);
154 * gdk_event_handler_set:
155 * @func: the function to call to handle events from GDK.
156 * @data: user data to pass to the function.
157 * @notify: the function to call when the handler function is removed, i.e. when
158 * gdk_event_handler_set() is called with another event handler.
160 * Sets the function to call to handle all events from GDK.
162 * Note that GTK+ uses this to install its own event handler, so it is
163 * usually not useful for GTK+ applications. (Although an application
164 * can call this function then call gtk_main_do_event() to pass
168 gdk_event_handler_set (GdkEventFunc func,
170 GDestroyNotify notify)
172 if (_gdk_event_notify)
173 (*_gdk_event_notify) (_gdk_event_data);
175 _gdk_event_func = func;
176 _gdk_event_data = data;
177 _gdk_event_notify = notify;
183 * Checks all open displays for a #GdkEvent to process,to be processed
184 * on, fetching events from the windowing system if necessary.
185 * See gdk_display_get_event().
187 * Return value: the next #GdkEvent to be processed, or %NULL if no events
188 * are pending. The returned #GdkEvent should be freed with gdk_event_free().
195 for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
197 GdkEvent *event = gdk_display_get_event (tmp_list->data);
208 * If there is an event waiting in the event queue of some open
209 * display, returns a copy of it. See gdk_display_peek_event().
211 * Return value: a copy of the first #GdkEvent on some event queue, or %NULL if no
212 * events are in any queues. The returned #GdkEvent should be freed with
216 gdk_event_peek (void)
220 for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next)
222 GdkEvent *event = gdk_display_peek_event (tmp_list->data);
232 * @event: a #GdkEvent.
234 * Appends a copy of the given event onto the front of the event
235 * queue for event->any.window's display, or the default event
236 * queue if event->any.window is %NULL. See gdk_display_put_event().
239 gdk_event_put (GdkEvent *event)
243 g_return_if_fail (event != NULL);
245 if (event->any.window)
246 display = gdk_drawable_get_display (event->any.window);
250 g_message ("Falling back to default display for gdk_event_put()"));
251 display = gdk_display_get_default ();
254 gdk_display_put_event (display, event);
257 static GMemChunk *event_chunk = NULL;
258 static GHashTable *event_hash = NULL;
262 * @type: a #GdkEventType
264 * Creates a new event of the given type. All fields are set to 0.
266 * Return value: a newly-allocated #GdkEvent. The returned #GdkEvent
267 * should be freed with gdk_event_free().
272 gdk_event_new (GdkEventType type)
274 GdkEventPrivate *new_private;
277 if (event_chunk == NULL)
279 event_chunk = g_mem_chunk_new ("events",
280 sizeof (GdkEventPrivate),
283 event_hash = g_hash_table_new (g_direct_hash, NULL);
286 new_private = g_chunk_new (GdkEventPrivate, event_chunk);
287 memset (new_private, 0, sizeof (GdkEventPrivate));
289 new_private->flags = 0;
290 new_private->screen = NULL;
292 g_hash_table_insert (event_hash, new_private, GUINT_TO_POINTER (1));
294 new_event = (GdkEvent *) new_private;
296 new_event->any.type = type;
299 * Bytewise 0 initialization is reasonable for most of the
300 * current event types. Explicitely initialize double fields
301 * since I trust bytewise 0 == 0. less than for integers
306 case GDK_MOTION_NOTIFY:
307 new_event->motion.x = 0.;
308 new_event->motion.y = 0.;
309 new_event->motion.x_root = 0.;
310 new_event->motion.y_root = 0.;
312 case GDK_BUTTON_PRESS:
313 case GDK_2BUTTON_PRESS:
314 case GDK_3BUTTON_PRESS:
315 case GDK_BUTTON_RELEASE:
316 new_event->button.x = 0.;
317 new_event->button.y = 0.;
318 new_event->button.x_root = 0.;
319 new_event->button.y_root = 0.;
322 new_event->scroll.x = 0.;
323 new_event->scroll.y = 0.;
324 new_event->scroll.x_root = 0.;
325 new_event->scroll.y_root = 0.;
327 case GDK_ENTER_NOTIFY:
328 case GDK_LEAVE_NOTIFY:
329 new_event->crossing.x = 0.;
330 new_event->crossing.y = 0.;
331 new_event->crossing.x_root = 0.;
332 new_event->crossing.y_root = 0.;
342 gdk_event_is_allocated (GdkEvent *event)
345 return g_hash_table_lookup (event_hash, event) != NULL;
352 * @event: a #GdkEvent
354 * Copies a #GdkEvent, copying or incrementing the reference count of the
355 * resources associated with it (e.g. #GdkWindow's and strings).
357 * Return value: a copy of @event. The returned #GdkEvent should be freed with
361 gdk_event_copy (GdkEvent *event)
363 GdkEventPrivate *new_private;
366 g_return_val_if_fail (event != NULL, NULL);
368 new_event = gdk_event_new (GDK_NOTHING);
369 new_private = (GdkEventPrivate *)new_event;
372 if (new_event->any.window)
373 g_object_ref (new_event->any.window);
375 if (gdk_event_is_allocated (event))
377 GdkEventPrivate *private = (GdkEventPrivate *)event;
379 new_private->screen = private->screen;
382 switch (event->any.type)
385 case GDK_KEY_RELEASE:
386 new_event->key.string = g_strdup (event->key.string);
389 case GDK_ENTER_NOTIFY:
390 case GDK_LEAVE_NOTIFY:
391 if (event->crossing.subwindow != NULL)
392 g_object_ref (event->crossing.subwindow);
397 case GDK_DRAG_MOTION:
398 case GDK_DRAG_STATUS:
400 case GDK_DROP_FINISHED:
401 g_object_ref (event->dnd.context);
405 if (event->expose.region)
406 new_event->expose.region = gdk_region_copy (event->expose.region);
410 new_event->setting.name = g_strdup (new_event->setting.name);
413 case GDK_BUTTON_PRESS:
414 case GDK_BUTTON_RELEASE:
415 if (event->button.axes)
416 new_event->button.axes = g_memdup (event->button.axes,
417 sizeof (gdouble) * event->button.device->num_axes);
420 case GDK_MOTION_NOTIFY:
421 if (event->motion.axes)
422 new_event->motion.axes = g_memdup (event->motion.axes,
423 sizeof (gdouble) * event->motion.device->num_axes);
436 * @event: a #GdkEvent.
438 * Frees a #GdkEvent, freeing or decrementing any resources associated with it.
439 * Note that this function should only be called with events returned from
440 * functions such as gdk_event_peek(), gdk_event_get(),
441 * gdk_event_get_graphics_expose() and gdk_event_copy().
444 gdk_event_free (GdkEvent *event)
446 g_return_if_fail (event != NULL);
448 g_assert (event_chunk != NULL); /* paranoid */
450 if (event->any.window)
451 g_object_unref (event->any.window);
453 switch (event->any.type)
456 case GDK_KEY_RELEASE:
457 g_free (event->key.string);
460 case GDK_ENTER_NOTIFY:
461 case GDK_LEAVE_NOTIFY:
462 if (event->crossing.subwindow != NULL)
463 g_object_unref (event->crossing.subwindow);
468 case GDK_DRAG_MOTION:
469 case GDK_DRAG_STATUS:
471 case GDK_DROP_FINISHED:
472 g_object_unref (event->dnd.context);
475 case GDK_BUTTON_PRESS:
476 case GDK_BUTTON_RELEASE:
477 if (event->button.axes)
478 g_free (event->button.axes);
482 if (event->expose.region)
483 gdk_region_destroy (event->expose.region);
486 case GDK_MOTION_NOTIFY:
487 if (event->motion.axes)
488 g_free (event->motion.axes);
492 g_free (event->setting.name);
499 g_hash_table_remove (event_hash, event);
500 g_mem_chunk_free (event_chunk, event);
504 * gdk_event_get_time:
505 * @event: a #GdkEvent
507 * Returns the time stamp from @event, if there is one; otherwise
508 * returns #GDK_CURRENT_TIME. If @event is %NULL, returns #GDK_CURRENT_TIME.
510 * Return value: time stamp field from @event
513 gdk_event_get_time (GdkEvent *event)
518 case GDK_MOTION_NOTIFY:
519 return event->motion.time;
520 case GDK_BUTTON_PRESS:
521 case GDK_2BUTTON_PRESS:
522 case GDK_3BUTTON_PRESS:
523 case GDK_BUTTON_RELEASE:
524 return event->button.time;
526 return event->scroll.time;
528 case GDK_KEY_RELEASE:
529 return event->key.time;
530 case GDK_ENTER_NOTIFY:
531 case GDK_LEAVE_NOTIFY:
532 return event->crossing.time;
533 case GDK_PROPERTY_NOTIFY:
534 return event->property.time;
535 case GDK_SELECTION_CLEAR:
536 case GDK_SELECTION_REQUEST:
537 case GDK_SELECTION_NOTIFY:
538 return event->selection.time;
539 case GDK_PROXIMITY_IN:
540 case GDK_PROXIMITY_OUT:
541 return event->proximity.time;
544 case GDK_DRAG_MOTION:
545 case GDK_DRAG_STATUS:
547 case GDK_DROP_FINISHED:
548 return event->dnd.time;
549 case GDK_CLIENT_EVENT:
550 case GDK_VISIBILITY_NOTIFY:
553 case GDK_FOCUS_CHANGE:
560 case GDK_WINDOW_STATE:
562 /* return current time */
566 return GDK_CURRENT_TIME;
570 * gdk_event_get_state:
571 * @event: a #GdkEvent or NULL
572 * @state: return location for state
574 * If the event contains a "state" field, puts that field in @state. Otherwise
575 * stores an empty state (0). Returns %TRUE if there was a state field
576 * in the event. @event may be %NULL, in which case it's treated
577 * as if the event had no state field.
579 * Return value: %TRUE if there was a state field in the event
582 gdk_event_get_state (GdkEvent *event,
583 GdkModifierType *state)
585 g_return_val_if_fail (state != NULL, FALSE);
590 case GDK_MOTION_NOTIFY:
591 *state = event->motion.state;
593 case GDK_BUTTON_PRESS:
594 case GDK_2BUTTON_PRESS:
595 case GDK_3BUTTON_PRESS:
596 case GDK_BUTTON_RELEASE:
597 *state = event->button.state;
600 *state = event->scroll.state;
603 case GDK_KEY_RELEASE:
604 *state = event->key.state;
606 case GDK_ENTER_NOTIFY:
607 case GDK_LEAVE_NOTIFY:
608 *state = event->crossing.state;
610 case GDK_PROPERTY_NOTIFY:
611 *state = event->property.state;
613 case GDK_VISIBILITY_NOTIFY:
614 case GDK_CLIENT_EVENT:
617 case GDK_FOCUS_CHANGE:
618 case GDK_SELECTION_CLEAR:
619 case GDK_SELECTION_REQUEST:
620 case GDK_SELECTION_NOTIFY:
621 case GDK_PROXIMITY_IN:
622 case GDK_PROXIMITY_OUT:
625 case GDK_DRAG_MOTION:
626 case GDK_DRAG_STATUS:
628 case GDK_DROP_FINISHED:
635 case GDK_WINDOW_STATE:
646 * gdk_event_get_coords:
647 * @event: a #GdkEvent
648 * @x_win: location to put event window x coordinate
649 * @y_win: location to put event window y coordinate
651 * Extract the event window relative x/y coordinates from an event.
653 * Return value: %TRUE if the event delivered event window coordinates
656 gdk_event_get_coords (GdkEvent *event,
660 gdouble x = 0, y = 0;
661 gboolean fetched = TRUE;
663 g_return_val_if_fail (event != NULL, FALSE);
668 x = event->configure.x;
669 y = event->configure.y;
671 case GDK_ENTER_NOTIFY:
672 case GDK_LEAVE_NOTIFY:
673 x = event->crossing.x;
674 y = event->crossing.y;
680 case GDK_BUTTON_PRESS:
681 case GDK_2BUTTON_PRESS:
682 case GDK_3BUTTON_PRESS:
683 case GDK_BUTTON_RELEASE:
687 case GDK_MOTION_NOTIFY:
705 * gdk_event_get_root_coords:
706 * @event: a #GdkEvent
707 * @x_root: location to put root window x coordinate
708 * @y_root: location to put root window y coordinate
710 * Extract the root window relative x/y coordinates from an event.
712 * Return value: %TRUE if the event delivered root window coordinates
715 gdk_event_get_root_coords (GdkEvent *event,
719 gdouble x = 0, y = 0;
720 gboolean fetched = TRUE;
722 g_return_val_if_fail (event != NULL, FALSE);
726 case GDK_MOTION_NOTIFY:
727 x = event->motion.x_root;
728 y = event->motion.y_root;
730 case GDK_BUTTON_PRESS:
731 case GDK_2BUTTON_PRESS:
732 case GDK_3BUTTON_PRESS:
733 case GDK_BUTTON_RELEASE:
734 x = event->button.x_root;
735 y = event->button.y_root;
737 case GDK_ENTER_NOTIFY:
738 case GDK_LEAVE_NOTIFY:
739 x = event->crossing.x_root;
740 y = event->crossing.y_root;
744 case GDK_DRAG_MOTION:
745 case GDK_DRAG_STATUS:
747 case GDK_DROP_FINISHED:
748 x = event->dnd.x_root;
749 y = event->dnd.y_root;
765 * gdk_event_get_axis:
766 * @event: a #GdkEvent
767 * @axis_use: the axis use to look for
768 * @value: location to store the value found
770 * Extract the axis value for a particular axis use from
771 * an event structure.
773 * Return value: %TRUE if the specified axis was found, otherwise %FALSE
776 gdk_event_get_axis (GdkEvent *event,
783 g_return_val_if_fail (event != NULL, FALSE);
785 if (axis_use == GDK_AXIS_X || axis_use == GDK_AXIS_Y)
791 case GDK_MOTION_NOTIFY:
799 case GDK_BUTTON_PRESS:
800 case GDK_BUTTON_RELEASE:
804 case GDK_ENTER_NOTIFY:
805 case GDK_LEAVE_NOTIFY:
806 x = event->crossing.x;
807 y = event->crossing.y;
814 if (axis_use == GDK_AXIS_X && value)
816 if (axis_use == GDK_AXIS_Y && value)
821 else if (event->type == GDK_BUTTON_PRESS ||
822 event->type == GDK_BUTTON_RELEASE)
824 device = event->button.device;
825 axes = event->button.axes;
827 else if (event->type == GDK_MOTION_NOTIFY)
829 device = event->motion.device;
830 axes = event->motion.axes;
835 return gdk_device_get_axis (device, axes, axis_use, value);
839 * gdk_event_set_screen:
840 * @event: a #GdkEvent
841 * @screen: a #GdkScreen
843 * Sets the screen for @event to @screen. The event must
844 * have been allocated by GTK+, for instance, by
850 gdk_event_set_screen (GdkEvent *event,
853 GdkEventPrivate *private;
855 g_return_if_fail (gdk_event_is_allocated (event));
857 private = (GdkEventPrivate *)event;
859 private->screen = screen;
863 * gdk_event_get_screen:
864 * @event: a #GdkEvent
866 * Returns the screen for the event. The screen is
867 * typically the screen for <literal>event->any.window</literal>, but
868 * for events such as mouse events, it is the screen
869 * where the the pointer was when the event occurs -
870 * that is, the screen which has the root window
871 * to which <literal>event->motion.x_root</literal> and
872 * <literal>event->motion.y_root</literal> are relative.
874 * Return value: the screen for the event
879 gdk_event_get_screen (GdkEvent *event)
881 if (gdk_event_is_allocated (event))
883 GdkEventPrivate *private = (GdkEventPrivate *)event;
886 return private->screen;
889 if (event->any.window)
890 return gdk_drawable_get_screen (event->any.window);
896 * gdk_set_show_events:
897 * @show_events: %TRUE to output event debugging information.
899 * Sets whether a trace of received events is output.
900 * Note that GTK+ must be compiled with debugging (that is,
901 * configured using the <option>--enable-debug</option> option)
902 * to use this option.
905 gdk_set_show_events (gboolean show_events)
908 _gdk_debug_flags |= GDK_DEBUG_EVENTS;
910 _gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
914 * gdk_get_show_events:
916 * Gets whether event debugging output is enabled.
918 * Return value: %TRUE if event debugging output is enabled.
921 gdk_get_show_events (void)
923 return (_gdk_debug_flags & GDK_DEBUG_EVENTS) != 0;
927 gdk_io_destroy (gpointer data)
929 GdkIOClosure *closure = data;
932 closure->notify (closure->data);
937 /* What do we do with G_IO_NVAL?
939 #define READ_CONDITION (G_IO_IN | G_IO_HUP | G_IO_ERR)
940 #define WRITE_CONDITION (G_IO_OUT | G_IO_ERR)
941 #define EXCEPTION_CONDITION (G_IO_PRI)
944 gdk_io_invoke (GIOChannel *source,
945 GIOCondition condition,
948 GdkIOClosure *closure = data;
949 GdkInputCondition gdk_cond = 0;
951 if (condition & READ_CONDITION)
952 gdk_cond |= GDK_INPUT_READ;
953 if (condition & WRITE_CONDITION)
954 gdk_cond |= GDK_INPUT_WRITE;
955 if (condition & EXCEPTION_CONDITION)
956 gdk_cond |= GDK_INPUT_EXCEPTION;
958 if (closure->condition & gdk_cond)
959 closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
965 gdk_input_add_full (gint source,
966 GdkInputCondition condition,
967 GdkInputFunction function,
969 GdkDestroyNotify destroy)
972 GdkIOClosure *closure = g_new (GdkIOClosure, 1);
974 GIOCondition cond = 0;
976 closure->function = function;
977 closure->condition = condition;
978 closure->notify = destroy;
979 closure->data = data;
981 if (condition & GDK_INPUT_READ)
982 cond |= READ_CONDITION;
983 if (condition & GDK_INPUT_WRITE)
984 cond |= WRITE_CONDITION;
985 if (condition & GDK_INPUT_EXCEPTION)
986 cond |= EXCEPTION_CONDITION;
988 channel = g_io_channel_unix_new (source);
989 result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond,
991 closure, gdk_io_destroy);
992 g_io_channel_unref (channel);
998 gdk_input_add (gint source,
999 GdkInputCondition condition,
1000 GdkInputFunction function,
1003 return gdk_input_add_full (source, condition, function, data, NULL);
1007 gdk_input_remove (gint tag)
1009 g_source_remove (tag);
1013 gdk_synthesize_click (GdkDisplay *display,
1017 GdkEvent temp_event;
1019 g_return_if_fail (event != NULL);
1021 temp_event = *event;
1022 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
1024 gdk_display_put_event (display, &temp_event);
1028 _gdk_event_button_generate (GdkDisplay *display,
1031 if ((event->button.time < (display->button_click_time[1] + 2*display->double_click_time)) &&
1032 (event->button.window == display->button_window[1]) &&
1033 (event->button.button == display->button_number[1]) &&
1034 (ABS (event->button.x - display->button_x[1]) <= display->double_click_distance) &&
1035 (ABS (event->button.y - display->button_y[1]) <= display->double_click_distance))
1037 gdk_synthesize_click (display, event, 3);
1039 display->button_click_time[1] = 0;
1040 display->button_click_time[0] = 0;
1041 display->button_window[1] = NULL;
1042 display->button_window[0] = 0;
1043 display->button_number[1] = -1;
1044 display->button_number[0] = -1;
1045 display->button_x[0] = display->button_x[1] = 0;
1046 display->button_y[0] = display->button_y[1] = 0;
1048 else if ((event->button.time < (display->button_click_time[0] + display->double_click_time)) &&
1049 (event->button.window == display->button_window[0]) &&
1050 (event->button.button == display->button_number[0]) &&
1051 (ABS (event->button.x - display->button_x[0]) <= display->double_click_distance) &&
1052 (ABS (event->button.y - display->button_y[0]) <= display->double_click_distance))
1054 gdk_synthesize_click (display, event, 2);
1056 display->button_click_time[1] = display->button_click_time[0];
1057 display->button_click_time[0] = event->button.time;
1058 display->button_window[1] = display->button_window[0];
1059 display->button_window[0] = event->button.window;
1060 display->button_number[1] = display->button_number[0];
1061 display->button_number[0] = event->button.button;
1062 display->button_x[1] = display->button_x[0];
1063 display->button_x[0] = event->button.x;
1064 display->button_y[1] = display->button_y[0];
1065 display->button_y[0] = event->button.y;
1069 display->button_click_time[1] = 0;
1070 display->button_click_time[0] = event->button.time;
1071 display->button_window[1] = NULL;
1072 display->button_window[0] = event->button.window;
1073 display->button_number[1] = -1;
1074 display->button_number[0] = event->button.button;
1075 display->button_x[1] = 0;
1076 display->button_x[0] = event->button.x;
1077 display->button_y[1] = 0;
1078 display->button_y[0] = event->button.y;
1083 gdk_synthesize_window_state (GdkWindow *window,
1084 GdkWindowState unset_flags,
1085 GdkWindowState set_flags)
1087 GdkEvent temp_event;
1090 g_return_if_fail (window != NULL);
1092 temp_event.window_state.window = window;
1093 temp_event.window_state.type = GDK_WINDOW_STATE;
1094 temp_event.window_state.send_event = FALSE;
1096 old = ((GdkWindowObject*) temp_event.window_state.window)->state;
1098 temp_event.window_state.new_window_state = old;
1099 temp_event.window_state.new_window_state |= set_flags;
1100 temp_event.window_state.new_window_state &= ~unset_flags;
1101 temp_event.window_state.changed_mask = temp_event.window_state.new_window_state ^ old;
1103 if (temp_event.window_state.new_window_state == old)
1104 return; /* No actual work to do, nothing changed. */
1106 /* Actually update the field in GdkWindow, this is sort of an odd
1107 * place to do it, but seems like the safest since it ensures we expose no
1108 * inconsistent state to the user.
1111 ((GdkWindowObject*) window)->state = temp_event.window_state.new_window_state;
1113 /* We only really send the event to toplevels, since
1114 * all the window states don't apply to non-toplevels.
1115 * Non-toplevels do use the GDK_WINDOW_STATE_WITHDRAWN flag
1116 * internally so we needed to update window->state.
1118 switch (((GdkWindowObject*) window)->window_type)
1120 case GDK_WINDOW_TOPLEVEL:
1121 case GDK_WINDOW_DIALOG:
1122 case GDK_WINDOW_TEMP: /* ? */
1123 gdk_display_put_event (gdk_drawable_get_display (window), &temp_event);
1126 case GDK_WINDOW_FOREIGN:
1127 case GDK_WINDOW_ROOT:
1128 case GDK_WINDOW_CHILD:
1134 * gdk_display_set_double_click_time:
1135 * @display: a #GdkDisplay
1136 * @msec: double click time in milliseconds (thousandths of a second)
1138 * Sets the double click time (two clicks within this time interval
1139 * count as a double click and result in a #GDK_2BUTTON_PRESS event).
1140 * Applications should <emphasis>not</emphasis> set this, it is a global
1141 * user-configured setting.
1146 gdk_display_set_double_click_time (GdkDisplay *display,
1149 display->double_click_time = msec;
1153 * gdk_set_double_click_time:
1154 * @msec: double click time in milliseconds (thousandths of a second)
1156 * Set the double click time for the default display. See
1157 * gdk_display_set_double_click_time().
1158 * See also gdk_display_set_double_click_distance().
1159 * Applications should <emphasis>not</emphasis> set this, it is a
1160 * global user-configured setting.
1163 gdk_set_double_click_time (guint msec)
1165 gdk_display_set_double_click_time (gdk_display_get_default (), msec);
1169 * gdk_display_set_double_click_distance:
1170 * @display: a #GdkDisplay
1171 * @distance: distance in pixels
1173 * Sets the double click distance (two clicks within this distance
1174 * count as a double click and result in a #GDK_2BUTTON_PRESS event).
1175 * See also gdk_display_set_double_click_time().
1176 * Applications should <emphasis>not</emphasis> set this, it is a global
1177 * user-configured setting.
1182 gdk_display_set_double_click_distance (GdkDisplay *display,
1185 display->double_click_distance = distance;
1189 gdk_event_get_type (void)
1191 static GType our_type = 0;
1194 our_type = g_boxed_type_register_static ("GdkEvent",
1195 (GBoxedCopyFunc)gdk_event_copy,
1196 (GBoxedFreeFunc)gdk_event_free);
1202 * @name: the name of the setting.
1203 * @value: location to store the value of the setting.
1205 * Obtains a desktop-wide setting, such as the double-click time,
1206 * for the default screen. See gdk_screen_get_setting().
1208 * Returns : %TRUE if the setting existed and a value was stored
1209 * in @value, %FALSE otherwise.
1212 gdk_setting_get (const gchar *name,
1215 return gdk_screen_get_setting (gdk_screen_get_default (), name, value);