]> Pileus Git - ~andy/gtk/commitdiff
Add gdkmouse-fb.c
authorAlexander Larsson <alexl@redhat.com>
Wed, 6 Dec 2000 17:27:52 +0000 (17:27 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Wed, 6 Dec 2000 17:27:52 +0000 (17:27 +0000)
2000-12-06  Alexander Larsson  <alexl@redhat.com>

* gdk/linux-fb/Makefile.am:
Add gdkmouse-fb.c

* gdk/linux-fb/gdkmouse-fb.c:
New file. Abstracted the mouse drivers a bit.

* gdk/linux-fb/gdkcursor-fb.c:
The cursor hide/show functions was moved here from gdkinput-ps2.c.

* gdk/linux-fb/gdkinput-ps2.c:
Removed old mouse handling code. Moved cursor handling code
to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
gdk_mouse_get_info.

* gdk/linux-fb/gdkmain-fb.c:
Pass NULL pointers for x,y in gdk_mouse_get_info call.

* gdk/linux-fb/gdkprivate-fb.h:
Removed public gdk_fb_find_common_ancestor, added and renamed
functions for the new mouse handling code.

* gdk/linux-fb/gdkwindow-fb.c:
Moved gdk_fb_window_send_crossing_events here. added global
variable gdk_fb_window_containing_pointer. made
gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
renamed to gdk_mouse_get_info.

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/linux-fb/Makefile.am
gdk/linux-fb/gdkcursor-fb.c
gdk/linux-fb/gdkinput-ps2.c
gdk/linux-fb/gdkmain-fb.c
gdk/linux-fb/gdkmouse-fb.c [new file with mode: 0644]
gdk/linux-fb/gdkprivate-fb.h
gdk/linux-fb/gdkwindow-fb.c

index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index ec294fc959034b5c3543e8ebfe58ac8cb5e331f0..b10aac88b3a25331abfcaa84642620ba20f62fa7 100644 (file)
@@ -1,3 +1,33 @@
+2000-12-06  Alexander Larsson  <alexl@redhat.com>
+
+       * gdk/linux-fb/Makefile.am:
+       Add gdkmouse-fb.c
+       
+       * gdk/linux-fb/gdkmouse-fb.c:
+       New file. Abstracted the mouse drivers a bit.
+
+       * gdk/linux-fb/gdkcursor-fb.c:
+       The cursor hide/show functions was moved here from gdkinput-ps2.c.
+
+       * gdk/linux-fb/gdkinput-ps2.c:
+       Removed old mouse handling code. Moved cursor handling code
+       to gdkcursor-fb.c, moved gdk_fb_window_send_crossing_events() to
+       gdkwindow-fb.c. gdk_input_get_mouseinfo was renamed to
+       gdk_mouse_get_info.
+
+       * gdk/linux-fb/gdkmain-fb.c:
+       Pass NULL pointers for x,y in gdk_mouse_get_info call.
+
+       * gdk/linux-fb/gdkprivate-fb.h:
+       Removed public gdk_fb_find_common_ancestor, added and renamed
+       functions for the new mouse handling code.
+
+       * gdk/linux-fb/gdkwindow-fb.c:
+       Moved gdk_fb_window_send_crossing_events here. added global
+       variable gdk_fb_window_containing_pointer. made
+       gdk_fb_find_common_ancestor static. gdk_input_get_mouseinfo was
+       renamed to gdk_mouse_get_info.
+
 2000-12-06  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/linux-fb/gdkevents-fb.c:
index 2bc07b88c2ae82819ff626fe702d3ce044e0dabf..95c4a3079e9e5238b9a674aceaa49cb3fc3bad55 100644 (file)
@@ -50,6 +50,7 @@ libgdk_linux_fb_la_SOURCES =    \
        gdkprivate-fb.h         \
        gdkinputprivate.h       \
        gdkinput-ps2.c          \
+       gdkmouse-fb.c           \
        gdkevents-fb.c          \
        gdkrender-fb.c          \
        mi.h                    \
index 80d51332c464793fc7d112137205fa9445729da5..6dab9f8bd6ab3446e86305666b98aaf04c1983b5 100644 (file)
@@ -284,3 +284,239 @@ _gdk_cursor_destroy (GdkCursor *cursor)
 
   g_free (private);
 }
+
+/* Global data to keep track of cursor */
+static GdkPixmap *last_contents = NULL;
+static GdkPoint last_location, last_contents_size;
+static GdkCursor *last_cursor = NULL;
+static GdkFBDrawingContext *gdk_fb_cursor_dc = NULL;
+static GdkFBDrawingContext cursor_dc_dat;
+static GdkGC *cursor_gc;
+static gint cursor_visibility_count = 1;
+
+static GdkFBDrawingContext *
+gdk_fb_cursor_dc_reset (void)
+{
+  if (gdk_fb_cursor_dc)
+    gdk_fb_drawing_context_finalize (gdk_fb_cursor_dc);
+
+  gdk_fb_cursor_dc = &cursor_dc_dat;
+  gdk_fb_drawing_context_init (gdk_fb_cursor_dc,
+                              GDK_DRAWABLE_IMPL(gdk_parent_root),
+                              cursor_gc,
+                              TRUE,
+                              FALSE);
+
+  return gdk_fb_cursor_dc;
+}
+
+void
+gdk_fb_cursor_hide (void)
+{
+  GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
+
+  cursor_visibility_count--;
+  g_assert (cursor_visibility_count <= 0);
+  
+  if (cursor_visibility_count < 0)
+    return;
+
+  if (!mydc)
+    mydc = gdk_fb_cursor_dc_reset ();
+
+  if (last_contents)
+    {
+      gdk_gc_set_clip_mask (cursor_gc, NULL);
+      /* Restore old picture */
+      gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
+                             cursor_gc,
+                             GDK_DRAWABLE_IMPL(last_contents),
+                             mydc,
+                             0, 0,
+                             last_location.x,
+                             last_location.y,
+                             last_contents_size.x,
+                             last_contents_size.y);
+    }
+}
+
+void
+gdk_fb_cursor_invalidate (void)
+{
+  if (last_contents)
+    {
+      gdk_pixmap_unref (last_contents);
+      last_contents = NULL;
+    }
+}
+
+void
+gdk_fb_cursor_unhide()
+{
+  GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
+  GdkCursorPrivateFB *last_private;
+  GdkDrawableFBData *pixmap_last;
+  
+  last_private = GDK_CURSOR_FB (last_cursor);
+  pixmap_last = GDK_DRAWABLE_IMPL_FBDATA (last_private->cursor);
+  cursor_visibility_count++;
+  g_assert (cursor_visibility_count <= 1);
+  if (cursor_visibility_count < 1)
+    return;
+
+  if (!mydc)
+    mydc = gdk_fb_cursor_dc_reset ();
+
+  if (last_cursor)
+    {
+      if (!last_contents ||
+         pixmap_last->width > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->width ||
+         pixmap_last->height > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->height)
+       {
+         if (last_contents)
+           gdk_pixmap_unref (last_contents);
+
+         last_contents = gdk_pixmap_new (gdk_parent_root,
+                                         pixmap_last->width,
+                                         pixmap_last->height,
+                                         GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->depth);
+       }
+
+      gdk_gc_set_clip_mask (cursor_gc, NULL);
+      gdk_fb_draw_drawable_2 (GDK_DRAWABLE_IMPL (last_contents),
+                             cursor_gc,
+                             GDK_DRAWABLE_IMPL (gdk_parent_root),
+                             last_location.x,
+                             last_location.y,
+                             0, 0,
+                             pixmap_last->width,
+                             pixmap_last->height,
+                             TRUE, FALSE);
+      last_contents_size.x = pixmap_last->width;
+      last_contents_size.y = pixmap_last->height;
+      
+      gdk_gc_set_clip_mask (cursor_gc, last_private->mask);
+      gdk_gc_set_clip_origin (cursor_gc,
+                             last_location.x,
+                             last_location.y);
+
+      gdk_fb_cursor_dc_reset ();
+      gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (gdk_parent_root),
+                             cursor_gc,
+                             GDK_DRAWABLE_IMPL (last_private->cursor),
+                             mydc,
+                             0, 0,
+                             last_location.x, last_location.y,
+                             pixmap_last->width,
+                             pixmap_last->height);
+    }
+  else
+    gdk_fb_cursor_invalidate ();
+}
+
+gboolean
+gdk_fb_cursor_region_need_hide (GdkRegion *region)
+{
+  GdkRectangle testme;
+
+  if (!last_cursor)
+    return FALSE;
+
+  testme.x = last_location.x;
+  testme.y = last_location.y;
+  testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
+  testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
+
+  return (gdk_region_rect_in (region, &testme) != GDK_OVERLAP_RECTANGLE_OUT);
+}
+
+gboolean
+gdk_fb_cursor_need_hide (GdkRectangle *rect)
+{
+  GdkRectangle testme;
+
+  if (!last_cursor)
+    return FALSE;
+
+  testme.x = last_location.x;
+  testme.y = last_location.y;
+  testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
+  testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
+
+  return gdk_rectangle_intersect (rect, &testme, &testme);
+}
+
+void
+gdk_fb_get_cursor_rect (GdkRectangle *rect)
+{
+  if (last_cursor)
+    {
+      rect->x = last_location.x;
+      rect->y = last_location.y;
+      rect->width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
+      rect->height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
+    }
+  else
+    {
+      rect->x = rect->y = -1;
+      rect->width = rect->height = 0;
+    }
+}
+
+void
+gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window)
+{
+  GdkCursor *the_cursor;
+
+  if (!cursor_gc)
+    {
+      GdkColor white, black;
+      cursor_gc = gdk_gc_new (gdk_parent_root);
+      gdk_color_black (gdk_colormap_get_system (), &black);
+      gdk_color_white (gdk_colormap_get_system (), &white);
+      gdk_gc_set_foreground (cursor_gc, &black);
+      gdk_gc_set_background (cursor_gc, &white);
+    }
+
+  gdk_fb_cursor_hide ();
+
+  if (_gdk_fb_pointer_grab_window)
+    {
+      if (_gdk_fb_pointer_grab_cursor)
+       the_cursor = _gdk_fb_pointer_grab_cursor;
+      else
+       {
+         GdkWindow *win = _gdk_fb_pointer_grab_window;
+         while (!GDK_WINDOW_IMPL_FBDATA (win)->cursor && GDK_WINDOW_OBJECT (win)->parent)
+           win = (GdkWindow *)GDK_WINDOW_OBJECT (win)->parent;
+         the_cursor = GDK_WINDOW_IMPL_FBDATA (win)->cursor;
+       }
+    }
+  else
+    {
+      while (!GDK_WINDOW_IMPL_FBDATA (in_window)->cursor && GDK_WINDOW_P (in_window)->parent)
+       in_window = (GdkWindow *)GDK_WINDOW_P (in_window)->parent;
+      the_cursor = GDK_WINDOW_IMPL_FBDATA (in_window)->cursor;
+    }
+
+  last_location.x = x - GDK_CURSOR_FB (the_cursor)->hot_x;
+  last_location.y = y - GDK_CURSOR_FB (the_cursor)->hot_y;
+
+  if (the_cursor)
+    gdk_cursor_ref (the_cursor);
+  if (last_cursor)
+    gdk_cursor_unref (last_cursor);
+  last_cursor = the_cursor;
+
+  gdk_fb_cursor_unhide ();
+}
+
+void
+gdk_fb_cursor_reset(void)
+{
+  GdkWindow *win = gdk_window_at_pointer (NULL, NULL);
+  gint x, y;
+
+  gdk_mouse_get_info (&x, &y, NULL);
+  gdk_fb_cursor_move (x, y, win);
+}
index 7c5a46a5bdc6d16b0f87e2bc81ebc502eda98312..2eccb61bd7f8b72cfc6d615228553ac70f87e87b 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-typedef struct {
-  gint fd, fd_tag;
-
-  gdouble x, y;
-  GdkWindow *prev_window;
-  gboolean button1_pressed, button2_pressed, button3_pressed;
-  gboolean click_grab;
-
-  guchar mouse_packet[5];
-  int packet_nbytes;
-} MouseDevice;
-
 typedef struct {
   gint fd, fd_tag, consfd;
 
@@ -73,7 +61,6 @@ static guint blanking_timer = 0;
 
 static Keyboard * tty_keyboard_open(void);
 
-static MouseDevice *gdk_fb_mouse = NULL;
 static Keyboard *keyboard = NULL;
 
 #ifndef VESA_NO_BLANKING
@@ -107,977 +94,6 @@ input_activity (void)
 #endif
 }
 
