⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdkmouse-fb.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GDK - The GIMP Drawing Kit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <gdk/gdk.h>#include <gdk/gdkinternals.h>#include "gdkprivate-fb.h"#include "gdkinputprivate.h"#include <stdlib.h>#include <sys/types.h>#include <fcntl.h>#include <termios.h>#include <sys/ioctl.h>#include <string.h>#include <math.h>#include <unistd.h>#include <errno.h>typedef struct _GdkFBMouse GdkFBMouse;typedef struct _GdkFBMouseDevice GdkFBMouseDevice;struct _GdkFBMouse {  gint fd; /* Set by open */  gchar *file;  /* 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;voidgdk_fb_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) |      gdk_fb_keyboard_modifiers ();}static voidhandle_mouse_movement(GdkFBMouse *mouse){  GdkWindow *mousewin;  GdkEvent *event;  gint x, y;  GdkWindow *old_win, *win, *event_win, *cursor_win;  guint state;  GdkDrawableFBData *mousewin_private;  old_win = gdk_window_at_pointer (NULL, NULL);    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);  cursor_win = win;  if (_gdk_fb_pointer_grab_window)    {      GdkWindow *w;            cursor_win = _gdk_fb_pointer_grab_window;      w = win;      while (w != _gdk_parent_root)	{	  if (w == _gdk_fb_pointer_grab_window)	    {	      cursor_win = win;	      break;	    }	  w = gdk_window_get_parent (w);	}    }    gdk_fb_cursor_move (mouse->x, mouse->y, cursor_win);  event_win = gdk_fb_pointer_event_window (win, GDK_MOTION_NOTIFY);  if (event_win && (win == old_win))    {      /* Only send motion events in the same window */      gdk_window_get_origin (event_win, &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) |	gdk_fb_keyboard_modifiers ();      event = gdk_event_make (event_win, GDK_MOTION_NOTIFY, TRUE);      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 (NULL, win, GDK_CROSSING_NORMAL);}static voidsend_button_event (GdkFBMouse *mouse,		   guint button,		   gboolean press_event){  GdkEvent *event;  gint x, y, i;  GdkWindow *mouse_win;  GdkWindow *event_win;  int nbuttons;    mouse_win = gdk_window_at_pointer(NULL, NULL);  event_win = gdk_fb_pointer_event_window (mouse_win,					   press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);    if (event_win)    {      event = gdk_event_make (event_win, press_event ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE, FALSE);            gdk_window_get_origin (event_win, &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 */ |	gdk_fb_keyboard_modifiers ();      event->button.device = _gdk_core_pointer;      event->button.x_root = mouse->x;      event->button.y_root = mouse->y;            _gdk_event_queue_append (gdk_display_get_default (), event);            /* For double-clicks */      if (press_event)	_gdk_event_button_generate (gdk_display_get_default (), 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 (mouse_win, FALSE,			   gdk_window_get_events (mouse_win),			   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 voidhandle_mouse_scroll (GdkFBMouse *mouse,		     gboolean    up){  GdkEvent *event;  gint x, y;  GdkWindow *mouse_win;  mouse_win = gdk_window_at_pointer(NULL, NULL);  event = gdk_event_make (mouse_win, GDK_SCROLL, FALSE);  gdk_window_get_origin (mouse_win, &x, &y);  x = mouse->x - x;  y = mouse->y - y;  event->button.window = mouse_win;  event->scroll.direction = up ? GDK_SCROLL_UP : GDK_SCROLL_DOWN;  event->scroll.window = mouse_win;  event->scroll.time = GDK_CURRENT_TIME;  event->scroll.x = x;  event->scroll.y = y;  event->scroll.x_root = mouse->x;  event->scroll.y_root = mouse->y;  event->scroll.state = gdk_fb_keyboard_modifiers ();  event->scroll.device = _gdk_core_pointer;  _gdk_event_queue_append (gdk_display_get_default (), event);}/****************************************************** ************ Device specific mouse code ************** ******************************************************//* proto is used to detect the start of the packet: *   (buf[0]&proto[0]) == proto[1] * indicates start of packet. */struct _GdkFBMouseDevice {  gchar *name;  gchar *file;  gint packet_size;  gboolean (*open)(GdkFBMouse *mouse);  void (*close)(GdkFBMouse *mouse);  gboolean (*parse_packet)(GdkFBMouse *mouse, gboolean *got_motion);  guchar proto[2];};static gboolean handle_mouse_io             (GIOChannel   *gioc,					     GIOCondition  cond,					     gpointer      data);static gboolean gdk_fb_mouse_ps2_open       (GdkFBMouse   *mouse);static gboolean gdk_fb_mouse_imps2_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",    "/dev/psaux",    3,    gdk_fb_mouse_ps2_open,    gdk_fb_mouse_ps2_close,    gdk_fb_mouse_ps2_packet,    { 0xc0, 0x00 }  },  { "imps2",    "/dev/psaux",    4,    gdk_fb_mouse_imps2_open,    gdk_fb_mouse_ps2_close,    gdk_fb_mouse_ps2_packet,    { 0xc0, 0x00 }  },  { "ms",    "/dev/mouse",    3,    gdk_fb_mouse_ms_open,    gdk_fb_mouse_ms_close,    gdk_fb_mouse_ms_packet,    { 0x40, 0x40 }  },  { "fidmour",    "/dev/fidmour",    5,    gdk_fb_mouse_fidmour_open,    gdk_fb_mouse_fidmour_close,    gdk_fb_mouse_fidmour_packet,    { 0x00, 0x00 } /* don't know what packet start looks like */  }};gbooleangdk_fb_mouse_init (gboolean open_dev){  gchar *mouse_type, *mouse_file;  gint i;  gdk_fb_mouse = g_new0 (GdkFBMouse, 1);  gdk_fb_mouse->fd = -1;  mouse_type = getenv ("GDK_MOUSE_TYPE");  if (!mouse_type)    mouse_type = "ps2";        for (i=0;i<G_N_ELEMENTS(mouse_devs);i++)    {      if (g_ascii_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", mouse_type);      return FALSE;    }  gdk_fb_mouse->dev = &mouse_devs[i];  mouse_file = getenv ("GDK_MOUSE_FILE");  if (!mouse_file)    mouse_file = gdk_fb_mouse->dev->file;  gdk_fb_mouse->file = mouse_file;  gdk_fb_mouse->x = gdk_display->fb_width / 2;  gdk_fb_mouse->y = gdk_display->fb_height / 2;  if (open_dev)    return gdk_fb_mouse_open ();  else    return TRUE;}gbooleangdk_fb_mouse_open (void){  GdkFBMouseDevice *device;  device = gdk_fb_mouse->dev;  if (!device->open(gdk_fb_mouse))    {      g_warning ("Mouse driver open failed");      return FALSE;    }  gdk_fb_mouse->io =     g_io_channel_unix_new (gdk_fb_mouse->fd);  gdk_fb_mouse->io_tag =     g_io_add_watch (gdk_fb_mouse->io,		    G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, 		    handle_mouse_io, gdk_fb_mouse);  return TRUE;}void gdk_fb_mouse_close (void){  if (gdk_fb_mouse->io_tag)    {      g_source_remove (gdk_fb_mouse->io_tag);      gdk_fb_mouse->io_tag = 0;    }      gdk_fb_mouse->dev->close(gdk_fb_mouse); if (gdk_fb_mouse->io)   {     g_io_channel_unref (gdk_fb_mouse->io);     gdk_fb_mouse->io = NULL;   }}static gbooleanhandle_mouse_io (GIOChannel *gioc,		 GIOCondition cond,		 gpointer data){  GdkFBMouse *mouse = (GdkFBMouse *)data;  GdkFBMouseDevice *dev = mouse->dev;  guchar *proto = dev->proto;  gboolean got_motion;  gint n, i;  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;      /* we just read in what should be the first byte of a packet */      if (mouse->packet_nbytes == 0)	{	  /* check to see if we have the first byte of a packet.	   * if not, throw it away */	  while ((mouse->mouse_packet[0] & proto[0]) != proto[1] && n > 0)	    {	      for (i = 1; i < n; i++)		mouse->mouse_packet[i-1] = mouse->mouse_packet[i];	      n--;	    }	  /* if none of the bytes read were packet starts, break */	  if (n <= 0)	    break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -