]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkevents.c
Fill in string, length and is_modifier for key events. Map some more keys
[~andy/gtk] / gdk / gdkevents.c
index 65ccee5e2410c57371f586a2d188c68e37ad64ec..ac6cd59d2eba6544f0f8d0f90b8e9273899ad327 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <config.h>
 #include <string.h>            /* For memset() */
 
 #include "gdk.h"
 #include "gdkinternals.h"
+#include "gdkalias.h"
 
 typedef struct _GdkIOClosure GdkIOClosure;
 
@@ -46,10 +48,6 @@ GdkEventFunc   _gdk_event_func = NULL;    /* Callback for events */
 gpointer       _gdk_event_data = NULL;
 GDestroyNotify _gdk_event_notify = NULL;
 
-#define TRIPLE_CLICK_TIME(display) (2*display->double_click_time)
-#define DOUBLE_CLICK_DIST      5
-#define TRIPLE_CLICK_DIST      5
-
 /*********************************************
  * Functions for maintaining the event queue *
  *********************************************/
@@ -257,7 +255,6 @@ gdk_event_put (GdkEvent *event)
   gdk_display_put_event (display, event);
 }
 
-static GMemChunk *event_chunk = NULL;
 static GHashTable *event_hash = NULL;
 
 /**
@@ -277,17 +274,10 @@ gdk_event_new (GdkEventType type)
   GdkEventPrivate *new_private;
   GdkEvent *new_event;
   
-  if (event_chunk == NULL)
-    {
-      event_chunk = g_mem_chunk_new ("events",
-                                    sizeof (GdkEventPrivate),
-                                    4096,
-                                    G_ALLOC_AND_FREE);
-      event_hash = g_hash_table_new (g_direct_hash, NULL);
-    }
-  
-  new_private = g_chunk_new (GdkEventPrivate, event_chunk);
-  memset (new_private, 0, sizeof (GdkEventPrivate));
+  if (!event_hash)
+    event_hash = g_hash_table_new (g_direct_hash, NULL);
+
+  new_private = g_slice_new0 (GdkEventPrivate);
   
   new_private->flags = 0;
   new_private->screen = NULL;
@@ -363,7 +353,6 @@ gdk_event_is_allocated (GdkEvent *event)
 GdkEvent*
 gdk_event_copy (GdkEvent *event)
 {
-  GdkEventPrivate *private;
   GdkEventPrivate *new_private;
   GdkEvent *new_event;
   
@@ -372,13 +361,16 @@ gdk_event_copy (GdkEvent *event)
   new_event = gdk_event_new (GDK_NOTHING);
   new_private = (GdkEventPrivate *)new_event;
 
-  private = (GdkEventPrivate *)event;
-
   *new_event = *event;
   if (new_event->any.window)
     g_object_ref (new_event->any.window);
 
-  new_private->screen = private->screen;
+  if (gdk_event_is_allocated (event))
+    {
+      GdkEventPrivate *private = (GdkEventPrivate *)event;
+
+      new_private->screen = private->screen;
+    }
   
   switch (event->any.type)
     {
@@ -446,8 +438,6 @@ gdk_event_free (GdkEvent *event)
 {
   g_return_if_fail (event != NULL);
 
-  g_assert (event_chunk != NULL); /* paranoid */
-  
   if (event->any.window)
     g_object_unref (event->any.window);
   
@@ -498,7 +488,7 @@ gdk_event_free (GdkEvent *event)
     }
 
   g_hash_table_remove (event_hash, event);
-  g_mem_chunk_free (event_chunk, event);
+  g_slice_free (GdkEventPrivate, (GdkEventPrivate*) event);
 }
 
 /**
@@ -560,6 +550,8 @@ gdk_event_get_time (GdkEvent *event)
       case GDK_UNMAP:
       case GDK_WINDOW_STATE:
       case GDK_SETTING:
+      case GDK_OWNER_CHANGE:
+      case GDK_GRAB_BROKEN:
         /* return current time */
         break;
       }
@@ -635,6 +627,8 @@ gdk_event_get_state (GdkEvent        *event,
       case GDK_UNMAP:
       case GDK_WINDOW_STATE:
       case GDK_SETTING:
+      case GDK_OWNER_CHANGE:
+      case GDK_GRAB_BROKEN:
         /* no state field */
         break;
       }
@@ -728,6 +722,10 @@ gdk_event_get_root_coords (GdkEvent *event,
       x = event->motion.x_root;
       y = event->motion.y_root;
       break;
+    case GDK_SCROLL:
+      x = event->scroll.x_root;
+      y = event->scroll.y_root;
+      break;
     case GDK_BUTTON_PRESS:
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
@@ -867,7 +865,7 @@ gdk_event_set_screen (GdkEvent  *event,
  * Returns the screen for the event. The screen is
  * typically the screen for <literal>event->any.window</literal>, but
  * for events such as mouse events, it is the screen
- * where the the pointer was when the event occurs -
+ * where the pointer was when the event occurs -
  * that is, the screen which has the root window 
  * to which <literal>event->motion.x_root</literal> and
  * <literal>event->motion.y_root</literal> are relative.
@@ -1029,22 +1027,28 @@ void
 _gdk_event_button_generate (GdkDisplay *display,
                            GdkEvent   *event)
 {
-  if ((event->button.time < (display->button_click_time[1] + TRIPLE_CLICK_TIME (display))) &&
+  if ((event->button.time < (display->button_click_time[1] + 2*display->double_click_time)) &&
       (event->button.window == display->button_window[1]) &&
-      (event->button.button == display->button_number[1]))
-    {
+      (event->button.button == display->button_number[1]) &&
+      (ABS (event->button.x - display->button_x[1]) <= display->double_click_distance) &&
+      (ABS (event->button.y - display->button_y[1]) <= display->double_click_distance))
+{
       gdk_synthesize_click (display, event, 3);
-      
+            
       display->button_click_time[1] = 0;
       display->button_click_time[0] = 0;
       display->button_window[1] = NULL;
-      display->button_window[0] = 0;
+      display->button_window[0] = NULL;
       display->button_number[1] = -1;
       display->button_number[0] = -1;
+      display->button_x[0] = display->button_x[1] = 0;
+      display->button_y[0] = display->button_y[1] = 0;
     }
   else if ((event->button.time < (display->button_click_time[0] + display->double_click_time)) &&
           (event->button.window == display->button_window[0]) &&
-          (event->button.button == display->button_number[0]))
+          (event->button.button == display->button_number[0]) &&
+          (ABS (event->button.x - display->button_x[0]) <= display->double_click_distance) &&
+          (ABS (event->button.y - display->button_y[0]) <= display->double_click_distance))
     {
       gdk_synthesize_click (display, event, 2);
       
@@ -1054,6 +1058,10 @@ _gdk_event_button_generate (GdkDisplay *display,
       display->button_window[0] = event->button.window;
       display->button_number[1] = display->button_number[0];
       display->button_number[0] = event->button.button;
+      display->button_x[1] = display->button_x[0];
+      display->button_x[0] = event->button.x;
+      display->button_y[1] = display->button_y[0];
+      display->button_y[0] = event->button.y;
     }
   else
     {
@@ -1063,6 +1071,10 @@ _gdk_event_button_generate (GdkDisplay *display,
       display->button_window[0] = event->button.window;
       display->button_number[1] = -1;
       display->button_number[0] = event->button.button;
+      display->button_x[1] = 0;
+      display->button_x[0] = event->button.x;
+      display->button_y[1] = 0;
+      display->button_y[0] = event->button.y;
     }
 }
 
@@ -1124,7 +1136,8 @@ gdk_synthesize_window_state (GdkWindow     *window,
  * 
  * Sets the double click time (two clicks within this time interval
  * count as a double click and result in a #GDK_2BUTTON_PRESS event).
- * Applications should NOT set this, it is a global user-configured setting.
+ * Applications should <emphasis>not</emphasis> set this, it is a global 
+ * user-configured setting.
  *
  * Since: 2.2
  **/
@@ -1140,8 +1153,10 @@ gdk_display_set_double_click_time (GdkDisplay *display,
  * @msec: double click time in milliseconds (thousandths of a second)
  *
  * Set the double click time for the default display. See
- * gdk_display_set_double_click_time(). Applications should NOT
- * set this, it is a global user-configured setting.
+ * gdk_display_set_double_click_time(). 
+ * See also gdk_display_set_double_click_distance().
+ * Applications should <emphasis>not</emphasis> set this, it is a 
+ * global user-configured setting.
  **/
 void
 gdk_set_double_click_time (guint msec)
@@ -1149,13 +1164,33 @@ gdk_set_double_click_time (guint msec)
   gdk_display_set_double_click_time (gdk_display_get_default (), msec);
 }
 
+/**
+ * gdk_display_set_double_click_distance:
+ * @display: a #GdkDisplay
+ * @distance: distance in pixels
+ * 
+ * Sets the double click distance (two clicks within this distance
+ * count as a double click and result in a #GDK_2BUTTON_PRESS event).
+ * See also gdk_display_set_double_click_time().
+ * Applications should <emphasis>not</emphasis> set this, it is a global 
+ * user-configured setting.
+ *
+ * Since: 2.4
+ **/
+void
+gdk_display_set_double_click_distance (GdkDisplay *display,
+                                      guint       distance)
+{
+  display->double_click_distance = distance;
+}
+
 GType
 gdk_event_get_type (void)
 {
   static GType our_type = 0;
   
   if (our_type == 0)
-    our_type = g_boxed_type_register_static ("GdkEvent",
+    our_type = g_boxed_type_register_static (g_intern_static_string ("GdkEvent"),
                                             (GBoxedCopyFunc)gdk_event_copy,
                                             (GBoxedFreeFunc)gdk_event_free);
   return our_type;
@@ -1178,3 +1213,6 @@ gdk_setting_get (const gchar *name,
 {
   return gdk_screen_get_setting (gdk_screen_get_default (), name, value);
 }
+
+#define __GDK_EVENTS_C__
+#include "gdkaliasdef.c"