-static void
-send_button_event (MouseDevice *mouse,
-                  guint button,
-                  gboolean press_event,
-                  guint32 the_time)
-{
-  GdkEvent *event;
-  gint x, y;
-  GdkWindow *window;
-  int nbuttons = 0;
-
-  if (_gdk_fb_pointer_grab_window_events)
-    window = _gdk_fb_pointer_grab_window_events;
-  else
-    window = gdk_window_at_pointer(NULL, NULL);
-
-  event = gdk_event_make (window, press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE, FALSE);
-
-  if (event)
-    {
-      gdk_window_get_origin (window, &x, &y);
-      x = mouse->x - x;
-      y = mouse->y - y;
-      
-      event->button.x = x;
-      event->button.y = y;
-      event->button.button = button;
-      event->button.state = (mouse->button1_pressed?GDK_BUTTON1_MASK:0) |
-       (mouse->button2_pressed ? GDK_BUTTON2_MASK : 0) |
-       (mouse->button3_pressed ? GDK_BUTTON3_MASK : 0) |
-       (1 << (button + 8)) /* badhack */ |
-       keyboard->modifier_state;
-      event->button.device = gdk_core_pointer;
-      event->button.x_root = mouse->x;
-      event->button.y_root = mouse->y;
-      
-      event->button.time = the_time;
-      
-#if 0
-      g_message ("Button #%d %s [%d, %d] in %p",
-                button, press_event?"pressed":"released",
-                x, y, window);
-      
-      /* Debugging aid */
-      if (window && window != gdk_parent_root)
-       {
-         GdkGC *tmp_gc;
-         
-         tmp_gc = gdk_gc_new (window);
-         GDK_GC_FBDATA (tmp_gc)->values.foreground.pixel = 0;
-         gdk_fb_draw_rectangle (GDK_DRAWABLE_IMPL(window), tmp_gc, TRUE, 0, 0,
-                                GDK_DRAWABLE_IMPL_FBDATA(window)->width, GDK_DRAWABLE_IMPL_FBDATA(window)->height);
-         gdk_gc_unref(tmp_gc);
-       }
-#endif
-      
-      gdk_event_queue_append (event);
-      
-      /* For double-clicks */
-      if (press_event)
-       gdk_event_button_generate (event);
-      
-    }
-  
-  if (mouse->button1_pressed)
-    nbuttons++;
-  if (mouse->button2_pressed)
-    nbuttons++;
-  if (mouse->button3_pressed)
-    nbuttons++;
-
-  /* Handle implicit button grabs: */
-  if (press_event && nbuttons == 1)
-    {
-      gdk_fb_pointer_grab (window, FALSE,
-                          gdk_window_get_events (window),
-                          NULL, NULL,
-                          GDK_CURRENT_TIME, TRUE);
-      mouse->click_grab = TRUE;
-    }
-  else if (!press_event && nbuttons == 0 && mouse->click_grab)
-    {
-      gdk_fb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
-      mouse->click_grab = FALSE;
-    }
-}
-
-static GdkPixmap *last_contents = NULL;
-static GdkPoint last_location, last_contents_size;
-static GdkCursor *last_cursor = NULL;
-static GdkFBDrawingContext *gdk_fb_cursor_dc = NULL;
-static GdkFBDrawingContext cursor_dc_dat;
-static GdkGC *cursor_gc;
-static gint cursor_visibility_count = 1;
-
-static GdkFBDrawingContext *
-gdk_fb_cursor_dc_reset (void)
-{
-  if (gdk_fb_cursor_dc)
-    gdk_fb_drawing_context_finalize (gdk_fb_cursor_dc);
-
-  gdk_fb_cursor_dc = &cursor_dc_dat;
-  gdk_fb_drawing_context_init (gdk_fb_cursor_dc,
-                              GDK_DRAWABLE_IMPL(gdk_parent_root),
-                              cursor_gc,
-                              TRUE,
-                              FALSE);
-
-  return gdk_fb_cursor_dc;
-}
-
-void
-gdk_fb_cursor_hide (void)
-{
-  GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
-
-  cursor_visibility_count--;
-  g_assert (cursor_visibility_count <= 0);
-  
-  if (cursor_visibility_count < 0)
-    return;
-
-  if (!mydc)
-    mydc = gdk_fb_cursor_dc_reset ();
-
-  if (last_contents)
-    {
-      gdk_gc_set_clip_mask (cursor_gc, NULL);
-      /* Restore old picture */
-      gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL(gdk_parent_root),
-                             cursor_gc,
-                             GDK_DRAWABLE_IMPL(last_contents),
-                             mydc,
-                             0, 0,
-                             last_location.x,
-                             last_location.y,
-                             last_contents_size.x,
-                             last_contents_size.y);
-    }
-}
-
-void
-gdk_fb_cursor_invalidate (void)
-{
-  if (last_contents)
-    {
-      gdk_pixmap_unref (last_contents);
-      last_contents = NULL;
-    }
-}
-
-void
-gdk_fb_cursor_unhide()
-{
-  GdkFBDrawingContext *mydc = gdk_fb_cursor_dc;
-  GdkCursorPrivateFB *last_private;
-  GdkDrawableFBData *pixmap_last;
-  
-  last_private = GDK_CURSOR_FB (last_cursor);
-  pixmap_last = GDK_DRAWABLE_IMPL_FBDATA (last_private->cursor);
-  cursor_visibility_count++;
-  g_assert (cursor_visibility_count <= 1);
-  if (cursor_visibility_count < 1)
-    return;
-
-  if (!mydc)
-    mydc = gdk_fb_cursor_dc_reset ();
-
-  if (last_cursor)
-    {
-      if (!last_contents ||
-         pixmap_last->width > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->width ||
-         pixmap_last->height > GDK_DRAWABLE_IMPL_FBDATA (last_contents)->height)
-       {
-         if (last_contents)
-           gdk_pixmap_unref (last_contents);
-
-         last_contents = gdk_pixmap_new (gdk_parent_root,
-                                         pixmap_last->width,
-                                         pixmap_last->height,
-                                         GDK_DRAWABLE_IMPL_FBDATA (gdk_parent_root)->depth);
-       }
-
-      gdk_gc_set_clip_mask (cursor_gc, NULL);
-      gdk_fb_draw_drawable_2 (GDK_DRAWABLE_IMPL (last_contents),
-                             cursor_gc,
-                             GDK_DRAWABLE_IMPL (gdk_parent_root),
-                             last_location.x,
-                             last_location.y,
-                             0, 0,
-                             pixmap_last->width,
-                             pixmap_last->height,
-                             TRUE, FALSE);
-      last_contents_size.x = pixmap_last->width;
-      last_contents_size.y = pixmap_last->height;
-      
-      gdk_gc_set_clip_mask (cursor_gc, last_private->mask);
-      gdk_gc_set_clip_origin (cursor_gc,
-                             last_location.x,
-                             last_location.y);
-
-      gdk_fb_cursor_dc_reset ();
-      gdk_fb_draw_drawable_3 (GDK_DRAWABLE_IMPL (gdk_parent_root),
-                             cursor_gc,
-                             GDK_DRAWABLE_IMPL (last_private->cursor),
-                             mydc,
-                             0, 0,
-                             last_location.x, last_location.y,
-                             pixmap_last->width,
-                             pixmap_last->height);
-    }
-  else
-    gdk_fb_cursor_invalidate ();
-}
-
-gboolean
-gdk_fb_cursor_region_need_hide (GdkRegion *region)
-{
-  GdkRectangle testme;
-
-  if (!last_cursor)
-    return FALSE;
-
-  testme.x = last_location.x;
-  testme.y = last_location.y;
-  testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
-  testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
-
-  return (gdk_region_rect_in (region, &testme) != GDK_OVERLAP_RECTANGLE_OUT);
-}
-
-gboolean
-gdk_fb_cursor_need_hide (GdkRectangle *rect)
-{
-  GdkRectangle testme;
-
-  if (!last_cursor)
-    return FALSE;
-
-  testme.x = last_location.x;
-  testme.y = last_location.y;
-  testme.width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
-  testme.height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
-
-  return gdk_rectangle_intersect (rect, &testme, &testme);
-}
-
-void
-gdk_fb_get_cursor_rect (GdkRectangle *rect)
-{
-  if (last_cursor)
-    {
-      rect->x = last_location.x;
-      rect->y = last_location.y;
-      rect->width = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->width;
-      rect->height = GDK_DRAWABLE_IMPL_FBDATA (GDK_CURSOR_FB (last_cursor)->cursor)->height;
-    }
-  else
-    {
-      rect->x = rect->y = -1;
-      rect->width = rect->height = 0;
-    }
-}
-
-static void
-move_pointer (MouseDevice *mouse, GdkWindow *in_window)
-{
-  GdkCursor *the_cursor;
-
-  if (!cursor_gc)
-    {
-      GdkColor white, black;
-      cursor_gc = gdk_gc_new (gdk_parent_root);
-      gdk_color_black (gdk_colormap_get_system (), &black);
-      gdk_color_white (gdk_colormap_get_system (), &white);
-      gdk_gc_set_foreground (cursor_gc, &black);
-      gdk_gc_set_background (cursor_gc, &white);
-    }
-
-  gdk_fb_cursor_hide ();
-
-  if (_gdk_fb_pointer_grab_window)
-    {
-      if (_gdk_fb_pointer_grab_cursor)
-       the_cursor = _gdk_fb_pointer_grab_cursor;
-      else
-       {
-         GdkWindow *win = _gdk_fb_pointer_grab_window;
-         while (!GDK_WINDOW_IMPL_FBDATA (win)->cursor && GDK_WINDOW_OBJECT (win)->parent)
-           win = (GdkWindow *)GDK_WINDOW_OBJECT (win)->parent;
-         the_cursor = GDK_WINDOW_IMPL_FBDATA (win)->cursor;
-       }
-    }
-  else
-    {
-      while (!GDK_WINDOW_IMPL_FBDATA (in_window)->cursor && GDK_WINDOW_P (in_window)->parent)
-       in_window = (GdkWindow *)GDK_WINDOW_P (in_window)->parent;
-      the_cursor = GDK_WINDOW_IMPL_FBDATA (in_window)->cursor;
-    }
-
-  last_location.x = mouse->x - GDK_CURSOR_FB (the_cursor)->hot_x;
-  last_location.y = mouse->y - GDK_CURSOR_FB (the_cursor)->hot_y;
-
-  if (the_cursor)
-    gdk_cursor_ref (the_cursor);
-  if (last_cursor)
-    gdk_cursor_unref (last_cursor);
-  last_cursor = the_cursor;
-
-  gdk_fb_cursor_unhide ();
-}
-
-void
-gdk_fb_cursor_reset(void)
-{
-  GdkWindow *win = gdk_window_at_pointer (NULL, NULL);
-
-  move_pointer (gdk_fb_mouse, win);
-}
-
-void
-gdk_fb_window_send_crossing_events (GdkWindow *dest,
-                                   GdkCrossingMode mode)
-{
-  GdkWindow *c;
-  GdkWindow *win, *last, *next;
-  GdkEvent *event;
-  gint x, y, x_int, y_int;
-  GdkModifierType my_mask;
-  GList *path, *list;
-  gboolean non_linear;
-  gboolean only_grabbed_window;
-  GdkWindow *a;
-  GdkWindow *b;
-
-  if (gdk_fb_mouse->prev_window == NULL)
-    gdk_fb_mouse->prev_window = gdk_window_ref (gdk_parent_root);
-
-  if (mode == GDK_CROSSING_UNGRAB)
-    a = _gdk_fb_pointer_grab_window;
-  else
-    a = gdk_fb_mouse->prev_window;
-  b = dest;
-
-  /* When grab in progress only send normal crossing events about
-   * the grabbed window.
-   */
-  only_grabbed_window = (_gdk_fb_pointer_grab_window_events != NULL) &&
-                        (mode == GDK_CROSSING_NORMAL);
-  
-  if (a==b)
-    return;
-
-  gdk_input_get_mouseinfo (&x, &y, &my_mask);
-
-  c = gdk_fb_find_common_ancestor (a, b);
-
-  non_linear = (c != a) && (c != b);
-
-  if (!only_grabbed_window || (a == _gdk_fb_pointer_grab_window))
-    event = gdk_event_make (a, GDK_LEAVE_NOTIFY, TRUE);
-  else
-    event = NULL;
-  if (event)
-    {
-      event->crossing.subwindow = NULL;
-      gdk_window_get_root_origin (a, &x_int, &y_int);
-      event->crossing.x = x - x_int;
-      event->crossing.y = y - y_int;
-      event->crossing.x_root = x;
-      event->crossing.y_root = y;
-      event->crossing.mode = mode;
-      if (non_linear)
-       event->crossing.detail = GDK_NOTIFY_NONLINEAR;
-      else if (c==a)
-       event->crossing.detail = GDK_NOTIFY_INFERIOR;
-      else
-       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
-      event->crossing.focus = FALSE;
-      event->crossing.state = my_mask;
-    }
-  
-  /* Traverse up from a to (excluding) c */
-  if (c != a)
-    {
-      last = a;
-      win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
-      while (win != c)
-       {
-         if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
-           event = gdk_event_make (win, GDK_LEAVE_NOTIFY, TRUE);
-         else
-           event = NULL;
-         if (event)
-           {
-             event->crossing.subwindow = gdk_window_ref (last);
-             gdk_window_get_root_origin (win, &x_int, &y_int);
-             event->crossing.x = x - x_int;
-             event->crossing.y = y - y_int;
-             event->crossing.x_root = x;
-             event->crossing.y_root = y;
-             event->crossing.mode = mode;
-             if (non_linear)
-               event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-             else
-               event->crossing.detail = GDK_NOTIFY_VIRTUAL;
-             event->crossing.focus = FALSE;
-             event->crossing.state = my_mask;
-           }
-         last = win;
-         win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
-       }
-    }
-  
-  /* Traverse down from c to b */
-  if (c != b) 
-    {
-      path = NULL;
-      win = GDK_WINDOW( GDK_WINDOW_OBJECT (b)->parent);
-      while (win != c)
-       {
-         path = g_list_prepend (path, win);
-         win = GDK_WINDOW( GDK_WINDOW_OBJECT (win)->parent);
-       }
-      
-      list = path;
-      while (list) 
-       {
-         win = (GdkWindow *)list->data;
-         list = g_list_next (list);
-         if (list)
-           next = (GdkWindow *)list->data;
-         else 
-           next = b;
-         
-         if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
-           event = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE);
-         else
-           event = NULL;
-         if (event)
-           {
-             event->crossing.subwindow = gdk_window_ref (next);
-             gdk_window_get_root_origin (win, &x_int, &y_int);
-             event->crossing.x = x - x_int;
-             event->crossing.y = y - y_int;
-             event->crossing.x_root = x;
-             event->crossing.y_root = y;
-             event->crossing.mode = mode;
-             if (non_linear)
-               event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-             else
-               event->crossing.detail = GDK_NOTIFY_VIRTUAL;
-             event->crossing.focus = FALSE;
-             event->crossing.state = my_mask;
-           }
-       }
-      g_list_free (path);
-    }
-
-  if (!only_grabbed_window || (b == _gdk_fb_pointer_grab_window))
-    event = gdk_event_make (b, GDK_ENTER_NOTIFY, TRUE);
-  else
-    event = NULL;
-  if (event)
-    {
-      event->crossing.subwindow = NULL;
-      gdk_window_get_root_origin (b, &x_int, &y_int);
-      event->crossing.x = x - x_int;
-      event->crossing.y = y - y_int;
-      event->crossing.x_root = x;
-      event->crossing.y_root = y;
-      event->crossing.mode = mode;
-      if (non_linear)
-       event->crossing.detail = GDK_NOTIFY_NONLINEAR;
-      else if (c==a)
-       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
-      else
-       event->crossing.detail = GDK_NOTIFY_INFERIOR;
-      event->crossing.focus = FALSE;
-      event->crossing.state = my_mask;
-    }
-
-  if ((mode != GDK_CROSSING_GRAB) &&
-      (b != gdk_fb_mouse->prev_window))
-    {
-      gdk_window_unref (gdk_fb_mouse->prev_window);
-      gdk_fb_mouse->prev_window = gdk_window_ref (b);
-    }
-}
-
-static void
-handle_mouse_input(MouseDevice *mouse,
-                  gboolean got_motion)
-{
-  GdkWindow *mousewin;
-  GdkEvent *event;
-  gint x, y;
-  GdkWindow *win, *grabwin;
-  guint state;
-
-  if (_gdk_fb_pointer_grab_confine)
-    mousewin = _gdk_fb_pointer_grab_confine;
-  else
-    mousewin = gdk_parent_root;
-
-  if (mouse->x < GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_x)
-    mouse->x = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_x;
-  else if (mouse->x > (GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_x - 1))
-    mouse->x = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_x - 1;
-
-  if (mouse->y < GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_y)
-    mouse->y = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->llim_y;
-  else if (mouse->y > (GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_y - 1))
-    mouse->y = GDK_DRAWABLE_IMPL_FBDATA (mousewin)->lim_y - 1;
-
-  if (!got_motion)
-    return;
-
-  win = gdk_window_at_pointer (NULL, NULL);
-  if (_gdk_fb_pointer_grab_window_events)
-    grabwin = _gdk_fb_pointer_grab_window_events;
-  else
-    grabwin = win;
-
-  move_pointer (mouse, grabwin);
-  
-  gdk_window_get_origin (grabwin, &x, &y);
-  x = mouse->x - x;
-  y = mouse->y - y;
-
-
-  state = (mouse->button1_pressed?GDK_BUTTON1_MASK:0) |
-    (mouse->button2_pressed?GDK_BUTTON2_MASK:0) |
-    (mouse->button3_pressed?GDK_BUTTON3_MASK:0) |
-    keyboard->modifier_state;
-
-  event = gdk_event_make (grabwin, GDK_MOTION_NOTIFY, TRUE);
-  if (event)
-    {
-      event->motion.x = x;
-      event->motion.y = y;
-      event->motion.state = state;
-      event->motion.is_hint = FALSE;
-      event->motion.device = gdk_core_pointer;
-      event->motion.x_root = mouse->x;
-      event->motion.y_root = mouse->y;
-      event->motion.time = gdk_fb_get_time ();
-    }
-
-  if (win != mouse->prev_window)
-    gdk_fb_window_send_crossing_events (win,
-                                       GDK_CROSSING_NORMAL);
-
-  input_activity ();
-}
-
-static gboolean
-pull_fidmour_packet (MouseDevice *mouse,
-                    gboolean *btn_down,
-                    gdouble *x,
-                    gdouble *y)
-{
-  gboolean keep_reading = TRUE;
-
-  while (keep_reading)
-    {
-      int n;
-
-      n = read (mouse->fd, mouse->mouse_packet + mouse->packet_nbytes, 5 - mouse->packet_nbytes);
-      if (n < 0)
-       return FALSE;
-      else if (n == 0)
-       {
-         g_error ("EOF on mouse device!");
-         g_source_remove (mouse->fd_tag);
-         return FALSE;
-       }
-
-      mouse->packet_nbytes += n;
-
-      n = 0;
-      if (!(mouse->mouse_packet[0] & 0x80))
-       {
-         int i;
-         /* We haven't received any of the packet yet but there is no header at the beginning */
-         for (i = 1; i < mouse->packet_nbytes; i++)
-           {
-             if (mouse->mouse_packet[i] & 0x80)
-               {
-                 n = i;
-                 break;
-               }
-           }
-       }
-      else if (mouse->packet_nbytes > 1 &&
-              ((mouse->mouse_packet[0] & 0x90) == 0x90))
-       {
-         /* eat the 0x90 and following byte, no clue what it's for */
-         n = 2;
-       }
-      else if (mouse->packet_nbytes == 5)
-       {
-         switch (mouse->mouse_packet[0] & 0xF)
-           {
-           case 2:
-             *btn_down = 0;
-             break;
-           case 1:
-           case 0:
-             *btn_down = 1;
-             break;
-           default:
-             g_assert_not_reached ();
-             break;
-           }
-
-         *x = mouse->mouse_packet[1] + (mouse->mouse_packet[2] << 7);
-         if (*x > 8192)
-           *x -= 16384;
-         *y = mouse->mouse_packet[3] + (mouse->mouse_packet[4] << 7);
-         if (*y > 8192)
-           *y -= 16384;
-         /* Now map touchscreen coords to screen coords */
-         *x *= ((double)gdk_display->modeinfo.xres)/4096.0;
-         *y *= ((double)gdk_display->modeinfo.yres)/4096.0;
-         n = 5;
-         keep_reading = FALSE;
-       }
-
-      if (n)
-       {
-         memmove (mouse->mouse_packet, mouse->mouse_packet+n, mouse->packet_nbytes-n);
-         mouse->packet_nbytes -= n;
-       }
-    }
-
-  return TRUE;
-}
-
-static gboolean
-handle_input_fidmour (GIOChannel *gioc,
-                     GIOCondition cond,
-                     gpointer data)
-{
-  MouseDevice *mouse = data;
-  gdouble x, y, oldx, oldy;
-  gboolean got_motion = FALSE;
-  gboolean btn_down;
-  guint32 the_time;
-
-  the_time = gdk_fb_get_time ();
-  
-  oldx = mouse->x;
-  oldy = mouse->y;
-  while (pull_fidmour_packet (mouse, &btn_down, &x, &y))
-    {
-      if (fabs(x - mouse->x) >= 1.0 || fabs(x - mouse->y) >= 1.0)
-       {
-         got_motion = TRUE;
-         mouse->x = x;
-         mouse->y = y;
-       }
-
-      if (btn_down != mouse->button1_pressed)
-       {
-         if (got_motion)
-           {
-             handle_mouse_input (mouse, TRUE);
-             got_motion = FALSE;
-           }
-
-         mouse->button1_pressed = btn_down;
-         send_button_event (mouse, 1, btn_down, the_time);
-       }
-    }
-
-  if (got_motion)
-    handle_mouse_input (mouse, TRUE);
-
-  return TRUE;
-}
-
-static gboolean
-handle_input_ps2 (GIOChannel *gioc,
-                 GIOCondition cond,
-                 gpointer data)
-{
-  MouseDevice *mouse = data;
-  int n, dx=0, dy=0;
-  gboolean new_button1, new_button2, new_button3;
-  guint32 the_time;
-  gboolean got_motion = FALSE;
-  guchar *buf;
-
-  the_time = gdk_fb_get_time ();
-
-  while (1) /* Go through as many mouse events as we can */
-    {
-      n = read (mouse->fd, mouse->mouse_packet + mouse->packet_nbytes, 3 - mouse->packet_nbytes);
-      if (n<=0) /* error or nothing to read */
-       break;
-      
-      mouse->packet_nbytes += n;
-      
-      if (mouse->packet_nbytes < 3) /* Mouse packet not finished */
-       break;
-
-      mouse->packet_nbytes = 0;
-
-      /* Finished reading a packet */
-      buf = mouse->mouse_packet;
-      
-      new_button1 = (buf[0] & 1) && 1;
-      new_button3 = (buf[0] & 2) && 1;
-      new_button2 = (buf[0] & 4) && 1;
-
-      if (got_motion &&
-         (new_button1 != mouse->button1_pressed ||
-          new_button2 != mouse->button2_pressed ||
-          new_button3 != mouse->button3_pressed))
-       {
-         /* If a mouse button state changes we need to get correct ordering with enter/leave events,
-            so push those out via handle_mouse_input */
-         got_motion = FALSE;
-         handle_mouse_input (mouse, TRUE);
-       }
-
-      if (new_button1 != mouse->button1_pressed)
-       {
-         mouse->button1_pressed = new_button1; 
-         send_button_event (mouse, 1, new_button1, the_time);
-       }
-
-      if (new_button2 != mouse->button2_pressed)
-       {
-         mouse->button2_pressed = new_button2;
-         send_button_event (mouse, 2, new_button2, the_time);
-       }
-
-      if (new_button3 != mouse->button3_pressed)
-       {
-         mouse->button3_pressed = new_button3; 
-         send_button_event (mouse, 3, new_button3, the_time);
-       }
-
-      if (buf[1] != 0)
-       dx = ((buf[0] & 0x10) ? ((gint)buf[1])-256 : buf[1]);
-      else
-       dx = 0;
-      if (buf[2] != 0)
-       dy = -((buf[0] & 0x20) ? ((gint)buf[2])-256 : buf[2]);
-      else
-       dy = 0;
-
-      mouse->x += dx;
-      mouse->y += dy;
-      if (dx || dy)
-       got_motion = TRUE;
-    }
-
-  if (got_motion)
-    handle_mouse_input (mouse, TRUE);
-
-  return TRUE;
-}
-
-static gboolean
-handle_input_ms (GIOChannel *gioc,
-                GIOCondition cond,
-                gpointer data)
-{
-  MouseDevice *mouse = data;
-  guchar byte1, byte2, byte3;
-  int n, dx=0, dy=0;
-  gboolean new_button1, new_button2, new_button3;
-  guint32 the_time;
-
-  the_time = gdk_fb_get_time ();
-
-  n = read (mouse->fd, &byte1, 1);
-  if ( (n!=1) || (byte1 & 0x40) != 0x40)
-    return TRUE;
-  
-  n = read (mouse->fd, &byte2, 1);
-  if ( (n!=1) || (byte2 & 0x40) != 0x00)
-    return TRUE;
-  
-  n = read (mouse->fd, &byte3, 1);
-  if (n!=1)
-    return TRUE;
-  
-  new_button1 = (byte1 & 0x20) && 1;
-  new_button2 = (byte1 & 0x10) && 1;
-  new_button3 = 0;
-  
-  if (new_button1 != mouse->button1_pressed)
-    {
-      mouse->button1_pressed = new_button1; 
-      send_button_event (mouse, 1, new_button1, the_time);
-    }
-  
-  if (new_button2 != mouse->button2_pressed)
-    {
-      mouse->button2_pressed = new_button2;
-      send_button_event (mouse, 2, new_button2, the_time);
-    }
-  
-  if (new_button3 != mouse->button3_pressed)
-    {
-      mouse->button3_pressed = new_button3; 
-      send_button_event (mouse, 3, new_button3, the_time);
-    }
-  
-  dx = (signed char)(((byte1 & 0x03) << 6) | (byte2 & 0x3F));
-  dy = (signed char)(((byte1 & 0x0C) << 4) | (byte3 & 0x3F));
-  
-  mouse->x += dx;
-  mouse->y += dy;
-  
-  if (dx || dy)
-    handle_mouse_input (mouse, TRUE);
-  
-  return TRUE;
-}
-
-static MouseDevice *
-mouse_open(void)
-{
-  MouseDevice *retval;
-  guchar buf[7];
-  int i = 0;
-  GIOChannel *gioc;
-  char *mousedev, *ctmp;
-  int mode;
-  struct termios tty;
-  enum { PS2_MOUSE, FIDMOUR_MOUSE, MS_MOUSE, UNKNOWN_MOUSE } type;
-  int flags;
-  fd_set fds;
-  char c;
-  struct timeval tv;
-      
-  retval = g_new0 (MouseDevice, 1);
-  retval->fd = -1;
-  mode = O_RDWR;
-  ctmp = getenv ("GDK_MOUSETYPE");
-  if (ctmp)
-    {
-      if (!strcmp (ctmp, "fidmour"))
-       type = FIDMOUR_MOUSE;
-      else if (!strcmp (ctmp, "ps2"))
-       type = PS2_MOUSE;
-      else if (!strcmp (ctmp, "ms"))
-       type = MS_MOUSE;
-      else
-       {
-         g_print ("Unknown mouse type %s\n", ctmp);
-         type = UNKNOWN_MOUSE;
-       }
-    }
-  else
-    type = PS2_MOUSE;
-
-  switch (type)
-    {
-    case PS2_MOUSE:
-      mousedev = "/dev/psaux";
-      mode = O_RDWR;
-      break;
-    case MS_MOUSE:
-      mousedev = "/dev/ttyS0";
-      mode = O_RDWR;
-      break;
-    case FIDMOUR_MOUSE:
-      mousedev = "/dev/fidmour";
-      mode = O_RDONLY;
-      break;
-    default:
-      goto error;
-      break;
-    }
-
-  ctmp = getenv ("GDK_MOUSEDEV");
-  if (ctmp)
-    mousedev = ctmp;
-
-  /* Use nonblocking mode to open, to not hang on device */
-  retval->fd = open (mousedev, mode | O_NONBLOCK);
-  if (retval->fd < 0)
-    goto error;
-
-  flags = fcntl (retval->fd, F_GETFL);
-  fcntl (retval->fd, F_SETFL, flags & ~O_NONBLOCK);
-
-  switch (type)
-    {
-    case PS2_MOUSE:
-      /* From xf86_Mouse.c */
-      buf[i++] = 230; /* 1:1 scaling */
-      buf[i++] = 244; /* enable mouse */
-      buf[i++] = 243; /* Sample rate */
-      buf[i++] = 200;
-      buf[i++] = 232; /* device resolution */
-      buf[i++] = 1;
-      write (retval->fd, buf, i);
-      fcntl (retval->fd, F_SETFL, O_RDWR|O_NONBLOCK);
-
-      usleep (10000); /* sleep 10 ms, then read whatever junk we can get from the mouse, in a vain attempt
-                       to get synchronized with the event stream */
-      while ((i = read (retval->fd, buf, sizeof(buf))) > 0)
-       g_print ("Got %d bytes of junk from psaux\n", i);
-
-      gioc = g_io_channel_unix_new (retval->fd);
-      retval->fd_tag = g_io_add_watch (gioc, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_input_ps2, retval);
-      break;
-
-    case MS_MOUSE:
-      /* Read all data from fd: */
-      FD_ZERO (&fds);
-      FD_SET (retval->fd, &fds);
-      tv.tv_sec = 0;
-      tv.tv_usec = 0;
-      while (select (retval->fd+1, &fds, NULL, NULL, &tv) > 0) {
-       FD_ZERO (&fds);
-       FD_SET (retval->fd, &fds);
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-       read (retval->fd, &c, 1);
-      } 
-
-      tcgetattr (retval->fd, &tty);
-      tty.c_iflag = IGNBRK | IGNPAR;
-      tty.c_cflag = CREAD|CLOCAL|HUPCL|CS7|B1200;
-      tty.c_oflag = 0;
-      tty.c_lflag = 0;
-      tty.c_line = 0;
-      tty.c_cc[VTIME] = 0;
-      tty.c_cc[VMIN] = 1;
-      tcsetattr (retval->fd, TCSAFLUSH, &tty);
-
-      write (retval->fd, "*n", 2);
-      
-      gioc = g_io_channel_unix_new (retval->fd);
-      retval->fd_tag = g_io_add_watch (gioc, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_input_ms, retval);
-      break;
-
-    case FIDMOUR_MOUSE:
-      fcntl (retval->fd, F_SETFL, O_RDONLY|O_NONBLOCK);
-      gioc = g_io_channel_unix_new (retval->fd);
-      /* We set the priority lower here because otherwise it will flood out all the other stuff */
-      retval->fd_tag = g_io_add_watch_full (gioc, G_PRIORITY_DEFAULT, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
-                                          handle_input_fidmour, retval, NULL);
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
-
-  retval->x = gdk_display->modeinfo.xres >> 1;
-  retval->y = gdk_display->modeinfo.yres >> 1;
-
-  return retval;
-
- error:
-  /* No errors allowed once fd_tag is added */
-  g_warning ("Failed to open mouse device\n");
-  if (retval->fd >= 0)
-    close (retval->fd);
-  g_free (retval);
-  return NULL;
-}
-
 void
 gdk_input_init (void)
 {
@@ -1085,21 +101,7 @@ gdk_input_init (void)
 
   gdk_input_ignore_core = FALSE;
 
-  gdk_fb_mouse = mouse_open ();
-}
-
-void
-gdk_input_get_mouseinfo (gint *x,
-                        gint *y,
-                        GdkModifierType *mask)
-{
-  *x = gdk_fb_mouse->x;
-  *y = gdk_fb_mouse->y;
-  *mask =
-    (gdk_fb_mouse->button1_pressed?GDK_BUTTON1_MASK:0) |
-    (gdk_fb_mouse->button2_pressed?GDK_BUTTON2_MASK:0) |
-    (gdk_fb_mouse->button3_pressed?GDK_BUTTON3_MASK:0) |
-    keyboard->modifier_state;
+  gdk_fb_mouse_open ();
 }
 
 GdkWindow *
index 8a7d258f79e65f574e509434591b4ef3b667ed26..c8f8d12a9e8ce76af1838f8a9748bf3d4f91a549 100644 (file)
@@ -966,10 +966,9 @@ gdk_event_make (GdkWindow *window,
 
   if (evmask & (GDK_BUTTON1_MOTION_MASK|GDK_BUTTON2_MOTION_MASK|GDK_BUTTON3_MOTION_MASK))
     {
-      gint x, y;
       GdkModifierType mask;
 
-      gdk_input_get_mouseinfo (&x, &y, &mask);
+      gdk_mouse_get_info (NULL, NULL, &mask);
 
       if (((mask & GDK_BUTTON1_MASK) && (evmask & GDK_BUTTON1_MOTION_MASK)) ||
          ((mask & GDK_BUTTON2_MASK) && (evmask & GDK_BUTTON2_MOTION_MASK)) ||
diff --git a/gdk/linux-fb/gdkmouse-fb.c b/gdk/linux-fb/gdkmouse-fb.c
new file mode 100644 (file)
index 0000000..3a149a2
--- /dev/null
@@ -0,0 +1,618 @@
+#include <gdk/gdk.h>
+#include <gdk/gdkinternals.h>
+#include "gdkprivate-fb.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <math.h>
+
+typedef struct _GdkFBMouse GdkFBMouse;
+typedef struct _GdkFBMouseDevice GdkFBMouseDevice;
+
+struct _GdkFBMouse {
+  gint fd; /* Set by open */
+
+  /* These are written to by parse_packet */
+  gdouble x, y;
+  gboolean button_pressed[3];
+
+  guchar mouse_packet[5]; /* read by parse_packet */
+  gint packet_nbytes;
+  
+  gboolean click_grab;
+  GIOChannel *io;
+  gint io_tag;
+
+  GdkFBMouseDevice *dev;
+};
+
+static GdkFBMouse *gdk_fb_mouse = NULL;
+
+void
+gdk_mouse_get_info (gint *x,
+                   gint *y,
+                   GdkModifierType *mask)
+{
+  if (x)
+    *x = gdk_fb_mouse->x;
+  if (y)
+    *y = gdk_fb_mouse->y;
+  if (mask)
+    *mask =
+      (gdk_fb_mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
+      (gdk_fb_mouse->button_pressed[1]?GDK_BUTTON2_MASK:0) |
+      (gdk_fb_mouse->button_pressed[2]?GDK_BUTTON3_MASK:0) |
+      /*keyboard->modifier_state*/0; //TODO
+}
+
+static void
+handle_mouse_movement(GdkFBMouse *mouse)
+{
+  GdkWindow *mousewin;
+  GdkEvent *event;
+  gint x, y;
+  GdkWindow *win, *grabwin;
+  guint state;
+  GdkDrawableFBData *mousewin_private;
+
+  if (_gdk_fb_pointer_grab_confine)
+    mousewin = _gdk_fb_pointer_grab_confine;
+  else
+    mousewin = gdk_parent_root;
+
+  mousewin_private = GDK_DRAWABLE_IMPL_FBDATA (mousewin);
+  
+  if (mouse->x < mousewin_private->llim_x)
+    mouse->x = mousewin_private->llim_x;
+  else if (mouse->x > mousewin_private->lim_x - 1)
+    mouse->x = mousewin_private->lim_x - 1;
+  
+  if (mouse->y < mousewin_private->llim_y)
+    mouse->y = mousewin_private->llim_y;
+  else if (mouse->y > mousewin_private->lim_y - 1)
+    mouse->y = mousewin_private->lim_y - 1;
+
+  win = gdk_window_at_pointer (NULL, NULL);
+  if (_gdk_fb_pointer_grab_window_events)
+    grabwin = _gdk_fb_pointer_grab_window_events;
+  else
+    grabwin = win;
+  
+  gdk_fb_cursor_move (mouse->x, mouse->y, grabwin);
+  
+  gdk_window_get_origin (grabwin, &x, &y);
+  x = mouse->x - x;
+  y = mouse->y - y;
+
+  state = (mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
+    (mouse->button_pressed[1]?GDK_BUTTON2_MASK:0) |
+    (mouse->button_pressed[2]?GDK_BUTTON3_MASK:0) |
+    /*keyboard->modifier_state*/0; // TODO
+
+  event = gdk_event_make (grabwin, GDK_MOTION_NOTIFY, TRUE);
+  if (event)
+    {
+      event->motion.x = x;
+      event->motion.y = y;
+      event->motion.state = state;
+      event->motion.is_hint = FALSE;
+      event->motion.device = gdk_core_pointer;
+      event->motion.x_root = mouse->x;
+      event->motion.y_root = mouse->y;
+    }
+
+  gdk_fb_window_send_crossing_events (win, GDK_CROSSING_NORMAL);
+}
+
+static void
+send_button_event (GdkFBMouse *mouse,
+                  guint button,
+                  gboolean press_event)
+{
+  GdkEvent *event;
+  gint x, y, i;
+  GdkWindow *window;
+  int nbuttons;
+
+  if (_gdk_fb_pointer_grab_window_events)
+    window = _gdk_fb_pointer_grab_window_events;
+  else
+    window = gdk_window_at_pointer(NULL, NULL);
+
+  event = gdk_event_make (window, press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE, FALSE);
+
+  if (event)
+    {
+      gdk_window_get_origin (window, &x, &y);
+      x = mouse->x - x;
+      y = mouse->y - y;
+      
+      event->button.x = x;
+      event->button.y = y;
+      event->button.button = button;
+      event->button.state = (mouse->button_pressed[0]?GDK_BUTTON1_MASK:0) |
+       (mouse->button_pressed[1] ? GDK_BUTTON2_MASK : 0) |
+       (mouse->button_pressed[2] ? GDK_BUTTON3_MASK : 0) |
+       (1 << (button + 8)) /* badhack */ |
+       /*keyboard->modifier_state*/0; // TODO
+      event->button.device = gdk_core_pointer;
+      event->button.x_root = mouse->x;
+      event->button.y_root = mouse->y;
+      
+      gdk_event_queue_append (event);
+      
+      /* For double-clicks */
+      if (press_event)
+       gdk_event_button_generate (event);
+    }
+
+  nbuttons = 0;
+  for (i=0;i<3;i++)
+    if (mouse->button_pressed[i])
+      nbuttons++;
+  
+  /* Handle implicit button grabs: */
+  if (press_event && nbuttons == 1)
+    {
+      gdk_fb_pointer_grab (window, FALSE,
+                          gdk_window_get_events (window),
+                          NULL, NULL,
+                          GDK_CURRENT_TIME, TRUE);
+      mouse->click_grab = TRUE;
+    }
+  else if (!press_event && nbuttons == 0 && mouse->click_grab)
+    {
+      gdk_fb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
+      mouse->click_grab = FALSE;
+    }
+}
+
+/******************************************************
+ ************ Device specific mouse code **************
+ ******************************************************/
+
+struct _GdkFBMouseDevice {
+  char *name;
+  gint packet_size;
+  gboolean (*open)(GdkFBMouse *mouse);
+  void (*close)(GdkFBMouse *mouse);
+  gboolean (*parse_packet)(GdkFBMouse *mouse, gboolean *got_motion);
+};
+
+static gboolean handle_mouse_io             (GIOChannel   *gioc,
+                                            GIOCondition  cond,
+                                            gpointer      data);
+static gboolean gdk_fb_mouse_ps2_open       (GdkFBMouse   *mouse);
+static void     gdk_fb_mouse_ps2_close      (GdkFBMouse   *mouse);
+static gboolean gdk_fb_mouse_ps2_packet     (GdkFBMouse   *mouse,
+                                            gboolean     *got_motion);
+static gboolean gdk_fb_mouse_ms_open        (GdkFBMouse   *mouse);
+static void     gdk_fb_mouse_ms_close       (GdkFBMouse   *mouse);
+static gboolean gdk_fb_mouse_ms_packet      (GdkFBMouse   *mouse,
+                                            gboolean     *got_motion);
+static gboolean gdk_fb_mouse_fidmour_open   (GdkFBMouse   *mouse);
+static void     gdk_fb_mouse_fidmour_close  (GdkFBMouse   *mouse);
+static gboolean gdk_fb_mouse_fidmour_packet (GdkFBMouse   *mouse,
+                                            gboolean     *got_motion);
+
+static GdkFBMouseDevice mouse_devs[] =
+{
+  { "ps2",
+    3,
+    gdk_fb_mouse_ps2_open,
+    gdk_fb_mouse_ps2_close,
+    gdk_fb_mouse_ps2_packet
+  },
+  { "ms",
+    3,
+    gdk_fb_mouse_ms_open,
+    gdk_fb_mouse_ms_close,
+    gdk_fb_mouse_ms_packet
+  },
+  { "fidmour",
+    5,
+    gdk_fb_mouse_fidmour_open,
+    gdk_fb_mouse_fidmour_close,
+    gdk_fb_mouse_fidmour_packet
+  }
+};
+
+
+gboolean
+gdk_fb_mouse_open (void)
+{
+  GdkFBMouse *mouse;
+  GdkFBMouseDevice *device;
+  char *mouse_type;
+  int i;
+
+  mouse = g_new0 (GdkFBMouse, 1);
+  mouse->fd = -1;
+  mouse_type = getenv ("GDK_MOUSETYPE");
+  if (!mouse_type)
+    mouse_type = "ps2";
+
+  for (i=0;i<G_N_ELEMENTS(mouse_devs);i++)
+    {
+      if (g_strcasecmp(mouse_type, mouse_devs[i].name)==0)
+       break;
+    }
+  
+  if (i == G_N_ELEMENTS(mouse_devs))
+    {
+      g_warning ("No mouse driver of type %s found\n", mouse_type);
+      return FALSE;
+    }
+
+  device = &mouse_devs[i];
+
+  mouse->dev = device;
+  
+  mouse->x = gdk_display->modeinfo.xres / 2;
+  mouse->y = gdk_display->modeinfo.yres / 2;
+
+  if (!device->open(mouse))
+    {
+      g_warning ("Mouse driver open failed\n");
+      g_free (mouse);
+      return FALSE;
+    }
+
+  mouse->io = g_io_channel_unix_new (mouse->fd);
+  mouse->io_tag = g_io_add_watch (mouse->io, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, handle_mouse_io, mouse);
+
+  gdk_fb_mouse = mouse;
+  return TRUE;
+}
+
+void 
+gdk_fb_mouse_close (void)
+{
+  g_source_remove (gdk_fb_mouse->io_tag);
+  gdk_fb_mouse->dev->close(gdk_fb_mouse);
+  g_io_channel_unref (gdk_fb_mouse->io);
+  g_free (gdk_fb_mouse);
+}
+
+static gboolean
+handle_mouse_io (GIOChannel *gioc,
+                GIOCondition cond,
+                gpointer data)
+{
+  GdkFBMouse *mouse = (GdkFBMouse *)data;
+  GdkFBMouseDevice *dev = mouse->dev;
+  gboolean got_motion;
+  gint n;
+
+  got_motion = FALSE;
+  
+  while (1)
+    {
+      n = read (mouse->fd, mouse->mouse_packet + mouse->packet_nbytes, dev->packet_size - mouse->packet_nbytes);
+      if (n<=0) /* error or nothing to read */
+       break;
+  
+      mouse->packet_nbytes += n;
+      
+      if (mouse->packet_nbytes == dev->packet_size)
+       {
+         if (dev->parse_packet (mouse, &got_motion))
+           mouse->packet_nbytes = 0;
+       }
+    }
+  
+  if (got_motion)
+    handle_mouse_movement (mouse);
+  
+  return TRUE;
+}
+
+static gint
+gdk_fb_mouse_dev_open (char *devname, gint mode)
+{
+  gint fd;
+  
+  /* Use nonblocking mode to open, to not hang on device */
+  fd = open (devname, mode | O_NONBLOCK);
+  return fd;
+}
+
+static gboolean
+gdk_fb_mouse_ps2_open (GdkFBMouse *mouse)
+{
+  gint fd;
+  guchar buf[7];
+  int i = 0;
+
+  fd = gdk_fb_mouse_dev_open ("/dev/psaux", O_RDWR);
+  if (fd < 0)
+    return FALSE;
+  
+  /* From xf86_Mouse.c */
+  buf[i++] = 230; /* 1:1 scaling */
+  buf[i++] = 244; /* enable mouse */
+  buf[i++] = 243; /* Sample rate */
+  buf[i++] = 200;
+  buf[i++] = 232; /* device resolution */
+  buf[i++] = 1;
+  
+  write (fd, buf, i);
+  
+  usleep (10000); /* sleep 10 ms, then read whatever junk we can get from the mouse, in a vain attempt
+                    to get synchronized with the event stream */
+  
+  while ((i = read (fd, buf, sizeof(buf))) > 0)
+    g_print ("Got %d bytes of junk from psaux\n", i);
+  
+  mouse->fd = fd;
+  return TRUE;
+}
+
+static void
+gdk_fb_mouse_ps2_close (GdkFBMouse *mouse)
+{
+  close (mouse->fd);
+}
+
+static gboolean
+gdk_fb_mouse_ps2_packet (GdkFBMouse *mouse, gboolean *got_motion)
+{
+  int dx=0, dy=0;
+  gboolean new_button1, new_button2, new_button3;
+  guchar *buf;
+
+  buf = mouse->mouse_packet;
+      
+  new_button1 = (buf[0] & 1) && 1;
+  new_button3 = (buf[0] & 2) && 1;
+  new_button2 = (buf[0] & 4) && 1;
+  
+
+  if (*got_motion &&
+      (new_button1 != mouse->button_pressed[0] ||
+       new_button2 != mouse->button_pressed[1] ||
+       new_button3 != mouse->button_pressed[2]))
+    {
+      /* If a mouse button state changes we need to get correct ordering with enter/leave events,
+        so push those out via handle_mouse_input */
+      *got_motion = FALSE;
+      handle_mouse_movement (mouse);
+    }
+
+  if (new_button1 != mouse->button_pressed[0])
+    {
+      mouse->button_pressed[0] = new_button1; 
+      send_button_event (mouse, 1, new_button1);
+    }
+  
+  if (new_button2 != mouse->button_pressed[1])
+    {
+      mouse->button_pressed[1] = new_button2;
+      send_button_event (mouse, 2, new_button2);
+    }
+  
+  if (new_button3 != mouse->button_pressed[2])
+    {
+      mouse->button_pressed[2] = new_button3; 
+      send_button_event (mouse, 3, new_button3);
+    }
+      
+  if (buf[1] != 0)
+    dx = ((buf[0] & 0x10) ? ((gint)buf[1])-256 : buf[1]);
+  else
+    dx = 0;
+  if (buf[2] != 0)
+    dy = -((buf[0] & 0x20) ? ((gint)buf[2])-256 : buf[2]);
+  else
+    dy = 0;
+  
+  mouse->x += dx;
+  mouse->y += dy;
+  
+  if (dx || dy)
+    *got_motion = TRUE;
+
+  return TRUE;
+}
+
+
+static gboolean
+gdk_fb_mouse_ms_open (GdkFBMouse   *mouse)
+{
+  gint fd;
+  gint i;
+  guchar buf[7];
+  struct termios tty;
+
+  fd = gdk_fb_mouse_dev_open ("/dev/ttyS0", O_RDWR);
+  if (fd < 0)
+    return FALSE;
+  
+  while ((i = read (fd, buf, sizeof(buf))) > 0)
+    g_print ("Got %d bytes of junk from psaux\n", i);
+
+  tcgetattr (fd, &tty);
+  tty.c_iflag = IGNBRK | IGNPAR;
+  tty.c_cflag = CREAD|CLOCAL|HUPCL|CS7|B1200;
+  tty.c_oflag = 0;
+  tty.c_lflag = 0;
+  tty.c_line = 0;
+  tty.c_cc[VTIME] = 0;
+  tty.c_cc[VMIN] = 1;
+  tcsetattr (fd, TCSAFLUSH, &tty);
+  
+  write (fd, "*n", 2);
+
+  mouse->fd = fd;
+  return TRUE;
+}
+
+static void
+gdk_fb_mouse_ms_close (GdkFBMouse   *mouse)
+{
+  close (mouse->fd);
+}
+
+static gboolean
+gdk_fb_mouse_ms_packet (GdkFBMouse   *mouse,
+                       gboolean     *got_motion)
+{
+  int dx=0, dy=0;
+  gboolean new_button1, new_button2, new_button3;
+  guchar *buf;
+
+  buf = mouse->mouse_packet;
+
+  new_button1 = (buf[0] & 0x20) && 1;
+  new_button2 = (buf[1] & 0x10) && 1;
+  new_button3 = 0;
+
+  if (*got_motion &&
+      (new_button1 != mouse->button_pressed[0] ||
+       new_button2 != mouse->button_pressed[1] ||
+       new_button3 != mouse->button_pressed[2]))
+    {
+      /* If a mouse button state changes we need to get correct ordering with enter/leave events,
+        so push those out via handle_mouse_input */
+      *got_motion = FALSE;
+      handle_mouse_movement (mouse);
+    }
+
+  if (new_button1 != mouse->button_pressed[0])
+    {
+      mouse->button_pressed[0] = new_button1; 
+      send_button_event (mouse, 1, new_button1);
+    }
+  
+  if (new_button2 != mouse->button_pressed[1])
+    {
+      mouse->button_pressed[1] = new_button2;
+      send_button_event (mouse, 2, new_button2);
+    }
+  
+  if (new_button3 != mouse->button_pressed[2])
+    {
+      mouse->button_pressed[2] = new_button3; 
+      send_button_event (mouse, 3, new_button3);
+    }
+
+  dx = (signed char)(((buf[0] & 0x03) << 6) | (buf[1] & 0x3F));
+  dy = (signed char)(((buf[0] & 0x0C) << 4) | (buf[2] & 0x3F));
+  
+  mouse->x += dx;
+  mouse->y += dy;
+  
+  if (dx || dy)
+    *got_motion = TRUE;
+
+  return TRUE;
+}
+
+static gboolean
+gdk_fb_mouse_fidmour_open (GdkFBMouse   *mouse)
+{
+  gint fd;
+
+  fd = gdk_fb_mouse_dev_open ("/dev/fidmour", O_RDONLY);
+  if (fd < 0)
+    return FALSE;
+  
+  mouse->fd = fd;
+  return TRUE;
+}
+
+static void
+gdk_fb_mouse_fidmour_close (GdkFBMouse   *mouse)
+{
+  close (mouse->fd);
+}
+
+static gboolean
+gdk_fb_mouse_fidmour_packet (GdkFBMouse   *mouse,
+                            gboolean     *got_motion)
+{
+  int n;
+  gboolean btn_down = 0;
+  gdouble x = 0.0, y = 0.0;
+
+  n = 0;
+  if (!(mouse->mouse_packet[0] & 0x80))
+    {
+      int i;
+      /* We haven't received any of the packet yet but there is no header at the beginning */
+      for (i = 1; i < mouse->packet_nbytes; i++)
+       {
+         if (mouse->mouse_packet[i] & 0x80)
+           {
+             n = i;
+             break;
+           }
+       }
+    }
+  else if (mouse->packet_nbytes > 1 &&
+          ((mouse->mouse_packet[0] & 0x90) == 0x90))
+    {
+      /* eat the 0x90 and following byte, no clue what it's for */
+      n = 2;
+    }
+  else
+    {
+      switch (mouse->mouse_packet[0] & 0xF)
+       {
+       case 2:
+         btn_down = 0;
+         break;
+       case 1:
+       case 0:
+         btn_down = 1;
+         break;
+       default:
+         g_assert_not_reached ();
+         break;
+       }
+      
+      x = mouse->mouse_packet[1] + (mouse->mouse_packet[2] << 7);
+      if (x > 8192)
+       x -= 16384;
+      y = mouse->mouse_packet[3] + (mouse->mouse_packet[4] << 7);
+      if (y > 8192)
+       y -= 16384;
+      /* Now map touchscreen coords to screen coords */
+      x *= ((double)gdk_display->modeinfo.xres)/4096.0;
+      y *= ((double)gdk_display->modeinfo.yres)/4096.0;
+    }
+  
+  if (n)
+    {
+      memmove (mouse->mouse_packet, mouse->mouse_packet+n, mouse->packet_nbytes-n);
+      mouse->packet_nbytes -= n;
+      return FALSE;
+    }
+
+  if (btn_down != mouse->button_pressed[0])
+    {
+      if (*got_motion)
+       {
+         /* If a mouse button state changes we need to get correct
+            ordering with enter/leave events, so push those out
+            via handle_mouse_input */
+         *got_motion = FALSE;
+         handle_mouse_movement (mouse);
+       }
+      
+      mouse->button_pressed[0] = btn_down;
+      send_button_event (mouse, 1, btn_down);
+    }
+  
+  if (fabs(x - mouse->x) >= 1.0 || fabs(x - mouse->y) >= 1.0)
+    {
+      *got_motion = TRUE;
+      mouse->x = x;
+      mouse->y = y;
+    }
+  
+  return TRUE;
+}
index 5f830e7dfe02a46fa4a5ba272a5be59b22e9a1fc..06d026ca942af73faf4999db123cb6394ff264db 100644 (file)
@@ -264,8 +264,6 @@ void      gdk_window_invalidate_region_clear (GdkWindow       *window,
                                              GdkRegion       *region);
 void      gdk_window_invalidate_rect_clear   (GdkWindow       *window,
                                              GdkRectangle    *rect);
-GdkWindow *gdk_fb_find_common_ancestor       (GdkWindow       *win1,
-                                             GdkWindow       *win2);
 
 GdkGC *   _gdk_fb_gc_new                     (GdkDrawable     *drawable,
                                              GdkGCValues     *values,
@@ -386,13 +384,18 @@ void gdk_fb_cursor_unhide(void);
 void gdk_fb_cursor_reset(void);
 void gdk_fb_cursor_hide(void);
 void gdk_fb_redraw_all(void);
+void gdk_fb_cursor_move (gint x, gint y, GdkWindow *in_window);
 
-void gdk_input_get_mouseinfo            (gint *x, 
-                                        gint *y, 
-                                        GdkModifierType *mask);
 void gdk_fb_window_send_crossing_events (GdkWindow *dest,
                                         GdkCrossingMode mode);
 
+gboolean gdk_fb_mouse_open  (void);
+void     gdk_fb_mouse_close (void);
+void     gdk_mouse_get_info (gint *x, 
+                            gint *y, 
+                            GdkModifierType *mask);
+
+
 #define PANGO_TYPE_FB_FONT              (pango_fb_font_get_type ())
 #define PANGO_FB_FONT(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FB_FONT, PangoFBFont))
 
index b4b691d03974d73d344d9a8f58062e18d7cd612b..0d03563a8e7892a16d342f8c55bab3cb30907890 100644 (file)
@@ -34,6 +34,8 @@
 
 #include <limits.h>
 
+/* Global variables: */
+static GdkWindow *gdk_fb_window_containing_pointer = NULL;
 static gpointer parent_class = NULL;
 
 static void recompute_drawable (GdkDrawable *drawable);
@@ -438,7 +440,7 @@ gdk_fb_redraw_all (void)
   gdk_window_process_all_updates ();
 }
 
-GdkWindow *
+static GdkWindow *
 gdk_fb_find_common_ancestor (GdkWindow *win1,
                             GdkWindow *win2)
 {
@@ -474,6 +476,180 @@ gdk_fb_find_common_ancestor (GdkWindow *win1,
   return GDK_WINDOW (tmp);
 }
 
+void
+gdk_fb_window_send_crossing_events (GdkWindow *dest,
+                                   GdkCrossingMode mode)
+{
+  GdkWindow *c;
+  GdkWindow *win, *last, *next;
+  GdkEvent *event;
+  gint x, y, x_int, y_int;
+  GdkModifierType my_mask;
+  GList *path, *list;
+  gboolean non_linear;
+  gboolean only_grabbed_window;
+  GdkWindow *a;
+  GdkWindow *b;
+
+  if ((mode == GDK_CROSSING_NORMAL) &&
+      (dest == gdk_fb_window_containing_pointer))
+    return;
+
+  if (gdk_fb_window_containing_pointer == NULL)
+    gdk_fb_window_containing_pointer = gdk_window_ref (gdk_parent_root);
+
+  if (mode == GDK_CROSSING_UNGRAB)
+    a = _gdk_fb_pointer_grab_window;
+  else
+    a = gdk_fb_window_containing_pointer;
+  b = dest;
+
+  /* When grab in progress only send normal crossing events about
+   * the grabbed window.
+   */
+  only_grabbed_window = (_gdk_fb_pointer_grab_window_events != NULL) &&
+                        (mode == GDK_CROSSING_NORMAL);
+  
+  if (a==b)
+    return;
+
+  gdk_mouse_get_info (&x, &y, &my_mask);
+
+  c = gdk_fb_find_common_ancestor (a, b);
+
+  non_linear = (c != a) && (c != b);
+
+  if (!only_grabbed_window || (a == _gdk_fb_pointer_grab_window))
+    event = gdk_event_make (a, GDK_LEAVE_NOTIFY, TRUE);
+  else
+    event = NULL;
+  if (event)
+    {
+      event->crossing.subwindow = NULL;
+      gdk_window_get_root_origin (a, &x_int, &y_int);
+      event->crossing.x = x - x_int;
+      event->crossing.y = y - y_int;
+      event->crossing.x_root = x;
+      event->crossing.y_root = y;
+      event->crossing.mode = mode;
+      if (non_linear)
+       event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+      else if (c==a)
+       event->crossing.detail = GDK_NOTIFY_INFERIOR;
+      else
+       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+      event->crossing.focus = FALSE;
+      event->crossing.state = my_mask;
+    }
+  
+  /* Traverse up from a to (excluding) c */
+  if (c != a)
+    {
+      last = a;
+      win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
+      while (win != c)
+       {
+         if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
+           event = gdk_event_make (win, GDK_LEAVE_NOTIFY, TRUE);
+         else
+           event = NULL;
+         if (event)
+           {
+             event->crossing.subwindow = gdk_window_ref (last);
+             gdk_window_get_root_origin (win, &x_int, &y_int);
+             event->crossing.x = x - x_int;
+             event->crossing.y = y - y_int;
+             event->crossing.x_root = x;
+             event->crossing.y_root = y;
+             event->crossing.mode = mode;
+             if (non_linear)
+               event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+             else
+               event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+             event->crossing.focus = FALSE;
+             event->crossing.state = my_mask;
+           }
+         last = win;
+         win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
+       }
+    }
+  
+  /* Traverse down from c to b */
+  if (c != b) 
+    {
+      path = NULL;
+      win = GDK_WINDOW( GDK_WINDOW_OBJECT (b)->parent);
+      while (win != c)
+       {
+         path = g_list_prepend (path, win);
+         win = GDK_WINDOW( GDK_WINDOW_OBJECT (win)->parent);
+       }
+      
+      list = path;
+      while (list) 
+       {
+         win = (GdkWindow *)list->data;
+         list = g_list_next (list);
+         if (list)
+           next = (GdkWindow *)list->data;
+         else 
+           next = b;
+         
+         if (!only_grabbed_window || (win == _gdk_fb_pointer_grab_window))
+           event = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE);
+         else
+           event = NULL;
+         if (event)
+           {
+             event->crossing.subwindow = gdk_window_ref (next);
+             gdk_window_get_root_origin (win, &x_int, &y_int);
+             event->crossing.x = x - x_int;
+             event->crossing.y = y - y_int;
+             event->crossing.x_root = x;
+             event->crossing.y_root = y;
+             event->crossing.mode = mode;
+             if (non_linear)
+               event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+             else
+               event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+             event->crossing.focus = FALSE;
+             event->crossing.state = my_mask;
+           }
+       }
+      g_list_free (path);
+    }
+
+  if (!only_grabbed_window || (b == _gdk_fb_pointer_grab_window))
+    event = gdk_event_make (b, GDK_ENTER_NOTIFY, TRUE);
+  else
+    event = NULL;
+  if (event)
+    {
+      event->crossing.subwindow = NULL;
+      gdk_window_get_root_origin (b, &x_int, &y_int);
+      event->crossing.x = x - x_int;
+      event->crossing.y = y - y_int;
+      event->crossing.x_root = x;
+      event->crossing.y_root = y;
+      event->crossing.mode = mode;
+      if (non_linear)
+       event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+      else if (c==a)
+       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+      else
+       event->crossing.detail = GDK_NOTIFY_INFERIOR;
+      event->crossing.focus = FALSE;
+      event->crossing.state = my_mask;
+    }
+
+  if ((mode != GDK_CROSSING_GRAB) &&
+      (b != gdk_fb_window_containing_pointer))
+    {
+      gdk_window_unref (gdk_fb_window_containing_pointer);
+      gdk_fb_window_containing_pointer = gdk_window_ref (b);
+    }
+}
+
 void
 gdk_window_show (GdkWindow *window)
 {
@@ -1231,7 +1407,7 @@ gdk_window_get_pointer (GdkWindow       *window,
     window = gdk_parent_root;
   
   gdk_window_get_root_origin (window, &x_int, &y_int);
-  gdk_input_get_mouseinfo (&winx, &winy, &my_mask);
+  gdk_mouse_get_info (&winx, &winy, &my_mask);
 
   winx -= x_int;
   winy -= y_int;