mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 02:40:11 +00:00
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.
This commit is contained in:
parent
5a86cbd116
commit
24f6d8b887
26
ChangeLog
26
ChangeLog
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
207
gdk/gdkevents.c
207
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)
|
||||
{
|
||||
head = &queued_events;
|
||||
tail = &queued_tail;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
tmp_list = gdk_event_queue_find_first ();
|
||||
|
||||
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);
|
||||
if (tmp_list)
|
||||
{
|
||||
event = tmp_list->data;
|
||||
gdk_event_queue_remove_link (tmp_list);
|
||||
g_list_free_1 (tmp_list);
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
head = &queued_events;
|
||||
tail = &queued_tail;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
tmp_list = gdk_event_queue_find_first ();
|
||||
|
||||
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);
|
||||
if (tmp_list)
|
||||
{
|
||||
event = tmp_list->data;
|
||||
gdk_event_queue_remove_link (tmp_list);
|
||||
g_list_free_1 (tmp_list);
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
@ -358,6 +358,25 @@ target_drag_data_received (GtkWidget *widget,
|
||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
@ -358,6 +358,25 @@ target_drag_data_received (GtkWidget *widget,
|
||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user