diff options
author | Owen Taylor <otaylor@redhat.com> | 1999-01-12 23:27:30 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 1999-01-12 23:27:30 +0000 |
commit | 24f6d8b887ffdd24e1841340c81b54e41811e165 (patch) | |
tree | a320b3efe6053ceb3d4e17e06d515f0d943fd989 | |
parent | 5a86cbd116bd55fbb31b3c90baca8cd30dd395d0 (diff) | |
download | gtk+-24f6d8b887ffdd24e1841340c81b54e41811e165.tar.gz |
Add a drag_data_received handler for the label.
Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com>
* gtk/testdnd.c (label_drag_data_received): Add
a drag_data_received handler for the label.
Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com>
* gdk/gdkevents.c: Removed the putback_events queue,
since it was causing problems with event ordering -
just keep a single queue. If we need it, we can
add priorities to events.
* gdk/gdkevents.c: Annotate events with flags - we allocate
a GdkEventPrivate structure in gdk_event_new() and use these
flags to mark an event being translated as "pending" -
I.e., not yet ready to be dequeued. So we can put
the event on the queue and get the order of the
events right. (This solves the double-click problems)
* gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy
of the next event on the event queue.
* gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek()
to check the next event without causing event queue
reordering.
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 26 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 26 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 26 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 26 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 26 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 26 | ||||
-rw-r--r-- | gdk/gdk.h | 2 | ||||
-rw-r--r-- | gdk/gdkevents.c | 205 | ||||
-rw-r--r-- | gdk/x11/gdkevents-x11.c | 205 | ||||
-rw-r--r-- | gtk/gtkmain.c | 14 | ||||
-rw-r--r-- | gtk/testdnd.c | 24 | ||||
-rw-r--r-- | tests/testdnd.c | 24 |
13 files changed, 536 insertions, 120 deletions
@@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index f7a6ea3bff..0dd7d9af51 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index f7a6ea3bff..0dd7d9af51 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index f7a6ea3bff..0dd7d9af51 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index f7a6ea3bff..0dd7d9af51 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index f7a6ea3bff..0dd7d9af51 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index f7a6ea3bff..0dd7d9af51 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,29 @@ +Tue Jan 12 18:30:51 1999 Owen Taylor <otaylor@redhat.com> + + * gtk/testdnd.c (label_drag_data_received): Add + a drag_data_received handler for the label. + +Tue Jan 12 15:01:50 1999 Owen Taylor <otaylor@redhat.com> + + * gdk/gdkevents.c: Removed the putback_events queue, + since it was causing problems with event ordering - + just keep a single queue. If we need it, we can + add priorities to events. + + * gdk/gdkevents.c: Annotate events with flags - we allocate + a GdkEventPrivate structure in gdk_event_new() and use these + flags to mark an event being translated as "pending" - + I.e., not yet ready to be dequeued. So we can put + the event on the queue and get the order of the + events right. (This solves the double-click problems) + + * gdk/gdk.h gdk/gdkevents.h: Add gdk_event_peek() to get a copy + of the next event on the event queue. + + * gtk/gtkmain.c (gtk_main_do_event): Use gdk_event_peek() + to check the next event without causing event queue + reordering. + Tue Jan 12 15:41:20 1999 Owen Taylor <otaylor@redhat.com> * gtk/gtklabel.c (gtk_label_expose): Minor fix @@ -37,6 +37,8 @@ gchar* gdk_set_locale (void); gboolean gdk_events_pending (void); GdkEvent* gdk_event_get (void); + +GdkEvent* gdk_event_peek (void); GdkEvent* gdk_event_get_graphics_expose (GdkWindow *window); void gdk_event_put (GdkEvent *event); diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index e8b0444467..24e1b67a04 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -32,12 +32,20 @@ typedef struct _GdkIOClosure GdkIOClosure; +typedef struct _GdkEventPrivate GdkEventPrivate; #define DOUBLE_CLICK_TIME 250 #define TRIPLE_CLICK_TIME 500 #define DOUBLE_CLICK_DIST 5 #define TRIPLE_CLICK_DIST 5 +typedef enum { + /* Following flag is set for events on the event queue during + * translation and cleared afterwards. + */ + GDK_EVENT_PENDING = 1 << 0 +} GdkEventFlags; + struct _GdkIOClosure { GdkInputFunction function; GdkInputCondition condition; @@ -45,6 +53,11 @@ struct _GdkIOClosure { gpointer data; }; +struct _GdkEventPrivate { + GdkEvent event; + guint flags; +}; + /* * Private function declarations */ @@ -105,14 +118,10 @@ static GDestroyNotify event_notify; static GList *client_filters; /* Filters for client messages */ /* FIFO's for event queue, and for events put back using - * gdk_event_put(). We keep separate queues so that - * we can make the putback events both FIFO and preemptive - * of pending events. + * gdk_event_put(). */ static GList *queued_events = NULL; static GList *queued_tail = NULL; -static GList *putback_events = NULL; -static GList *putback_tail = NULL; static GSourceFuncs event_funcs = { gdk_event_prepare, @@ -123,6 +132,77 @@ static GSourceFuncs event_funcs = { GPollFD event_poll_fd; +/********************************************* + * Functions for maintaining the event queue * + *********************************************/ + +/************************************************************* + * gdk_event_queue_find_first: + * Find the first event on the queue that is not still + * being filled in. + * arguments: + * + * results: + * Pointer to the list node for that event, or NULL + *************************************************************/ + +static GList * +gdk_event_queue_find_first (void) +{ + GList *tmp_list = queued_events; + + while (tmp_list) + { + GdkEventPrivate *event = queued_events->data; + if (!(event->flags & GDK_EVENT_PENDING)) + return tmp_list; + } + + return NULL; +} + +/************************************************************* + * gdk_event_queue_remove_link: + * Remove a specified list node from the event queue. + * arguments: + * node: Node to remove. + * results: + *************************************************************/ + +static void +gdk_event_queue_remove_link (GList *node) +{ + if (node->prev) + node->prev->next = node->next; + else + queued_events = node->next; + + if (node->next) + node->next->prev = node->prev; + else + queued_tail = node->prev; + +} + +/************************************************************* + * gdk_event_queue_append: + * Append an event onto the tail of the event queue. + * arguments: + * event: Event to append. + * results: + *************************************************************/ + +static void +gdk_event_queue_append (GdkEvent *event) +{ + queued_tail = g_list_append(queued_tail, event); + + if (!queued_events) + queued_events = queued_tail; + else + queued_tail = queued_tail->next; +} + void gdk_events_init (void) { @@ -137,10 +217,6 @@ gdk_events_init (void) g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS); - /* 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. - */ button_click_time[0] = 0; button_click_time[1] = 0; button_window[0] = NULL; @@ -171,7 +247,7 @@ gdk_events_init (void) gboolean gdk_events_pending (void) { - return (queued_events || putback_events); + return (gdk_event_queue_find_first() || XPending (gdk_display)); } /* @@ -451,11 +527,9 @@ gdk_event_handler_set (GdkEventFunc func, * Arguments: * * Results: - * If an event was received that we care about, returns + * If an event is waiting 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. + * Otherwise, returns NULL. * * Side effects: * @@ -470,6 +544,38 @@ gdk_event_get (void) return gdk_event_unqueue(); } +/* + *-------------------------------------------------------------- + * gdk_event_peek + * + * Gets the next event. + * + * Arguments: + * + * Results: + * If an event is waiting that we care about, returns + * a copy of that event, but does not remove it from + * the queue. The pointer is to be freed with gdk_event_free. + * Otherwise, returns NULL. + * + * Side effects: + * + *-------------------------------------------------------------- + */ + +GdkEvent * +gdk_event_peek (void) +{ + GList *tmp_list; + + tmp_list = gdk_event_queue_find_first (); + + if (tmp_list) + return gdk_event_copy (tmp_list->data); + else + return NULL; +} + void gdk_event_put (GdkEvent *event) { @@ -479,12 +585,7 @@ gdk_event_put (GdkEvent *event) new_event = gdk_event_copy (event); - putback_tail = g_list_append(putback_tail, new_event); - - if (!putback_events) - putback_events = putback_tail; - else - putback_tail = putback_tail->next; + gdk_event_queue_append (new_event); } /* @@ -510,17 +611,18 @@ static GMemChunk *event_chunk; static GdkEvent* gdk_event_new (void) { - GdkEvent *new_event; + GdkEventPrivate *new_event; if (event_chunk == NULL) event_chunk = g_mem_chunk_new ("events", - sizeof (GdkEvent), + sizeof (GdkEventPrivate), 4096, G_ALLOC_AND_FREE); - new_event = g_chunk_new (GdkEvent, event_chunk); + new_event = g_chunk_new (GdkEventPrivate, event_chunk); + new_event->flags = 0; - return new_event; + return (GdkEvent *)new_event; } GdkEvent* @@ -1835,10 +1937,11 @@ gdk_event_get_type (Display *display, static void gdk_events_queue (void) { + GList *node; GdkEvent *event; XEvent xevent; - while (!(putback_events || queued_events) && XPending (gdk_display)) + while (!gdk_event_queue_find_first() && XPending (gdk_display)) { #ifdef USE_XIM Window w = None; @@ -1867,18 +1970,22 @@ gdk_events_queue (void) event->any.window = NULL; event->any.send_event = FALSE; event->any.send_event = xevent.xany.send_event; - + + ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; + + gdk_event_queue_append (event); + node = queued_tail; + if (gdk_event_translate (event, &xevent)) { - queued_tail = g_list_append(queued_tail, event); - - if (!queued_events) - queued_events = queued_tail; - else - queued_tail = queued_tail->next; + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; } else - gdk_event_free (event); + { + gdk_event_queue_remove_link (node); + g_list_free_1 (node); + gdk_event_free (event); + } } } @@ -1894,7 +2001,7 @@ gdk_event_prepare (gpointer source_data, *timeout = -1; gdk_events_queue (); - retval = (queued_events || putback_events); + retval = (gdk_event_queue_find_first () != NULL); GDK_THREADS_LEAVE (); @@ -1912,7 +2019,7 @@ gdk_event_check (gpointer source_data, if (event_poll_fd.revents & G_IO_IN) gdk_events_queue (); - retval = (queued_events || putback_events); + retval = (gdk_event_queue_find_first () != NULL); GDK_THREADS_LEAVE (); @@ -1922,29 +2029,17 @@ gdk_event_check (gpointer source_data, static GdkEvent * gdk_event_unqueue (void) { - GdkEvent *event; - GList *tmp_list, **head, **tail; + GdkEvent *event = NULL; + GList *tmp_list; - if (putback_events) - { - head = &putback_events; - tail = &putback_tail; - } - else if (queued_events) + tmp_list = gdk_event_queue_find_first (); + + if (tmp_list) { - head = &queued_events; - tail = &queued_tail; + event = tmp_list->data; + gdk_event_queue_remove_link (tmp_list); + g_list_free_1 (tmp_list); } - else - return NULL; - - if (*head == *tail) - *tail = NULL; - - tmp_list = *head; - event = tmp_list->data; - *head = g_list_remove_link (tmp_list, tmp_list); - g_list_free_1 (tmp_list); return event; } diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index e8b0444467..24e1b67a04 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -32,12 +32,20 @@ typedef struct _GdkIOClosure GdkIOClosure; +typedef struct _GdkEventPrivate GdkEventPrivate; #define DOUBLE_CLICK_TIME 250 #define TRIPLE_CLICK_TIME 500 #define DOUBLE_CLICK_DIST 5 #define TRIPLE_CLICK_DIST 5 +typedef enum { + /* Following flag is set for events on the event queue during + * translation and cleared afterwards. + */ + GDK_EVENT_PENDING = 1 << 0 +} GdkEventFlags; + struct _GdkIOClosure { GdkInputFunction function; GdkInputCondition condition; @@ -45,6 +53,11 @@ struct _GdkIOClosure { gpointer data; }; +struct _GdkEventPrivate { + GdkEvent event; + guint flags; +}; + /* * Private function declarations */ @@ -105,14 +118,10 @@ static GDestroyNotify event_notify; static GList *client_filters; /* Filters for client messages */ /* FIFO's for event queue, and for events put back using - * gdk_event_put(). We keep separate queues so that - * we can make the putback events both FIFO and preemptive - * of pending events. + * gdk_event_put(). */ static GList *queued_events = NULL; static GList *queued_tail = NULL; -static GList *putback_events = NULL; -static GList *putback_tail = NULL; static GSourceFuncs event_funcs = { gdk_event_prepare, @@ -123,6 +132,77 @@ static GSourceFuncs event_funcs = { GPollFD event_poll_fd; +/********************************************* + * Functions for maintaining the event queue * + *********************************************/ + +/************************************************************* + * gdk_event_queue_find_first: + * Find the first event on the queue that is not still + * being filled in. + * arguments: + * + * results: + * Pointer to the list node for that event, or NULL + *************************************************************/ + +static GList * +gdk_event_queue_find_first (void) +{ + GList *tmp_list = queued_events; + + while (tmp_list) + { + GdkEventPrivate *event = queued_events->data; + if (!(event->flags & GDK_EVENT_PENDING)) + return tmp_list; + } + + return NULL; +} + +/************************************************************* + * gdk_event_queue_remove_link: + * Remove a specified list node from the event queue. + * arguments: + * node: Node to remove. + * results: + *************************************************************/ + +static void +gdk_event_queue_remove_link (GList *node) +{ + if (node->prev) + node->prev->next = node->next; + else + queued_events = node->next; + + if (node->next) + node->next->prev = node->prev; + else + queued_tail = node->prev; + +} + +/************************************************************* + * gdk_event_queue_append: + * Append an event onto the tail of the event queue. + * arguments: + * event: Event to append. + * results: + *************************************************************/ + +static void +gdk_event_queue_append (GdkEvent *event) +{ + queued_tail = g_list_append(queued_tail, event); + + if (!queued_events) + queued_events = queued_tail; + else + queued_tail = queued_tail->next; +} + void gdk_events_init (void) { @@ -137,10 +217,6 @@ gdk_events_init (void) g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS); - /* 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. - */ button_click_time[0] = 0; button_click_time[1] = 0; button_window[0] = NULL; @@ -171,7 +247,7 @@ gdk_events_init (void) gboolean gdk_events_pending (void) { - return (queued_events || putback_events); + return (gdk_event_queue_find_first() || XPending (gdk_display)); } /* @@ -451,11 +527,9 @@ gdk_event_handler_set (GdkEventFunc func, * Arguments: * * Results: - * If an event was received that we care about, returns + * If an event is waiting 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. + * Otherwise, returns NULL. * * Side effects: * @@ -470,6 +544,38 @@ gdk_event_get (void) return gdk_event_unqueue(); } +/* + *-------------------------------------------------------------- + * gdk_event_peek + * + * Gets the next event. + * + * Arguments: + * + * Results: + * If an event is waiting that we care about, returns + * a copy of that event, but does not remove it from + * the queue. The pointer is to be freed with gdk_event_free. + * Otherwise, returns NULL. + * + * Side effects: + * + *-------------------------------------------------------------- + */ + +GdkEvent * +gdk_event_peek (void) +{ + GList *tmp_list; + + tmp_list = gdk_event_queue_find_first (); + + if (tmp_list) + return gdk_event_copy (tmp_list->data); + else + return NULL; +} + void gdk_event_put (GdkEvent *event) { @@ -479,12 +585,7 @@ gdk_event_put (GdkEvent *event) new_event = gdk_event_copy (event); - putback_tail = g_list_append(putback_tail, new_event); - - if (!putback_events) - putback_events = putback_tail; - else - putback_tail = putback_tail->next; + gdk_event_queue_append (new_event); } /* @@ -510,17 +611,18 @@ static GMemChunk *event_chunk; static GdkEvent* gdk_event_new (void) { - GdkEvent *new_event; + GdkEventPrivate *new_event; if (event_chunk == NULL) event_chunk = g_mem_chunk_new ("events", - sizeof (GdkEvent), + sizeof (GdkEventPrivate), 4096, G_ALLOC_AND_FREE); - new_event = g_chunk_new (GdkEvent, event_chunk); + new_event = g_chunk_new (GdkEventPrivate, event_chunk); + new_event->flags = 0; - return new_event; + return (GdkEvent *)new_event; } GdkEvent* @@ -1835,10 +1937,11 @@ gdk_event_get_type (Display *display, static void gdk_events_queue (void) { + GList *node; GdkEvent *event; XEvent xevent; - while (!(putback_events || queued_events) && XPending (gdk_display)) + while (!gdk_event_queue_find_first() && XPending (gdk_display)) { #ifdef USE_XIM Window w = None; @@ -1867,18 +1970,22 @@ gdk_events_queue (void) event->any.window = NULL; event->any.send_event = FALSE; event->any.send_event = xevent.xany.send_event; - + + ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; + + gdk_event_queue_append (event); + node = queued_tail; + if (gdk_event_translate (event, &xevent)) { - queued_tail = g_list_append(queued_tail, event); - - if (!queued_events) - queued_events = queued_tail; - else - queued_tail = queued_tail->next; + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; } else - gdk_event_free (event); + { + gdk_event_queue_remove_link (node); + g_list_free_1 (node); + gdk_event_free (event); + } } } @@ -1894,7 +2001,7 @@ gdk_event_prepare (gpointer source_data, *timeout = -1; gdk_events_queue (); - retval = (queued_events || putback_events); + retval = (gdk_event_queue_find_first () != NULL); GDK_THREADS_LEAVE (); @@ -1912,7 +2019,7 @@ gdk_event_check (gpointer source_data, if (event_poll_fd.revents & G_IO_IN) gdk_events_queue (); - retval = (queued_events || putback_events); + retval = (gdk_event_queue_find_first () != NULL); GDK_THREADS_LEAVE (); @@ -1922,29 +2029,17 @@ gdk_event_check (gpointer source_data, static GdkEvent * gdk_event_unqueue (void) { - GdkEvent *event; - GList *tmp_list, **head, **tail; + GdkEvent *event = NULL; + GList *tmp_list; - if (putback_events) - { - head = &putback_events; - tail = &putback_tail; - } - else if (queued_events) + tmp_list = gdk_event_queue_find_first (); + + if (tmp_list) { - head = &queued_events; - tail = &queued_tail; + event = tmp_list->data; + gdk_event_queue_remove_link (tmp_list); + g_list_free_1 (tmp_list); } - else - return NULL; - - if (*head == *tail) - *tail = NULL; - - tmp_list = *head; - event = tmp_list->data; - *head = g_list_remove_link (tmp_list, tmp_list); - g_list_free_1 (tmp_list); return event; } diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 57f78d5172..4e04df9382 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -553,7 +553,7 @@ gtk_main_do_event (GdkEvent *event) /* If there are any events pending then get the next one. */ - next_event = gdk_event_get (); + next_event = gdk_event_peek (); /* Try to compress enter/leave notify events. These event * pairs occur when the mouse is dragged quickly across @@ -571,19 +571,17 @@ gtk_main_do_event (GdkEvent *event) (next_event->type != event->type) && (next_event->any.window == event->any.window)) { + /* Throw both the peeked copy and the queued copy away + */ + gdk_event_free (next_event); + next_event = gdk_event_get (); gdk_event_free (next_event); - next_event = NULL; return; } - if (next_event) - { - gdk_event_put (next_event); - gdk_event_free (next_event); - next_event = NULL; - } + gdk_event_free (next_event); /* Find the widget which got the event. We store the widget * in the user_data field of GdkWindow's. diff --git a/gtk/testdnd.c b/gtk/testdnd.c index 118e04d427..263e7f50dc 100644 --- a/gtk/testdnd.c +++ b/gtk/testdnd.c @@ -350,7 +350,7 @@ target_drag_data_received (GtkWidget *widget, { if ((data->length >= 0) && (data->format == 8)) { - g_print ("Received %s\n", (gchar *)data->data); + g_print ("Received \"%s\" in trashcan\n", (gchar *)data->data); gtk_drag_finish (context, TRUE, FALSE, time); return; } @@ -359,6 +359,25 @@ target_drag_data_received (GtkWidget *widget, } void +label_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *data, + guint info, + guint time) +{ + if ((data->length >= 0) && (data->format == 8)) + { + g_print ("Received \"%s\" in label\n", (gchar *)data->data); + gtk_drag_finish (context, TRUE, FALSE, time); + return; + } + + gtk_drag_finish (context, FALSE, FALSE, time); +} + +void source_drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, @@ -560,6 +579,9 @@ main (int argc, char **argv) target_table, n_targets - 1, /* no rootwin */ GDK_ACTION_COPY | GDK_ACTION_MOVE); + gtk_signal_connect( GTK_OBJECT(label), "drag_data_received", + GTK_SIGNAL_FUNC( label_drag_data_received), NULL); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); diff --git a/tests/testdnd.c b/tests/testdnd.c index 118e04d427..263e7f50dc 100644 --- a/tests/testdnd.c +++ b/tests/testdnd.c @@ -350,7 +350,7 @@ target_drag_data_received (GtkWidget *widget, { if ((data->length >= 0) && (data->format == 8)) { - g_print ("Received %s\n", (gchar *)data->data); + g_print ("Received \"%s\" in trashcan\n", (gchar *)data->data); gtk_drag_finish (context, TRUE, FALSE, time); return; } @@ -359,6 +359,25 @@ target_drag_data_received (GtkWidget *widget, } void +label_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *data, + guint info, + guint time) +{ + if ((data->length >= 0) && (data->format == 8)) + { + g_print ("Received \"%s\" in label\n", (gchar *)data->data); + gtk_drag_finish (context, TRUE, FALSE, time); + return; + } + + gtk_drag_finish (context, FALSE, FALSE, time); +} + +void source_drag_data_get (GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, @@ -560,6 +579,9 @@ main (int argc, char **argv) target_table, n_targets - 1, /* no rootwin */ GDK_ACTION_COPY | GDK_ACTION_MOVE); + gtk_signal_connect( GTK_OBJECT(label), "drag_data_received", + GTK_SIGNAL_FUNC( label_drag_data_received), NULL); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); |