diff options
Diffstat (limited to 'source/a/gpm/gpm-evdev-cumulative.patch')
-rw-r--r-- | source/a/gpm/gpm-evdev-cumulative.patch | 7023 |
1 files changed, 0 insertions, 7023 deletions
diff --git a/source/a/gpm/gpm-evdev-cumulative.patch b/source/a/gpm/gpm-evdev-cumulative.patch deleted file mode 100644 index 2fd86d10..00000000 --- a/source/a/gpm/gpm-evdev-cumulative.patch +++ /dev/null @@ -1,7023 +0,0 @@ -diff -urN gpm-1.20.1/configure.in gpm/configure.in ---- gpm-1.20.1/configure.in 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/configure.in 2003-10-02 01:22:42.000000000 -0500 -@@ -61,6 +61,13 @@ - - AC_CHECK_HEADERS(syslog.h linux/input.h linux/joystick.h ncurses.h ncurses/curses.h curses.h) - -+EVDEV_SRCS= -+if test ${ac_cv_header_linux_input_h} = yes ; then -+ EVDEV_SRCS=evdev.c ; -+ AC_CHECK_TYPE(struct input_absinfo,AC_DEFINE_UNQUOTED(HAVE_INPUT_ABSINFO, 1, [define if struct input_absinfo defined in linux/input.h]),,[#include <linux/input.h>]) -+ AC_CHECK_TYPE(struct input_id,AC_DEFINE_UNQUOTED(HAVE_INPUT_ID, 1, [define if struct input_id defined in linux/input.h]),,[#include <linux/input.h>]) -+fi -+ - AC_ARG_WITH(curses, - [ --without-curses disable curses support even if curses found]) - -@@ -124,6 +131,7 @@ - AC_SUBST(PICFLAGS) - AC_SUBST(SOLDFLAGS) - AC_SUBST(CURSES_OBJS) -+AC_SUBST(EVDEV_SRCS) - AC_SUBST(SHARED_LIBS) - AC_SUBST(lispdir) - -diff -urN gpm-1.20.1/src/client.c gpm/src/client.c ---- gpm-1.20.1/src/client.c 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/client.c 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,319 @@ -+/* -+ * client.c - GPM client handling (server side) -+ * -+ * Copyright (C) 1993 Andreq Haylett <ajh@gec-mrc.co.uk> -+ * Copyright (C) 1994-1999 Alessandro Rubini <rubini@linux.it> -+ * Copyright (C) 1998 Ian Zimmerman <itz@rahul.net> -+ * Copyright (c) 2001,2002 Nico Schottelius <nico@schottelius.org> -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> /* strerror(); ?!? */ -+#include <errno.h> -+#include <unistd.h> /* select(); */ -+#include <signal.h> /* SIGPIPE */ -+#include <time.h> /* time() */ -+#include <sys/fcntl.h> /* O_RDONLY */ -+#include <sys/stat.h> /* mkdir() */ -+#include <sys/time.h> /* timeval */ -+#include <sys/types.h> /* socket() */ -+#include <sys/socket.h> /* socket() */ -+#include <sys/un.h> /* struct sockaddr_un */ -+ -+#include "headers/gpmInt.h" -+#include "headers/message.h" -+#include "headers/console.h" -+#include "headers/selection.h" -+#include "headers/client.h" -+ -+/* who the f*** runs gpm without glibc? doesn't have dietlibc __socklent_t? */ -+#if !defined(__GLIBC__) -+ typedef unsigned int __socklen_t; -+#endif /* __GLIBC__ */ -+ -+#ifndef max -+#define max(a,b) ((a)>(b) ? (a) : (b)) -+#endif -+ -+extern int errno; -+ -+struct client_info *cinfo[MAX_VC + 1]; -+ -+/*-------------------------------------------------------------------* -+ * This was inline, and incurred in a compiler bug (2.7.0) -+ *-------------------------------------------------------------------*/ -+static int get_data(int fd, Gpm_Connect *data) -+{ -+ static int len; -+ -+#ifdef GPM_USE_MAGIC -+ while ((len = read(whence, &check, sizeof(int))) == 4 && -+ check != GPM_MAGIC) -+ gpm_report(GPM_PR_INFO, GPM_MESS_NO_MAGIC); -+ -+ if (len == 0) return 0; -+ -+ if (check != GPM_MAGIC) { -+ gpm_report(GPM_PR_INFO, GPM_MESS_NOTHING_MORE); -+ return -1; -+ } -+#endif -+ -+ len = read(fd, data, sizeof(Gpm_Connect)); -+ -+ return len ? (len == sizeof(Gpm_Connect) ? 1 : -1) : 0; -+} -+ -+/*-------------------------------------------------------------------*/ -+int listen_for_clients(void) -+{ -+ struct sockaddr_un ctladdr; -+ int fd, len; -+ -+ unlink(GPM_NODE_CTL); -+ -+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_SOCKET_PROB); -+ -+ memset(&ctladdr, 0, sizeof(ctladdr)); -+ ctladdr.sun_family = AF_UNIX; -+ strcpy(ctladdr.sun_path, GPM_NODE_CTL); -+ len = sizeof(ctladdr.sun_family) + strlen(GPM_NODE_CTL); -+ -+ if (bind(fd, (struct sockaddr *)&ctladdr, len) == -1) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_BIND_PROB, ctladdr.sun_path); -+ -+ /* needs to be 0777, so all users can _try_ to access gpm */ -+ chmod(GPM_NODE_CTL, 0777); -+ listen(fd, 5); /* Queue up calls */ -+ -+ return fd; -+} -+ -+/*-------------------------------------------------------------------*/ -+struct client_info *accept_client_connection(int fd) -+{ -+ struct client_info *info; -+ Gpm_Connect *request; -+ int newfd; -+#if !defined(__GLIBC__) -+ int len; -+#else /* __GLIBC__ */ -+ size_t len; /* isn't that generally defined in C ??? -- nico */ -+#endif /* __GLIBC__ */ -+ struct sockaddr_un addr; /* reuse this each time */ -+#ifndef SO_PEERCRED -+ struct stat statbuf; -+ time_t staletime; -+#endif -+ uid_t uid; -+ -+ /*....................................... Accept */ -+ memset(&addr, 0, sizeof(addr)); -+ addr.sun_family = AF_UNIX; -+ -+ len = sizeof(addr); -+ if ((newfd = accept(fd, (struct sockaddr *)&addr, &len)) < 0) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_ACCEPT_FAILED, strerror(errno)); -+ return NULL; -+ } -+ -+ gpm_report(GPM_PR_INFO, GPM_MESS_CONECT_AT, newfd); -+ -+ if (!(info = malloc(sizeof(struct client_info)))) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_NO_MEM); -+ -+ request = &info->data; -+ if (get_data(newfd, request) == -1) -+ goto err; -+ -+ if (request->vc > MAX_VC) { -+ gpm_report(GPM_PR_WARN,GPM_MESS_REQUEST_ON, request->vc, MAX_VC); -+ goto err; -+ } -+ -+#ifndef SO_PEERCRED -+ if (stat(addr.sun_path, &statbuf) == -1 || !S_ISSOCK(statbuf.st_mode)) { -+ gpm_report(GPM_PR_ERR,GPM_MESS_ADDRES_NSOCKET,addr.sun_path); -+ goto err; -+ } -+ -+ unlink(addr.sun_path); /* delete socket */ -+ -+ staletime = time(0) - 30; -+ if (statbuf.st_atime < staletime || -+ statbuf.st_ctime < staletime || -+ statbuf.st_mtime < staletime) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_SOCKET_OLD); -+ goto err; -+ } -+ -+ uid = statbuf.st_uid; /* owner of socket */ -+#else -+ { -+ struct ucred sucred; -+ socklen_t credlen = sizeof(struct ucred); -+ -+ if (getsockopt(newfd, SOL_SOCKET, SO_PEERCRED, &sucred, &credlen) == -1) { -+ gpm_report(GPM_PR_ERR,GPM_MESS_GETSOCKOPT, strerror(errno)); -+ goto err; -+ } -+ uid = sucred.uid; -+ gpm_report(GPM_PR_DEBUG,GPM_MESS_PEER_SCK_UID, uid); -+ } -+#endif -+ -+ if (uid != 0 && !is_console_owner(request->vc, uid)) { -+ gpm_report(GPM_PR_WARN, GPM_MESS_FAILED_CONNECT, uid, request->vc); -+ goto err; -+ } -+ -+ /* register the connection information in the right place */ -+ info->next = cinfo[request->vc]; -+ info->fd = newfd; -+ cinfo[request->vc] = info; -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_LONG_STATUS, -+ request->pid, request->vc, request->eventMask, request->defaultMask, -+ request->minMod, request->maxMod); -+ -+ return info; -+ -+err: -+ free(info); -+ close(newfd); -+ -+ return NULL; -+} -+ -+/*-------------------------------------------------------------------*/ -+void remove_client(struct client_info *ci, int vc) -+{ -+ struct client_info *p, *prev = NULL; -+ -+ for (p = cinfo[vc]; p; prev = p, p = p->next) { -+ if (p == ci) { -+ if (!prev) /* it is on top of the stack */ -+ cinfo[vc] = p->next; -+ else -+ prev->next = p->next; -+ break; -+ } -+ } -+ if (p) free(p); -+} -+ -+/*-------------------------------------------------------------------*/ -+void notify_clients_resize(void) -+{ -+ struct client_info *ci; -+ int i; -+ -+ for (i = 0; i < MAX_VC + 1; i++) -+ for (ci = cinfo[i]; ci; ci = ci->next) -+ kill(ci->data.pid, SIGWINCH); -+} -+ -+/*-------------------------------------------------------------------*/ -+/* returns 0 if the event has not been processed, and 1 if it has */ -+int do_client(struct client_info *cinfo, Gpm_Event *event) -+{ -+ Gpm_Connect *info = &cinfo->data; -+ /* value to return if event is not used */ -+ int res = !(info->defaultMask & event->type); -+ -+ /* instead of returning 0, scan the stack of clients */ -+ if ((info->minMod & event->modifiers) < info->minMod) -+ goto try_next; -+ if ((info->maxMod & event->modifiers) < event->modifiers) -+ goto try_next; -+ -+ /* if not managed, use default mask */ -+ if (!(info->eventMask & GPM_BARE_EVENTS(event->type))) { -+ if (res) return res; -+ else goto try_next; -+ } -+ -+ /* WARNING */ /* This can generate a SIGPIPE... I'd better catch it */ -+ MAGIC_P((write(cinfo->fd, &magic, sizeof(int)))); -+ write(cinfo->fd, event, sizeof(Gpm_Event)); -+ -+ return info->defaultMask & GPM_HARD ? res : 1; /* HARD forces pass-on */ -+ -+ try_next: -+ if (cinfo->next != 0) -+ return do_client(cinfo->next, event); /* try the next */ -+ -+ return 0; /* no next, not used */ -+} -+ -+/*-------------------------------------------------------------------*/ -+/* returns 0 if client disconnects, -1 - error, 1 -successs */ -+int process_client_request(struct client_info *ci, int vc, -+ int x, int y, int buttons, int clicks, -+ int three_button_mouse) -+{ -+ int rc; -+ Gpm_Connect conn; -+ static Gpm_Event event; -+ -+ gpm_report(GPM_PR_INFO, GPM_MESS_CON_REQUEST, ci->fd, vc); -+ if (vc > MAX_VC) return -1; -+ -+ /* itz 10-22-96 this shouldn't happen now */ -+ if (vc == -1) gpm_report(GPM_PR_OOPS, GPM_MESS_UNKNOWN_FD); -+ -+ rc = get_data(ci->fd, &conn); -+ -+ if (rc == 0) { /* no data */ -+ gpm_report(GPM_PR_INFO, GPM_MESS_CLOSE); -+ close(ci->fd); -+ return 0; -+ } -+ -+ if (rc == -1) return -1; /* too few bytes */ -+ -+ if (conn.pid != 0) { -+ ci->data = conn; -+ return 1; -+ } -+ -+ /* Aha, request for information (so-called snapshot) */ -+ switch (conn.vc) { -+ case GPM_REQ_SNAPSHOT: -+ event.vc = get_console_state(&event.modifiers); -+ event.x = x; event.y = y; -+ event.buttons = buttons; -+ event.clicks = clicks; -+ event.dx = console.max_x; event.dy = console.max_y; -+ /* fall through */ -+ -+ case GPM_REQ_BUTTONS: -+ event.type = (three_button_mouse == 1 ? 3 : 2); /* buttons */ -+ write(ci->fd, &event, sizeof(Gpm_Event)); -+ break; -+ -+ case GPM_REQ_NOPASTE: -+ selection_disable_paste(); -+ gpm_report(GPM_PR_INFO, GPM_MESS_DISABLE_PASTE, vc); -+ break; -+ } -+ -+ return 1; -+} -+ -diff -urN gpm-1.20.1/src/console.c gpm/src/console.c ---- gpm-1.20.1/src/console.c 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/console.c 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,257 @@ -+/* -+ * console.c - GPM console and selection/paste handling -+ * -+ * Copyright (C) 1993 Andreq Haylett <ajh@gec-mrc.co.uk> -+ * Copyright (C) 1994-1999 Alessandro Rubini <rubini@linux.it> -+ * Copyright (C) 1998 Ian Zimmerman <itz@rahul.net> -+ * Copyright (c) 2001,2002 Nico Schottelius <nico@schottelius.org> -+ * Copyright (c) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> /* strerror(); ?!? */ -+#include <errno.h> -+#include <unistd.h> /* select(); */ -+#include <time.h> /* time() */ -+#include <sys/fcntl.h> /* O_RDONLY */ -+#include <sys/stat.h> /* mkdir() */ -+#include <asm/types.h> /* __u32 */ -+ -+#include <linux/vt.h> /* VT_GETSTATE */ -+#include <sys/kd.h> /* KDGETMODE */ -+#include <termios.h> /* winsize */ -+ -+#include "headers/gpmInt.h" -+#include "headers/console.h" -+#include "headers/message.h" -+ -+#ifndef HAVE___U32 -+# ifndef _I386_TYPES_H /* /usr/include/asm/types.h */ -+typedef unsigned int __u32; -+# endif -+#endif -+ -+struct gpm_console console = { 0, DEF_LUT, 0, 0 }; -+ -+/*-------------------------------------------------------------------*/ -+static int count_digits(int num) -+{ -+ int digits = 1; -+ -+ while ((num /= 10)) -+ digits++; -+ -+ return digits; -+} -+ -+/*-------------------------------------------------------------------*/ -+char *compose_vc_name(int vc) -+{ -+ char *tty; -+ -+ tty = malloc(strlen(console.device) + count_digits(vc) + sizeof(char)); -+ if (tty) { -+ /* console is /dev/vc/0 or /dev/tty0 and we trimming the ending 0 */ -+ strncpy(tty, console.device, strlen(console.device) - 1); -+ sprintf(&tty[strlen(console.device) - 1], "%d", vc); -+ } -+ -+ return tty; -+} -+ -+/*-------------------------------------------------------------------*/ -+int open_console(int mode) -+{ -+ int fd; -+ -+ if ((fd = open(console.device, mode)) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN_CON); -+ -+ return fd; -+} -+ -+/*-------------------------------------------------------------------*/ -+int is_text_console(void) -+{ -+ int fd; -+ int kd_mode; -+ -+ fd = open_console(O_RDONLY); -+ if (ioctl(fd, KDGETMODE, &kd_mode)<0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_IOCTL_KDGETMODE); -+ close(fd); -+ -+ return kd_mode == KD_TEXT; -+} -+ -+/*-------------------------------------------------------------------*/ -+void wait_text_console(void) -+{ -+ do { -+ sleep(2); -+ } while (!is_text_console()); -+} -+ -+/*-------------------------------------------------------------------*/ -+void refresh_console_size(void) -+{ -+ struct winsize win; -+ int fd = open_console(O_RDONLY); -+ -+ ioctl(fd, TIOCGWINSZ, &win); -+ close(fd); -+ -+ if (!win.ws_col || !win.ws_row) { -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_ZERO_SCREEN_DIM); -+ console.max_x = 80; console.max_y = 25; -+ } else { -+ console.max_x = win.ws_col; console.max_y = win.ws_row; -+ } -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_SCREEN_SIZE, console.max_x, console.max_y); -+} -+ -+/*-------------------------------------------------------------------*/ -+int get_console_state(unsigned char *shift_state) -+{ -+ struct vt_stat stat; -+ int fd; -+ -+ fd = open_console(O_RDONLY); -+ -+ *shift_state = 6; /* code for the ioctl */ -+ if (ioctl(fd, TIOCLINUX, shift_state) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_GET_SHIFT_STATE); -+ -+ if (ioctl(fd, VT_GETSTATE, &stat) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_GET_CONSOLE_STAT); -+ -+ close(fd); -+ -+ return stat.v_active; -+} -+ -+/*-------------------------------------------------------------------*/ -+int is_console_owner(int vc, uid_t uid) -+{ -+ struct stat statbuf; -+ char *tty; -+ int rc; -+ -+ if ((tty = compose_vc_name(vc)) == NULL) -+ gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -+ -+ if ((rc = stat(tty, &statbuf)) == -1) -+ gpm_report(GPM_PR_ERR, GPM_MESS_STAT_FAILS, tty); -+ -+ free(tty); -+ -+ return rc != -1 && uid == statbuf.st_uid; -+} -+ -+/*-------------------------------------------------------------------*/ -+/* octal digit */ -+static int isodigit(const unsigned char c) -+{ -+ return ((c & ~7) == '0'); -+} -+ -+/*-------------------------------------------------------------------*/ -+/* routine to convert digits from octal notation (Andries Brouwer) */ -+static int getsym(const unsigned char *p0, unsigned char *res) -+{ -+ const unsigned char *p = p0; -+ char c; -+ -+ c = *p++; -+ if (c == '\\' && *p) { -+ c = *p++; -+ if (isodigit(c)) { -+ c -= '0'; -+ if (isodigit(*p)) c = 8*c + (*p++ - '0'); -+ if (isodigit(*p)) c = 8*c + (*p++ - '0'); -+ } -+ } -+ *res = c; -+ return (p - p0); -+} -+ -+/*-------------------------------------------------------------------*/ -+/* description missing! FIXME */ -+void console_load_lut(void) -+{ -+ extern int errno; -+ int i, c, fd; -+ unsigned char this, next; -+ static __u32 long_array[9] = { -+ 0x05050505, /* ugly, but preserves alignment */ -+ 0x00000000, /* control chars */ -+ 0x00000000, /* digits */ -+ 0x00000000, /* uppercase and '_' */ -+ 0x00000000, /* lowercase */ -+ 0x00000000, /* Latin-1 control */ -+ 0x00000000, /* Latin-1 misc */ -+ 0x00000000, /* Latin-1 uppercase */ -+ 0x00000000 /* Latin-1 lowercase */ -+ }; -+ -+#define inwordLut (long_array+1) -+ -+ for (i = 0; console.charset[i]; ) { -+ i += getsym(console.charset + i, &this); -+ if (console.charset[i] == '-' && console.charset[i + 1] != '\0') -+ i += getsym(console.charset + i + 1, &next) + 1; -+ else -+ next = this; -+ for (c = this; c <= next; c++) -+ inwordLut[c >> 5] |= 1 << (c & 0x1F); -+ } -+ -+ fd = open_console(O_WRONLY); -+ -+ if (ioctl(fd, TIOCLINUX, &long_array) < 0) { /* fd <0 is checked */ -+ if (errno == EPERM && getuid()) -+ gpm_report(GPM_PR_WARN, GPM_MESS_ROOT); /* why do we still continue?*/ -+ else if (errno == EINVAL) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_CSELECT); -+ } -+ close(fd); -+} -+ -+/*-------------------------------------------------------------------*/ -+/* Returns the name of the console (/dev/tty0 or /dev/vc/0) */ -+/* Also fills console.device */ -+char *get_console_name() -+{ -+ struct stat buf; -+ -+ /* first try the devfs device, because in the next time this will be -+ * the preferred one. If that fails, take the old console */ -+ -+ /* Check for open new console */ -+ if (stat(GPM_DEVFS_CONSOLE, &buf) == 0) -+ console.device = GPM_DEVFS_CONSOLE; -+ -+ /* Failed, try OLD console */ -+ else if (stat(GPM_OLD_CONSOLE, &buf) == 0) -+ console.device = GPM_OLD_CONSOLE; -+ else -+ gpm_report(GPM_PR_OOPS, "Can't determine console device"); -+ -+ return console.device; -+} -+ -diff -urN gpm-1.20.1/src/evdev.c gpm/src/evdev.c ---- gpm-1.20.1/src/evdev.c 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/evdev.c 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,851 @@ -+/* -+ * evdev.c - support for event input devices in linux 2.4 & 2.6 -+ * -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * Based on XFree86 driver by Stefan Gmeiner & Peter Osterlund -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <string.h> -+#include <time.h> -+#include <sys/select.h> -+#include <sys/time.h> -+ -+#include <linux/input.h> -+#include "headers/input-defines.h" /* misisng bits in case <linux/input.h> is old */ -+ -+#include "headers/gpm.h" -+#include "headers/gpmInt.h" -+#include "headers/console.h" -+#include "headers/message.h" -+#include "headers/optparser.h" -+ -+enum evdev_type { -+ EVDEV_UNKNOWN, -+ EVDEV_RELATIVE, -+ EVDEV_ABSOLUTE, -+ EVDEV_TOUCHPAD, -+ EVDEV_SYNAPTICS -+}; -+ -+enum touch_type { -+ TOUCH_NONE, -+ TOUCH_FINGERS, -+ TOUCH_PALM -+}; -+ -+enum gesture_type { -+ GESTURE_NONE, -+ GESTURE_TAP_PENDING, -+ GESTURE_TAP, -+ GESTURE_DRAG_PENDING, -+ GESTURE_DRAG, -+ GESTURE_DOUBLE_TAP -+}; -+ -+enum edge_type { -+ BOTTOM_EDGE = 1, -+ TOP_EDGE = 2, -+ LEFT_EDGE = 4, -+ RIGHT_EDGE = 8, -+ LEFT_BOTTOM_EDGE = BOTTOM_EDGE | LEFT_EDGE, -+ RIGHT_BOTTOM_EDGE = BOTTOM_EDGE | RIGHT_EDGE, -+ RIGHT_TOP_EDGE = TOP_EDGE | RIGHT_EDGE, -+ LEFT_TOP_EDGE = TOP_EDGE | LEFT_EDGE -+}; -+ -+struct event_data { -+ int dx, dy; -+ int wdx, wdy; -+ int abs_x, abs_y; -+ int buttons; -+ int touch; /* dumb touchpad report touch events, smart ones - pressure */ -+ int pressure; -+ int w; -+ int finger_count; -+ int synced; -+}; -+ -+struct touch_data { -+ int touching; -+ int x, y; -+ int finger_count; -+ int buttons; -+ int clicks; -+ struct timeval start; -+ enum gesture_type gesture; -+}; -+ -+struct event_device { -+ enum evdev_type type; -+ int dont_sync; -+ -+ struct event_data pkt; -+ int pkt_count; -+ -+ int prev_x[4], prev_y[4]; -+ int prev_pressure, avg_w; -+ struct touch_data touch; -+ -+ int left_edge, right_edge; -+ int top_edge, bottom_edge; -+ int touch_high, touch_low; -+ int tap_time, tap_move; -+ int y_inverted; -+ -+ enum touch_type (*detect_touch)(struct event_device *evdev); -+ void (*update_finger_count)(struct event_device *evdev); -+}; -+ -+struct evdev_capabilities { -+ unsigned char evbits[EV_MAX/8 + 1]; -+ unsigned char keybits[KEY_MAX/8 + 1]; -+ unsigned char absbits[ABS_MAX/8 + 1]; -+ unsigned char mscbits[MSC_MAX/8 + 1]; -+}; -+ -+#ifndef max -+#define max(a,b) ((a)>(b) ? (a) : (b)) -+#endif -+ -+#define fx(i) (evdev->prev_x[(evdev->pkt_count - (i)) & 03]) -+#define fy(i) (evdev->prev_y[(evdev->pkt_count - (i)) & 03]) -+ -+#define toggle_btn(btn, val) do { if (val) data->buttons |= (btn);\ -+ else data->buttons &= ~(btn);\ -+ } while (0) -+#define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL)) -+#define DIF_TIME(t1,t2) ((t2.tv_sec - t1.tv_sec) * 1000 + (t2.tv_usec - t1.tv_usec) / 1000) -+ -+#define test_bit(bit, array) (array[bit / 8] & (1 << (bit % 8))) -+ -+/* ------------- evdev protocol handling routines ---------------------*/ -+ -+static void parse_input_event(struct input_event *event, struct event_data *data) -+{ -+ switch (event->type) { -+ case EV_REL: -+ switch (event->code) { -+ case REL_X: -+ data->dx = (signed char)event->value; -+ break; -+ case REL_Y: -+ data->dy = (signed char)event->value; -+ break; -+ case REL_WHEEL: -+ data->wdy += event->value; -+ break; -+ case REL_HWHEEL: -+ data->wdx += event->value; -+ break; -+ } -+ break; -+ -+ case EV_ABS: -+ switch (event->code) { -+ case ABS_X: -+ data->abs_x = event->value; -+ break; -+ -+ case ABS_Y: -+ data->abs_y = event->value; -+ break; -+ -+ case ABS_PRESSURE: -+ data->pressure = event->value; -+ break; -+ -+ case ABS_TOOL_WIDTH: -+ data->w = event->value; -+ break; -+ } -+ break; -+ -+ case EV_MSC: -+ switch (event->code) { -+ case MSC_GESTURE: -+ data->w = event->value; -+ break; -+ } -+ break; -+ -+ -+ case EV_KEY: -+ switch(event->code) { -+ case BTN_0: -+ case BTN_LEFT: -+ toggle_btn(GPM_B_LEFT, event->value); -+ break; -+ -+ case BTN_2: -+ case BTN_STYLUS2: -+ case BTN_SIDE: -+ case BTN_MIDDLE: -+ toggle_btn(GPM_B_MIDDLE, event->value); -+ break; -+ -+ case BTN_STYLUS: -+ case BTN_1: -+ case BTN_RIGHT: -+ toggle_btn(GPM_B_RIGHT, event->value); -+ break; -+ -+ case BTN_TOUCH: -+ data->touch = event->value ? 1 : 0; -+ break; -+ -+ case BTN_TOOL_FINGER: -+ if (event->value) data->finger_count = 1; -+ break; -+ -+ case BTN_TOOL_DOUBLETAP: -+ if (event->value) data->finger_count = 2; -+ break; -+ -+ case BTN_TOOL_TRIPLETAP: -+ if (event->value) data->finger_count = 3; -+ break; -+ -+ } -+ break; -+ -+ case EV_SYNC: -+ switch(event->code) { -+ case SYN_REPORT: -+ data->synced = 1; -+ break; -+ } -+ break; -+ } -+} -+ -+static void tp_figure_deltas(struct event_device *evdev, struct Gpm_Event *state) -+{ -+ struct event_data *pkt = &evdev->pkt; -+ -+ state->dx = state->dy = 0; -+ if (evdev->touch.touching) { -+ fx(0) = pkt->abs_x; -+ fy(0) = pkt->abs_y; -+ if (evdev->pkt_count >= 2 && -+ evdev->touch.gesture != GESTURE_DRAG_PENDING) { -+ state->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8; //SYN_REL_DECEL_FACTOR; -+ state->dy = ((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8; //SYN_REL_DECEL_FACTOR; -+ } -+ evdev->pkt_count++; -+ } else { -+ evdev->pkt_count = 0; -+ } -+} -+ -+static enum touch_type dumb_tp_detect_touch(struct event_device *evdev) -+{ -+ return evdev->pkt.touch ? TOUCH_FINGERS : TOUCH_NONE; -+} -+ -+static enum touch_type smart_tp_detect_touch(struct event_device *evdev) -+{ -+ if (evdev->touch.touching) -+ return evdev->pkt.pressure > evdev->touch_low ? TOUCH_FINGERS : TOUCH_NONE; -+ else -+ return evdev->pkt.pressure > evdev->touch_high ? TOUCH_FINGERS : TOUCH_NONE; -+} -+ -+static enum touch_type syn_detect_touch(struct event_device *evdev) -+{ -+ struct event_data *pkt = &evdev->pkt; -+ enum touch_type type = TOUCH_NONE; -+ -+ if (pkt->pressure > 200 || pkt->w > 10) -+ return TOUCH_PALM; -+ -+ if (pkt->abs_x == 0) -+ evdev->avg_w = 0; -+ else -+ evdev->avg_w = (pkt->w - evdev->avg_w + 1) / 2; -+ -+ if (evdev->touch.touching) { -+ type = pkt->pressure > evdev->touch_low ? TOUCH_FINGERS : TOUCH_NONE; -+ } else if (pkt->pressure > evdev->touch_high) { -+ int safe_w = max(pkt->w, evdev->avg_w); -+ -+ if (pkt->finger_count > 1) -+ type = TOUCH_FINGERS; -+ else if (pkt->w < 2) -+ type = TOUCH_FINGERS; /* more than one finger -> not a palm */ -+ else if (safe_w < 6 && evdev->prev_pressure < evdev->touch_high) -+ type = TOUCH_FINGERS; /* thin finger, distinct touch -> not a palm */ -+ else if (safe_w < 7 && evdev->prev_pressure < evdev->touch_high / 2) -+ type = TOUCH_FINGERS; /* thin finger, distinct touch -> not a palm */ -+ else if (pkt->pressure > evdev->prev_pressure + 1) -+ type = TOUCH_NONE; /* pressure not stable, may be a palm */ -+ else if (pkt->pressure < evdev->prev_pressure - 5) -+ type = TOUCH_NONE; /* pressure not stable, may be a palm */ -+ else -+ type = TOUCH_FINGERS; -+ } -+ -+ evdev->prev_pressure = pkt->pressure; -+ return type; -+} -+ -+static enum edge_type tp_detect_edges(struct event_device *evdev, int x, int y) -+{ -+ enum edge_type edge = 0; -+ -+ if (x > evdev->right_edge) -+ edge |= RIGHT_EDGE; -+ else if (x < evdev->left_edge) -+ edge |= LEFT_EDGE; -+ -+ if (y < evdev->top_edge) -+ edge |= TOP_EDGE; -+ else if (y > evdev->bottom_edge) -+ edge |= BOTTOM_EDGE; -+ -+ return edge; -+} -+ -+static int tp_touch_expired(struct event_device *evdev) -+{ -+ struct timeval now; -+ -+ GET_TIME(now); -+ return DIF_TIME(evdev->touch.start, now) > evdev->tap_time; -+} -+ -+static int tp_detect_tap(struct event_device *evdev) -+{ -+ return !tp_touch_expired(evdev) && -+ (evdev->touch.finger_count > 1 || -+ (abs(evdev->pkt.abs_x - evdev->touch.x) < evdev->tap_move && -+ abs(evdev->pkt.abs_y - evdev->touch.y) < evdev->tap_move)); -+} -+ -+static int tp_tap_to_buttons(struct event_device *evdev) -+{ -+ enum edge_type edge; -+ if (evdev->touch.finger_count < 2) { -+ edge = tp_detect_edges(evdev, evdev->pkt.abs_x, evdev->pkt.abs_y); -+ switch (edge) { -+ case RIGHT_TOP_EDGE: -+ return GPM_B_MIDDLE; -+ break; -+ case RIGHT_BOTTOM_EDGE: -+ return GPM_B_RIGHT; -+ break; -+ default: -+ return GPM_B_LEFT; -+ break; -+ } -+ } else { -+ switch (evdev->touch.finger_count) { -+ case 2: -+ return GPM_B_MIDDLE; -+ case 3: -+ return GPM_B_RIGHT; -+ default: -+ return GPM_B_LEFT; -+ } -+ } -+} -+ -+static void tp_detect_gesture(struct event_device *evdev, int timed_out, enum touch_type touch_type) -+{ -+ struct touch_data *touch = &evdev->touch; -+ int was_touching = touch->touching; -+ -+ touch->touching = touch_type == TOUCH_FINGERS; -+ -+ if (touch->touching) { -+ if (!was_touching) { -+ GET_TIME(touch->start); -+ touch->finger_count = 0; -+ if (touch->gesture == GESTURE_TAP_PENDING) { -+ touch->gesture = GESTURE_DRAG_PENDING; -+ } else { -+ touch->x = evdev->pkt.abs_x; -+ touch->y = evdev->pkt.abs_y; -+ touch->buttons = 0; -+ } -+ } else if (touch->gesture == GESTURE_DRAG_PENDING && tp_touch_expired(evdev)) { -+ touch->gesture = GESTURE_DRAG; -+ } -+ } else { -+ if (was_touching) { -+ if (tp_detect_tap(evdev)) { -+ if (touch->gesture == GESTURE_DRAG_PENDING) { -+ touch->gesture = GESTURE_DOUBLE_TAP; -+ touch->clicks = 4; -+ } else { -+ if ((touch->buttons = tp_tap_to_buttons(evdev)) == GPM_B_LEFT) { -+ touch->gesture = GESTURE_TAP_PENDING; -+ } else { -+ touch->gesture = GESTURE_TAP; -+ touch->clicks = 2; -+ } -+ } -+ } else { -+ touch->gesture = GESTURE_NONE; -+ } -+ } else { -+ if (touch->gesture == GESTURE_TAP_PENDING && tp_touch_expired(evdev)) { -+ touch->gesture = GESTURE_TAP; -+ touch->clicks = 2; -+ } -+ } -+ } -+} -+ -+static int tp_process_gesture(struct event_device *evdev, struct Gpm_Event *state) -+{ -+ int next_timeout = -1; -+ -+ switch(evdev->touch.gesture) { -+ case GESTURE_DOUBLE_TAP: -+ case GESTURE_TAP: -+ if (--evdev->touch.clicks == 0) -+ evdev->touch.gesture = GESTURE_NONE; -+ else -+ next_timeout = 0; -+ -+ if (evdev->touch.clicks % 2) -+ state->buttons |= evdev->touch.buttons; -+ else -+ state->buttons &= ~evdev->touch.buttons; -+ break; -+ -+ case GESTURE_DRAG: -+ state->buttons |= evdev->touch.buttons; -+ break; -+ -+ case GESTURE_DRAG_PENDING: -+ case GESTURE_TAP_PENDING: -+ next_timeout = evdev->tap_time; -+ break; -+ -+ default: -+ break; -+ } -+ return next_timeout; -+} -+ -+static void tp_update_finger_count(struct event_device *evdev) -+{ -+ evdev->touch.finger_count = max(evdev->pkt.finger_count, evdev->touch.finger_count); -+} -+ -+static void syn_update_finger_count(struct event_device *evdev) -+{ -+ if (evdev->pkt.w == 1) -+ evdev->touch.finger_count = 3; -+ else if (evdev->pkt.w == 0 && evdev->touch.finger_count != 3) -+ evdev->touch.finger_count = 2; -+ else -+ evdev->touch.finger_count = 1; -+} -+ -+static int compose_gpm_event(struct event_device *evdev, int timed_out, Gpm_Event *state) -+{ -+ struct event_data *pkt = &evdev->pkt; -+ enum touch_type touch_type; -+ int next_timeout = -1; -+ -+ if (!timed_out) { -+ state->buttons = pkt->buttons; -+ state->wdx = pkt->wdx; state->wdy = pkt->wdy; -+ } -+ -+ switch (evdev->type) { -+ case EVDEV_RELATIVE: -+ if (!timed_out) { -+ state->dx = pkt->dx; state->dy = pkt->dy; -+ if (evdev->pkt.touch) -+ state->buttons |= GPM_B_LEFT; -+ else -+ state->buttons &= ~GPM_B_LEFT; -+ } -+ break; -+ -+ case EVDEV_ABSOLUTE: -+ if (!timed_out) { -+ if (pkt->abs_x < evdev->left_edge) -+ pkt->abs_x = evdev->left_edge; -+ else if (pkt->abs_x > evdev->right_edge) -+ pkt->abs_x = evdev->right_edge; -+ -+ if (pkt->abs_y > evdev->bottom_edge) -+ pkt->abs_y = evdev->bottom_edge; -+ else if (pkt->abs_y < evdev->top_edge) -+ pkt->abs_y = evdev->top_edge; -+ -+ state->x = (pkt->abs_x - evdev->left_edge) * -+ console.max_x / (evdev->right_edge - evdev->left_edge); -+ state->y = (pkt->abs_y - evdev->top_edge) * -+ console.max_y / (evdev->bottom_edge - evdev->top_edge); -+ -+ if (evdev->y_inverted) state->y = console.max_y - state->y; -+ -+ if (evdev->pkt.touch) -+ state->buttons |= GPM_B_LEFT; -+ else -+ state->buttons &= ~GPM_B_LEFT; -+ } -+ break; -+ -+ case EVDEV_TOUCHPAD: -+ case EVDEV_SYNAPTICS: -+ touch_type = timed_out ? TOUCH_NONE : evdev->detect_touch(evdev); -+ -+ if (touch_type != TOUCH_PALM) { -+ tp_detect_gesture(evdev, timed_out, touch_type); -+ -+ if (evdev->touch.touching && !tp_touch_expired(evdev)) -+ evdev->update_finger_count(evdev); -+ -+ if (evdev->touch.finger_count < 2) -+ tp_figure_deltas(evdev, state); -+ -+ next_timeout = tp_process_gesture(evdev, state); -+ } -+ break; -+ -+ default: -+ /* should not happen */ -+ gpm_report(GPM_PR_OOPS, "Bad evdev type %d", evdev->type); -+ break; -+ } -+ -+ if (evdev->y_inverted) state->dy = -state->dy; -+ -+ return next_timeout; -+} -+ -+int M_evdev(struct micedev *dev, struct miceopt *opts, -+ unsigned char *data, struct Gpm_Event *state) -+{ -+ struct event_device *evdev = dev->private; -+ struct input_event *event = (struct input_event *)data; -+ int timed_out = data == NULL; -+ -+ if (!timed_out) -+ parse_input_event(event, &evdev->pkt); -+ -+ if (timed_out || evdev->pkt.synced || evdev->dont_sync) { -+ dev->timeout = compose_gpm_event(evdev, timed_out, state); -+ evdev->pkt.dx = evdev->pkt.dy = 0; -+ evdev->pkt.wdx = evdev->pkt.wdy = 0; -+ evdev->pkt.finger_count = 0; -+ evdev->pkt.synced = 0; -+ return 0; -+ } -+ -+ dev->timeout = -1; -+ return -1; -+} -+ -+/* ------------- evdev initialization routines ---------------------*/ -+ -+static int evdev_get_id(int fd, struct input_id *id) -+{ -+ if (ioctl(fd, EVIOCGID, id) < 0) { -+ gpm_report(GPM_PR_ERR, "evdev: cannot query device identification"); -+ return -1; -+ } -+ return 0; -+} -+ -+static int evdev_get_capabilities(int fd, struct evdev_capabilities *caps) -+{ -+ memset(caps, 0, sizeof(*caps)); -+ -+ if (ioctl(fd, EVIOCGBIT(0, EV_MAX), caps->evbits) < 0) { -+ gpm_report(GPM_PR_ERR, "evdev: cannot query device capabilities"); -+ return -1; -+ } -+ -+ if (test_bit(EV_ABS, caps->evbits) && -+ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(caps->absbits)), caps->absbits) < 0) { -+ gpm_report(GPM_PR_ERR, "evdev: cannot query ABS device capabilities"); -+ return -1; -+ } -+ -+ if (test_bit(EV_KEY, caps->evbits) && -+ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(caps->keybits)), caps->keybits) < 0) { -+ gpm_report(GPM_PR_ERR, "evdev: cannot query KEY device capabilities"); -+ return -1; -+ } -+ -+ if (test_bit(EV_MSC, caps->evbits) && -+ ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(caps->mscbits)), caps->mscbits) < 0) { -+ /* don't complain as 2.4 kernels didnt have it -+ gpm_report(GPM_PR_ERR, "evdev: cannot query MSC device capabilities"); -+ return -1; -+ */ -+ } -+ return 0; -+} -+ -+static int evdev_query_axis(int fd, int axis, int *axis_min, int *axis_max) -+{ -+ struct input_absinfo axis_info; -+ -+ if (ioctl(fd, EVIOCGABS(axis), &axis_info) == -1) { -+ gpm_report(GPM_PR_ERR, "evdev: could not query axis data"); -+ return -1; -+ } -+ -+ *axis_min = axis_info.minimum; -+ *axis_max = axis_info.maximum; -+ return 0; -+} -+ -+static int evdev_get_limits(int fd, struct event_device *evdev, -+ struct evdev_capabilities *caps) -+{ -+ if (test_bit(ABS_X, caps->absbits) && -+ evdev_query_axis(fd, ABS_X, &evdev->left_edge, &evdev->right_edge) < 0) -+ return -1; -+ -+ if (test_bit(ABS_Y, caps->absbits) && -+ evdev_query_axis(fd, ABS_Y, &evdev->top_edge, &evdev->bottom_edge) < 0) -+ return -1; -+ -+ return 0; -+} -+ -+static int is_synaptics(struct input_id *id) -+{ -+ return id->bustype == BUS_I8042 && id->vendor == 0x0002 && id->product == PSMOUSE_SYNAPTICS; -+} -+ -+static enum evdev_type evdev_guess_type(struct input_id *id, struct evdev_capabilities *caps) -+{ -+ if (test_bit(EV_ABS, caps->evbits)) { -+ if (is_synaptics(id)) -+ return EVDEV_SYNAPTICS; -+ -+ if (test_bit(BTN_TOUCH, caps->keybits) && caps->keybits[BTN_MOUSE / 8]) -+ return EVDEV_TOUCHPAD; -+ -+ return EVDEV_ABSOLUTE; -+ } -+ -+ if (!test_bit(EV_REL, caps->evbits)) { -+ gpm_report(GPM_PR_ERR, -+ "evdev: device does not report neither absolute nor relative coordinates"); -+ return EVDEV_UNKNOWN; -+ } -+ -+ return EVDEV_RELATIVE; -+} -+ -+static enum evdev_type evdev_str_to_type(const char *type) -+{ -+ if (!strcmp(type, "relative")) { -+ return EVDEV_RELATIVE; -+ } else if (!strcmp(type, "absolute")) { -+ return EVDEV_ABSOLUTE; -+ } else if (!strcmp(type, "touchpad")) { -+ return EVDEV_TOUCHPAD; -+ } else if (!strcmp(type, "synaptics")) { -+ return EVDEV_SYNAPTICS; -+ } else { -+ gpm_report(GPM_PR_ERR, "evdev: unknown type '%s'", type); -+ return EVDEV_UNKNOWN; -+ } -+} -+ -+static void warn_if_present(struct option_helper *optinfo, const char *name, const char *type) -+{ -+ if (is_option_present(optinfo, name)) -+ gpm_report(GPM_PR_WARN, -+ "evdev: option '%s' is not valud for type '%s', ignored", -+ name, type); -+} -+ -+// -o type=(auto|synaptics|touchpad|relative|absolute),y_inverse, -+// left=1234,right=1234,top=1234,bottom=1234, -+// touch_high=30,touch_low=25,tap_time=30,tap_move=100 -+static int evdev_apply_options(struct event_device *evdev, char *optstring) -+{ -+ char *type = "auto"; -+ struct option_helper optinfo[] = { -+ { "type", OPT_STRING, u: { sptr: &type } }, -+ { "y_inverted", OPT_BOOL, u: { iptr: &evdev->y_inverted }, value: 1 }, -+ { "left", OPT_INT, u: { iptr: &evdev->left_edge } }, -+ { "right", OPT_INT, u: { iptr: &evdev->right_edge } }, -+ { "top", OPT_INT, u: { iptr: &evdev->top_edge } }, -+ { "bottom", OPT_INT, u: { iptr: &evdev->bottom_edge } }, -+ { "touch_high", OPT_INT, u: { iptr: &evdev->touch_high } }, -+ { "touch_low", OPT_INT, u: { iptr: &evdev->touch_low } }, -+ { "tap_time", OPT_INT, u: { iptr: &evdev->tap_time } }, -+ { "tap_move", OPT_INT, u: { iptr: &evdev->tap_move } }, -+ { "", OPT_END } -+ }; -+ -+ if (parse_options("evdev", optstring, ',', optinfo) < 0) -+ return -1; -+ -+ if (strcmp(type, "auto")) -+ evdev->type = evdev_str_to_type(type); -+ -+ switch (evdev->type) { -+ case EVDEV_RELATIVE: -+ warn_if_present(optinfo, "left", type); -+ warn_if_present(optinfo, "right", type); -+ warn_if_present(optinfo, "top", type); -+ warn_if_present(optinfo, "bottom", type); -+ warn_if_present(optinfo, "tap_move", type); -+ warn_if_present(optinfo, "tap_time", type); -+ warn_if_present(optinfo, "touch_high", type); -+ warn_if_present(optinfo, "touch_low", type); -+ break; -+ -+ case EVDEV_ABSOLUTE: -+ warn_if_present(optinfo, "tap_move", type); -+ warn_if_present(optinfo, "tap_time", type); -+ warn_if_present(optinfo, "touch_high", type); -+ warn_if_present(optinfo, "touch_low", type); -+ break; -+ -+ case EVDEV_TOUCHPAD: -+ break; -+ -+ case EVDEV_SYNAPTICS: -+ warn_if_present(optinfo, "y_inverted", type); -+ break; -+ -+ default: -+ return -1; -+ } -+ return 0; -+} -+ -+int I_evdev(struct micedev *dev, struct miceopt *opts, Gpm_Type *type) -+{ -+ struct input_id id; -+ struct evdev_capabilities caps; -+ struct event_device *evdev; -+ -+ if (!dev->private) { /* called first time, not re-init */ -+ if (!(dev->private = evdev = malloc(sizeof(*evdev)))) -+ gpm_report(GPM_PR_OOPS, "Can't allocate memory for event device"); -+ -+ memset(evdev, 0, sizeof(*evdev)); -+ -+ if (evdev_get_id(dev->fd, &id)) -+ goto init_fail; -+ -+ if (evdev_get_capabilities(dev->fd, &caps)) -+ goto init_fail; -+ -+ evdev->type = evdev_guess_type(&id, &caps); -+ -+ /* load default values - suitable for my synaptics ;P */ -+ evdev->left_edge = 1900; -+ evdev->right_edge = 5300; -+ evdev->top_edge = 2000; -+ evdev->bottom_edge = 3900; -+ evdev->tap_time = 180; -+ evdev->tap_move = 220; -+ evdev->touch_high = 30; -+ evdev->touch_low = 25; -+ -+ if (evdev->type == EVDEV_ABSOLUTE && evdev_get_limits(dev->fd, evdev, &caps) < 0) -+ goto init_fail; -+ -+ if (evdev_apply_options(evdev, opts->text) < 0) -+ goto init_fail; -+ -+ if (!test_bit(EV_SYNC, caps.evbits)) { -+ evdev->dont_sync = 1; -+ if (evdev->type == EVDEV_TOUCHPAD || evdev->type == EVDEV_SYNAPTICS) { -+ gpm_report(GPM_PR_ERR, -+ "evdev: The running kernel lacks EV_SYNC support which is required for touchpad/synaptics mode"); -+ goto init_fail; -+ } -+ } -+ -+ switch (evdev->type) { -+ case EVDEV_RELATIVE: -+ gpm_report(GPM_PR_INFO, "evdev: selected Relative mode"); -+ if (!test_bit(EV_REL, caps.evbits)) -+ gpm_report(GPM_PR_WARN, "evdev: selected relative mode but device does not report any relative events"); -+ break; -+ -+ case EVDEV_ABSOLUTE: -+ gpm_report(GPM_PR_INFO, "evdev: selected Absolute mode"); -+ if (evdev->right_edge <= evdev->left_edge) { -+ gpm_report(GPM_PR_ERR, "evdev: right edge value should be gerater than left"); -+ goto init_fail; -+ } -+ if (evdev->bottom_edge <= evdev->top_edge) { -+ gpm_report(GPM_PR_ERR, "evdev: bottom edge value should be gerater than top"); -+ goto init_fail; -+ } -+ if (!test_bit(EV_ABS, caps.evbits)) -+ gpm_report(GPM_PR_WARN, "evdev: selected absolute mode but device does not report any absolute events"); -+ opts->absolute = 1; -+ break; -+ -+ case EVDEV_TOUCHPAD: -+ gpm_report(GPM_PR_INFO, "evdev: selected Touchpad mode"); -+ if (!test_bit(EV_ABS, caps.evbits)) -+ gpm_report(GPM_PR_WARN, "evdev: selected touchpad mode but device does not report any absolute events"); -+ if (test_bit(ABS_PRESSURE, caps.absbits)) -+ evdev->detect_touch = smart_tp_detect_touch; -+ else if (test_bit(BTN_TOUCH, caps.keybits)) -+ evdev->detect_touch = dumb_tp_detect_touch; -+ else -+ gpm_report(GPM_PR_WARN, "evdev: selected touchpad mode but device does not report pressure not touch events"); -+ evdev->update_finger_count = tp_update_finger_count; -+ break; -+ -+ case EVDEV_SYNAPTICS: -+ gpm_report(GPM_PR_INFO, "evdev: selected Synaptics mode"); -+ if (!is_synaptics(&id)) -+ gpm_report(GPM_PR_WARN, "evdev: idevice isn't identified as Synaptics"); -+ if (!test_bit(EV_ABS, caps.evbits)) -+ gpm_report(GPM_PR_WARN, "evdev: selected synaptics mode but device does not report any absolute events"); -+ if (!test_bit(ABS_PRESSURE, caps.absbits)) -+ gpm_report(GPM_PR_WARN, "evdev: selected synaptics mode but device does not report pressure"); -+ if (test_bit(EV_MSC, caps.evbits) && test_bit(MSC_GESTURE, caps.mscbits)) { -+ /* this is compatibility mode with pre 2.6-test6 kernels */ -+ evdev->update_finger_count = syn_update_finger_count; -+ evdev->y_inverted = 1; -+ } else { -+ evdev->update_finger_count = tp_update_finger_count; -+ } -+ evdev->detect_touch = syn_detect_touch; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ return 0; -+ -+init_fail: -+ free(dev->private); -+ return -1; -+} -+ -diff -urN gpm-1.20.1/src/gpm.c gpm/src/gpm.c ---- gpm-1.20.1/src/gpm.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/gpm.c 2003-10-02 01:22:42.000000000 -0500 -@@ -24,1108 +24,607 @@ - #include <stdio.h> - #include <stdlib.h> - #include <string.h> /* strerror(); ?!? */ -+#include <limits.h> - #include <errno.h> - #include <unistd.h> /* select(); */ - #include <signal.h> /* SIGPIPE */ - #include <time.h> /* time() */ --#include <sys/param.h> - #include <sys/fcntl.h> /* O_RDONLY */ - #include <sys/wait.h> /* wait() */ --#include <sys/stat.h> /* mkdir() */ - #include <sys/time.h> /* timeval */ --#include <sys/types.h> /* socket() */ --#include <sys/socket.h> /* socket() */ --#include <sys/un.h> /* struct sockaddr_un */ -- --#include <linux/vt.h> /* VT_GETSTATE */ --#include <sys/kd.h> /* KDGETMODE */ --#include <termios.h> /* winsize */ - - #include "headers/gpmInt.h" - #include "headers/message.h" -- --/* who the f*** runs gpm without glibc? doesn't have dietlibc __socklent_t? */ --#if !defined(__GLIBC__) -- typedef unsigned int __socklen_t; --#endif /* __GLIBC__ */ -+#include "headers/console.h" -+#include "headers/selection.h" -+#include "headers/client.h" - - #ifndef max - #define max(a,b) ((a)>(b) ? (a) : (b)) - #endif - --extern int errno; -- --static void gpm_killed(int); -- --/* -- * all the values duplicated for dual-mouse operation are -- * now in this structure (see gpmInt.h) -- * mouse_table[0] is single mouse, mouse_table[1] and mouse_table[2] -- * are copied data from mouse_table[0] for dual mouse operation. -- */ -- --struct mouse_features mouse_table[3] = { -- { -- DEF_TYPE, DEF_DEV, DEF_SEQUENCE, -- DEF_BAUD, DEF_SAMPLE, DEF_DELTA, DEF_ACCEL, DEF_SCALE, 0 /* scaley */, -- DEF_TIME, DEF_CLUSTER, DEF_THREE, DEF_GLIDEPOINT_TAP, -- (char *)NULL /* extra */, -- (Gpm_Type *)NULL, -- -1 -- } --}; --struct mouse_features *which_mouse; -- --/* These are only the 'global' options */ -- --char *opt_lut=DEF_LUT; --int opt_test=DEF_TEST; --int opt_ptrdrag=DEF_PTRDRAG; --int opt_double=0; --int opt_aged = 0; --char *opt_special=NULL; /* special commands, like reboot or such */ --int opt_rawrep=0; --Gpm_Type *repeated_type=0; -- --static int opt_resize=0; /* not really an option */ --struct winsize win; --int maxx, maxy; --int fifofd=-1; -- --int eventFlag=0; --Gpm_Cinfo *cinfo[MAX_VC+1]; --fd_set selSet, readySet, connSet; -- --time_t last_selection_time; --time_t opt_age_limit = 0; -- --/* BRAINDEAD..ok not really, but got to leave anyway... FIXME */ --/* argc and argv for mice initialization */ --static int mouse_argc[3]; /* 0 for default (unused) and two mice */ --static char **mouse_argv[3]; /* 0 for default (unused) and two mice */ -- --/*===================================================================*/ --/* -- * first, all the stuff that used to be in gpn.c (i.e., not main-loop) -- */ --/*-------------------------------------------------------------------*/ -+#ifndef min -+#define min(a,b) ((a)<(b) ? (a) : (b)) -+#endif - --/* build_argv is used for mouse initialization routines */ --static char **build_argv(char *argv0, char *str, int *argcptr, char sep) --{ -- int argc = 1; -- char **argv; -- char *s; -- -- /* argv0 is never NULL, but the extra string may well be */ -- if (str) -- for (s=str; sep && (s = strchr(s, sep)); argc++) s++; -- -- argv = calloc(argc+2, sizeof(char **)); -- if (!argv) gpm_report(GPM_PR_OOPS,GPM_MESS_ALLOC_FAILED); -- argv[0] = argv0; -- -- if (!str) { -- *argcptr = argc; /* 1 */ -- return argv; -- } -- /* else, add arguments */ -- s = argv[1] = strdup(str); -- argc = 2; /* first to fill */ -- -- /* ok, now split: the first one is in place, and s is the whole string */ -- for ( ; sep && (s = strchr(s, sep)) ; argc++) { -- *s = '\0'; -- s++; -- argv[argc] = s; -- } -- *argcptr = argc; -- return argv; --} -+#define NULL_SET ((fd_set *)NULL) -+#define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL)) -+#define DIF_TIME(t1,t2) ((t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_usec - t1.tv_usec)/1000) - --/*-------------------------------------------------------------------*/ --/* The old console option is removed. We are taking stderr now -- * In the next update there should also be support for syslog -- ********************************************************************/ - --static inline int open_console(const int mode) --{ -- int fd; -+enum mouse_rslt { MOUSE_NO_DATA, MOUSE_DATA_OK, MOUSE_MORE_DATA }; - -- if ((fd=open(option.consolename, mode)) < 0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN_CON); -- return fd; --} -+extern int errno; - --/*-------------------------------------------------------------------*/ --static inline int wait_text(int *fdptr) --{ -- int fd; -- int kd_mode; -+char *opt_special=NULL; /* special commands, like reboot or such */ -+struct repeater repeater; - -- close(*fdptr); -- do -- { -- sleep(2); -- fd = open_console(O_RDONLY); -- if (ioctl(fd, KDGETMODE, &kd_mode)<0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_KDGETMODE); -- close(fd); -- } -- while (kd_mode != KD_TEXT) ; -- -- /* reopen, reinit (the function is only used if we have one mouse device) */ -- if ((*fdptr=open(opt_dev,O_RDWR))<0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN,opt_dev); -- if (m_type->init) -- m_type=(m_type->init)(*fdptr, m_type->flags, m_type, mouse_argc[1], -- mouse_argv[1]); -- return (1); --} -+static int console_resized; /* not really an option */ - - /*-------------------------------------------------------------------*/ --static inline void selection_copy(int x1, int y1, int x2, int y2, int mode) -+static void gpm_killed(int signo) - { --/* -- * The approach in "selection" causes a bus error when run under SunOS 4.1 -- * due to alignment problems... -- */ -- unsigned char buf[6*sizeof(short)]; -- unsigned short *arg = (unsigned short *)buf + 1; -- int fd; -- -- buf[sizeof(short)-1] = 2; /* set selection */ -- -- arg[0]=(unsigned short)x1; -- arg[1]=(unsigned short)y1; -- arg[2]=(unsigned short)x2; -- arg[3]=(unsigned short)y2; -- arg[4]=(unsigned short)mode; -- -- if ((fd=open_console(O_WRONLY))<0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN_CON); -- /* FIXME: should be replaced with string constant (headers/message.h) */ -- gpm_report(GPM_PR_DEBUG,"ctl %i, mode %i",(int)*buf, arg[4]); -- if (ioctl(fd, TIOCLINUX, buf+sizeof(short)-1) < 0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_TIOCLINUX); -- close(fd); -- -- if (mode < 3) { -- opt_aged = 0; -- last_selection_time = time(0); -+ if (signo == SIGWINCH) { -+ gpm_report(GPM_PR_WARN, GPM_MESS_RESIZING, option.progname, getpid()); -+ console_resized = 1; -+ } else { -+ if (signo == SIGUSR1) -+ gpm_report(GPM_PR_WARN, GPM_MESS_KILLED_BY, option.progname, getpid(), option.progname); -+ exit(0); - } - } - -- --/*-------------------------------------------------------------------*/ --/* comment missing; FIXME */ --/*-------------------------------------------------------------------*/ --static inline void selection_paste(void) --{ -- char c=3; -- int fd; -- -- if (!opt_aged && (0 != opt_age_limit) && -- (last_selection_time + opt_age_limit < time(0))) { -- opt_aged = 1; -- } -- -- if (opt_aged) { -- gpm_report(GPM_PR_DEBUG,GPM_MESS_SKIP_PASTE); -- return; -- } -- -- fd=open_console(O_WRONLY); -- if(ioctl(fd, TIOCLINUX, &c) < 0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_TIOCLINUX); -- close(fd); --} -- --/*-------------------------------------------------------------------*/ --static inline int do_selection(Gpm_Event *event) /* returns 0, always */ --{ -- static int x1=1, y1=1, x2, y2; --#define UNPOINTER() 0 -- -- x2=event->x; y2=event->y; -- switch(GPM_BARE_EVENTS(event->type)) { -- case GPM_MOVE: -- if (x2<1) x2++; else if (x2>maxx) x2--; -- if (y2<1) y2++; else if (y2>maxy) y2--; -- selection_copy(x2,y2,x2,y2,3); /* just highlight pointer */ -- return 0; -- -- case GPM_DRAG: -- if (event->buttons==GPM_B_LEFT) { -- if (event->margin) /* fix margins */ -- switch(event->margin) { -- case GPM_TOP: x2=1; y2++; break; -- case GPM_BOT: x2=maxx; y2--; break; -- case GPM_RGT: x2--; break; -- case GPM_LFT: y2<=y1 ? x2++ : (x2=maxx, y2--); break; -- } -- selection_copy(x1,y1,x2,y2,event->clicks); -- if (event->clicks>=opt_ptrdrag && !event->margin) /* pointer */ -- selection_copy(x2,y2,x2,y2,3); -- } /* if */ -- return 0; -- -- case GPM_DOWN: -- switch (event->buttons) { -- case GPM_B_LEFT: -- x1=x2; y1=y2; -- selection_copy(x1,y1,x2,y2,event->clicks); /* start selection */ -- return 0; -- -- case GPM_B_MIDDLE: -- selection_paste(); -- return 0; -- -- case GPM_B_RIGHT: -- if (opt_three==1) -- selection_copy(x1,y1,x2,y2,event->clicks); -- else -- selection_paste(); -- return 0; -- } -- } /* switch above */ -- return 0; --} -- --/*-------------------------------------------------------------------*/ --/* returns 0 if the event has not been processed, and 1 if it has */ --static inline int do_client(Gpm_Cinfo *cinfo, Gpm_Event *event) --{ -- Gpm_Connect info=cinfo->data; -- int fd=cinfo->fd; -- /* value to return if event is not used */ -- int res = !(info.defaultMask & event->type); -- -- /* instead of returning 0, scan the stack of clients */ -- if ((info.minMod & event->modifiers) < info.minMod) -- goto scan; -- if ((info.maxMod & event->modifiers) < event->modifiers) -- goto scan; -- -- /* if not managed, use default mask */ -- if (!(info.eventMask & GPM_BARE_EVENTS(event->type))) { -- if (res) return res; -- else goto scan; -- } -- -- /* WARNING */ /* This can generate a SIGPIPE... I'd better catch it */ -- MAGIC_P((write(fd,&magic, sizeof(int)))); -- write(fd,event, sizeof(Gpm_Event)); -- -- return info.defaultMask & GPM_HARD ? res : 1; /* HARD forces pass-on */ -- -- scan: -- if (cinfo->next != 0) -- return do_client (cinfo->next, event); /* try the next */ -- return 0; /* no next, not used */ --} -- - /*------------------------------------------------------------------- - * fetch the actual device data from the mouse device, dependent on - * what Gpm_Type is being passed. - *-------------------------------------------------------------------*/ --static inline char *getMouseData(int fd, Gpm_Type *type, int kd_mode) -+static char *getMouseData(int fd, Gpm_Type *type, int text_mode) - { - static unsigned char data[32]; /* quite a big margin :) */ -- char *edata=data+type->packetlen; -- int howmany=type->howmany; -- int i,j; -+ unsigned char *pdata; -+ int len, togo; - --/*....................................... read and identify one byte */ -- -- if (read(fd, data, howmany)!=howmany) { -- if (opt_test) exit(0); -+ /*....................................... read and identify one byte */ -+ if (read(fd, data, type->howmany) != type->howmany) { - gpm_report(GPM_PR_ERR,GPM_MESS_READ_FIRST, strerror(errno)); - return NULL; - } - -- if (kd_mode!=KD_TEXT && fifofd != -1 && opt_rawrep) -- write(fifofd, data, howmany); -+ if (!text_mode && repeater.fd != -1 && repeater.raw) -+ write(repeater.fd, data, type->howmany); - -- if ((data[0]&(m_type->proto)[0]) != (m_type->proto)[1]) { -- if (m_type->getextra == 1) { -- data[1]=GPM_EXTRA_MAGIC_1; data[2]=GPM_EXTRA_MAGIC_2; -- gpm_report(GPM_PR_DEBUG,GPM_EXTRA_DATA,data[0]); -+ if ((data[0] & type->proto[0]) != type->proto[1]) { -+ if (type->getextra == 1) { -+ data[1] = GPM_EXTRA_MAGIC_1; data[2] = GPM_EXTRA_MAGIC_2; -+ gpm_report(GPM_PR_DEBUG, GPM_EXTRA_DATA, data[0]); - return data; - } -- gpm_report(GPM_PR_DEBUG,GPM_MESS_PROT_ERR); -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_PROT_ERR); - return NULL; - } - --/*....................................... read the rest */ -+ /*....................................... read the rest */ - - /* - * well, this seems to work almost right with ps2 mice. However, I've never - * tried ps2 with the original selection package, which called usleep() - */ -- -- if((i=m_type->packetlen-howmany)) /* still to get */ -+ if ((togo = type->packetlen - type->howmany)) { /* still to get */ -+ pdata = &data[type->howmany]; - do { -- j = read(fd,edata-i,i); /* edata is pointer just after data */ -- if (kd_mode!=KD_TEXT && fifofd != -1 && opt_rawrep && j > 0) -- write(fifofd, edata-i, j); -- i -= j; -- } while (i && j); -- -- if (i) { -- gpm_report(GPM_PR_ERR,GPM_MESS_READ_REST, strerror(errno)); -+ if ((len = read(fd, pdata, togo)) == 0) -+ break; -+ if (!text_mode && repeater.fd != -1 && repeater.raw && len > 0) -+ write(repeater.fd, pdata, len); -+ pdata += len; -+ togo -= len; -+ } while (togo); -+ } -+ -+ if (togo) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_READ_REST, strerror(errno)); - return NULL; - } - -- if ((data[1]&(m_type->proto)[2]) != (m_type->proto)[3]) { -- gpm_report(GPM_PR_INFO,GPM_MESS_SKIP_DATA); -+ if ((data[1] & type->proto[2]) != type->proto[3]) { -+ gpm_report(GPM_PR_INFO, GPM_MESS_SKIP_DATA); - return NULL; - } -- gpm_report(GPM_PR_DEBUG,GPM_MESS_DATA_4,data[0],data[1],data[2],data[3]); -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_DATA_4, data[0], data[1], data[2], data[3]); - return data; - } - -- --static int statusX,statusY,statusB; /* to return info */ --static int statusC=0; /* clicks */ --void get_console_size(Gpm_Event *ePtr); -- --/*------------------------------------------------------------------- -- * call getMouseData to get hardware device data, call mouse device's fun() -- * to retrieve the hardware independent event data, then optionally repeat -- * the data via repeat_fun() to the repeater device -- *-------------------------------------------------------------------*/ --static inline int processMouse(int fd, Gpm_Event *event, Gpm_Type *type, -- int kd_mode) -+/*-------------------------------------------------------------------*/ -+void handle_console_resize(Gpm_Event *event) - { -- char *data; -- static int fine_dx, fine_dy; -- static int i, j, m; -- static Gpm_Event nEvent; -- static struct vt_stat stat; -- static struct timeval tv1={0,0}, tv2; /* tv1==0: first click is single */ -- static struct timeval timeout={0,0}; -- fd_set fdSet; -- static int newB=0, oldB=0, oldT=0; /* old buttons and Type to chain events */ -- /* static int buttonlock, buttonlockflag; */ -- --#define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL)) --#define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \ -- (t2.tv_usec-t1.tv_usec)/1000) -- -- -- oldT=event->type; -- -- if (eventFlag) { -- eventFlag=0; -- -- if (m_type->absolute) { /* a pen or other absolute device */ -- event->x=nEvent.x; -- event->y=nEvent.y; -- } -- event->dx=nEvent.dx; -- event->dy=nEvent.dy; -- event->buttons=nEvent.buttons; -- } else { -- event->dx=event->dy=0; -- event->wdx=event->wdy=0; -- nEvent.modifiers = 0; /* some mice set them */ -- FD_ZERO(&fdSet); FD_SET(fd,&fdSet); i=0; -- -- do { /* cluster loop */ -- if(((data=getMouseData(fd,m_type,kd_mode))==NULL) -- || ((*(m_type->fun))(&nEvent,data)==-1) ) { -- if (!i) return 0; -- else break; -- } -- -- event->modifiers = nEvent.modifiers; /* propagate modifiers */ -- -- /* propagate buttons */ -- nEvent.buttons = (opt_sequence[nEvent.buttons&7]&7) | -- (nEvent.buttons & ~7); /* change the order */ -- oldB=newB; newB=nEvent.buttons; -- if (!i) event->buttons=nEvent.buttons; -- -- if (oldB!=newB) { -- eventFlag = (i!=0)*(which_mouse-mouse_table); /* 1 or 2 */ -- break; -- } -- -- /* propagate movement */ -- if (!(m_type->absolute)) { /* mouse */ -- if (abs(nEvent.dx)+abs(nEvent.dy) > opt_delta) -- nEvent.dx*=opt_accel, nEvent.dy*=opt_accel; -- -- /* increment the reported dx,dy */ -- event->dx+=nEvent.dx; -- event->dy+=nEvent.dy; -- } else { /* a pen */ -- /* get dx,dy to check if there has been movement */ -- event->dx = (nEvent.x) - (event->x); -- event->dy = (nEvent.y) - (event->y); -- } -- -- /* propagate wheel */ -- event->wdx += nEvent.wdx; -- event->wdy += nEvent.wdy; -- -- select(fd+1,&fdSet,(fd_set *)NULL,(fd_set *)NULL,&timeout/* zero */); -- -- } while (i++ <opt_cluster && nEvent.buttons==oldB && FD_ISSET(fd,&fdSet)); -- -- } /* if(eventFlag) */ -- --/*....................................... update the button number */ -+ int old_x, old_y; -+ struct micetab *mouse; - -- if ((event->buttons&GPM_B_MIDDLE) && !opt_three) opt_three++; -+ old_x = console.max_x; old_y = console.max_y; -+ refresh_console_size(); -+ if (!old_x) { /* first invocation, place the pointer in the middle */ -+ event->x = console.max_x / 2; -+ event->y = console.max_y / 2; -+ } else { /* keep the pointer in the same position where it was */ -+ event->x = event->x * console.max_x / old_x; -+ event->y = event->y * console.max_y / old_y; -+ } - --/*....................................... we're a repeater, aren't we? */ -+ for (mouse = micelist; mouse; mouse = mouse->next) { -+ /* -+ * the following operation is based on the observation that 80x50 -+ * has square cells. (An author-centric observation ;-) -+ */ -+ mouse->options.scaley = mouse->options.scalex * 50 * console.max_x / 80 / console.max_y; -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_X_Y_VAL, -+ mouse->options.scalex, mouse->options.scaley); -+ } -+} - -- if (kd_mode!=KD_TEXT) { -- if (fifofd != -1 && ! opt_rawrep) { -- if (m_type->absolute) { /* hof Wed Feb 3 21:43:28 MET 1999 */ -- /* prepare the values from a absolute device for repeater mode */ -- static struct timeval rept1,rept2; -- gettimeofday(&rept2, (struct timezone *)NULL); -- if (((rept2.tv_sec -rept1.tv_sec) -- *1000+(rept2.tv_usec-rept1.tv_usec)/1000)>250) { -- event->dx=0; -- event->dy=0; -- } -- rept1=rept2; -- -- event->dy=event->dy*((win.ws_col/win.ws_row)+1); -- event->x=nEvent.x; -- event->y=nEvent.y; -- } -- repeated_type->repeat_fun(event, fifofd); /* itz Jan 11 1999 */ -+static void handle_repeater(int absolute_dev, Gpm_Event *new_event, Gpm_Event *event) -+{ -+ static struct timeval last; -+ struct timeval now; -+ -+ if (absolute_dev) { -+ /* prepare the values from a absolute device for repeater mode */ -+ GET_TIME(now); -+ if (((now.tv_sec - last.tv_sec) * 1000 + -+ (now.tv_usec - last.tv_usec) / 1000) > 250) { -+ event->dx = 0; -+ event->dy = 0; - } -- return 0; /* no events nor information for clients */ -- } /* first if of these three */ -- --/*....................................... no, we arent a repeater, go on */ -+ last = now; - -- /* use fine delta values now, if delta is the information */ -- if (!(m_type)->absolute) { -- fine_dx+=event->dx; fine_dy+=event->dy; -- event->dx=fine_dx/opt_scale; event->dy=fine_dy/opt_scaley; -- fine_dx %= opt_scale; fine_dy %= opt_scaley; -+ event->dy = event->dy * ((console.max_x / console.max_y) + 1); -+ event->x = new_event->x; -+ event->y = new_event->y; - } -+ repeater.type->repeat_fun(event, repeater.fd); -+} - -- /* up and down, up and down, ... who does a do..while(0) loop ??? -- and then makes a break into it... argh ! */ -- -- if (!event->dx && !event->dy && (event->buttons==oldB)) -- do { /* so to break */ -- static long awaketime; -- /* -- * Ret information also if never happens, but enough time has elapsed. -- * Note: return 1 will segfault due to missing event->vc; FIXME! -- */ -- if (time(NULL)<=awaketime) return 0; -- awaketime=time(NULL)+1; -- break; -- } while (0); -- --/*....................................... fill missing fields */ -- -- event->x+=event->dx, event->y+=event->dy; -- statusB=event->buttons; -- -- i=open_console(O_RDONLY); -- /* modifiers */ -- j = event->modifiers; /* save them */ -- event->modifiers=6; /* code for the ioctl */ -- if (ioctl(i,TIOCLINUX,&(event->modifiers))<0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_GET_SHIFT_STATE); -- event->modifiers |= j; /* add mouse-specific bits */ -- -- /* status */ -- j = stat.v_active; -- if (ioctl(i,VT_GETSTATE,&stat)<0) gpm_report(GPM_PR_OOPS,GPM_MESS_GET_CONSOLE_STAT); -- -- /* -- * if we changed console, request the current console size, -- * as different consoles can be of different size -- */ -- if (stat.v_active != j) -- get_console_size(event); -- close(i); -- -- event->vc = stat.v_active; -- -- if (oldB==event->buttons) -- event->type = (event->buttons ? GPM_DRAG : GPM_MOVE); -- else -- event->type = (event->buttons > oldB ? GPM_DOWN : GPM_UP); -- -+static void calculate_clicks(Gpm_Event *event, int click_tmo) -+{ -+ static struct timeval release; -+ struct timeval now; -+ - switch(event->type) { /* now provide the cooked bits */ - case GPM_DOWN: -- GET_TIME(tv2); -- if (tv1.tv_sec && (DIF_TIME(tv1,tv2)<opt_time)) /* check first click */ -- statusC++, statusC%=3; /* 0, 1 or 2 */ -+ GET_TIME(now); -+ if (release.tv_sec && (DIF_TIME(release, now) < click_tmo)) /* check first click */ -+ event->clicks++, event->clicks %= 3; /* 0, 1 or 2 */ - else -- statusC=0; -- event->type|=(GPM_SINGLE<<statusC); -+ event->clicks = 0; -+ event->type |= GPM_SINGLE << event->clicks; - break; - - case GPM_UP: -- GET_TIME(tv1); -- event->buttons^=oldB; /* for button-up, tell which one */ -- event->type|= (oldT&GPM_MFLAG); -- event->type|=(GPM_SINGLE<<statusC); -+ GET_TIME(release); -+ event->type |= GPM_SINGLE << event->clicks; - break; - - case GPM_DRAG: -- event->type |= GPM_MFLAG; -- event->type|=(GPM_SINGLE<<statusC); -+ event->type |= GPM_SINGLE << event->clicks; - break; - - case GPM_MOVE: -- statusC=0; -+ event->clicks = 0; -+ - default: - break; - } -- event->clicks=statusC; -+} -+ -+static void snap_to_screen_limits(Gpm_Event *event) -+{ -+ int extent; - --/* UGLY - FIXME! */ --/* The current policy is to force the following behaviour: -- * - At buttons up, must fit inside the screen, though flags are set. -- * - At button down, allow going outside by one single step -- */ -+ /* The current policy is to force the following behaviour: -+ * - At buttons up, must fit inside the screen, though flags are set. -+ * - At button down, allow going outside by one single step -+ * DTOR: Midnight Commander seems to want the opposite... -+ */ - -+ extent = (event->type & (GPM_DRAG|GPM_UP)) ? 1 : 0; - - /* selection used 1-based coordinates, so do I */ -- - /* - * 1.05: only one margin is current. Y takes priority over X. -- * The i variable is how much margin is allowed. "m" is which one is there. - */ - -- m = 0; -- i = ((event->type&(GPM_DRAG|GPM_UP))!=0); /* i is boolean */ -- -- if (event->y>win.ws_row) {event->y=win.ws_row+1-!i; i=0; m = GPM_BOT;} -- else if (event->y<=0) {event->y=1-i; i=0; m = GPM_TOP;} -- -- if (event->x>win.ws_col) {event->x=win.ws_col+1-!i; if (!m) m = GPM_RGT;} -- else if (event->x<=0) {event->x=1-i; if (!m) m = GPM_LFT;} -+ event->margin = 0; - -- event->margin=m; -+ if (event->y > console.max_y) { -+ event->y = console.max_y + extent; -+ extent = 0; -+ event->margin = GPM_BOT; -+ } else if (event->y <= 0) { -+ event->y = 1 - extent; -+ extent = 0; -+ event->margin = GPM_TOP; -+ } - -- gpm_report(GPM_PR_DEBUG,"M: %3i %3i (%3i %3i) - butt=%i vc=%i cl=%i", -- event->dx,event->dy, -- event->x,event->y, -- event->buttons, event->vc, -- event->clicks); -+ if (event->x > console.max_x) { -+ event->x = console.max_x + extent; -+ if (!event->margin) event->margin = GPM_RGT; -+ } else if (event->x <= 0) { -+ event->x = 1 - extent; -+ if (!event->margin) event->margin = GPM_LFT; -+ } -+} - -- /* update the global state */ -- statusX=event->x; statusY=event->y; -+static int more_data_waiting(int fd) -+{ -+ static struct timeval timeout = {0, 0}; -+ fd_set fdSet; - -- if (opt_special && event->type & GPM_DOWN) -- return processSpecial(event); -+ FD_ZERO(&fdSet); -+ FD_SET(fd, &fdSet); -+ select(fd + 1, &fdSet, NULL_SET, NULL_SET, &timeout/* zero */); - -- return 1; -+ return FD_ISSET(fd, &fdSet); - } - --/*-------------------------------------------------------------------* -- * This was inline, and incurred in a compiler bug (2.7.0) -- *-------------------------------------------------------------------*/ --static int get_data(Gpm_Connect *where, int whence) -+static int multiplex_buttons(struct micetab *mouse, int new_buttons) - { -- static int i; -+ static int left_btn_clicks, mid_btn_clicks, right_btn_clicks; -+ int mask; -+ int muxed_buttons = 0; -+ -+ new_buttons = -+ (mouse->options.sequence[new_buttons & 7] & 7) | (new_buttons & ~7); -+ mask = new_buttons ^ mouse->buttons; -+ mouse->buttons = new_buttons; - --#ifdef GPM_USE_MAGIC -- while ((i=read(whence,&check,sizeof(int)))==4 && check!=GPM_MAGIC) -- gpm_report(GPM_PR_INFO,GPM_MESS_NO_MAGIC); -- -- if (!i) return 0; -- if (check!=GPM_MAGIC) { -- gpm_report(GPM_PR_INFO,GPM_MESS_NOTHING_MORE); -- return -1; -+ if (mask & GPM_B_LEFT) { -+ if (new_buttons & GPM_B_LEFT) left_btn_clicks++; -+ else left_btn_clicks--; - } --#endif -+ if (left_btn_clicks) muxed_buttons |= GPM_B_LEFT; - -- if ((i=read(whence, where, sizeof(Gpm_Connect)))!=sizeof(Gpm_Connect)) { -- return i ? -1 : 0; -+ if (mask & GPM_B_MIDDLE) { -+ if (new_buttons & GPM_B_MIDDLE) mid_btn_clicks++; -+ else mid_btn_clicks--; - } -+ if (mid_btn_clicks) muxed_buttons |= GPM_B_MIDDLE; - -- return 1; --} -+ if (mask & GPM_B_RIGHT) { -+ if (new_buttons & GPM_B_RIGHT) right_btn_clicks++; -+ else right_btn_clicks--; -+ } -+ if (right_btn_clicks) muxed_buttons |= GPM_B_RIGHT; - --static void disable_paste(int vc) --{ -- opt_aged++; -- gpm_report(GPM_PR_INFO,GPM_MESS_DISABLE_PASTE,vc); -+ return muxed_buttons; - } - --/*-------------------------------------------------------------------*/ -- /* returns -1 if closing connection */ --static inline int processRequest(Gpm_Cinfo *ci, int vc) -+/*------------------------------------------------------------------- -+ * call getMouseData to get hardware device data, call mouse device's fun() -+ * to retrieve the hardware independent event data, then optionally repeat -+ * the data via repeat_fun() to the repeater device -+ *-------------------------------------------------------------------*/ -+static enum mouse_rslt processMouse(struct micetab *mouse, int timeout, int attempt, -+ Gpm_Event *event, int text_mode) - { -+ static int last_active; -+ static int fine_dx, fine_dy; -+ static int oldB; -+ -+ static Gpm_Event nEvent; -+ struct Gpm_Type *type = mouse->type; -+ struct miceopt *opt = &mouse->options; -+ enum mouse_rslt rslt = MOUSE_DATA_OK; -+ unsigned char shift_state; -+ char *data = NULL; - int i; -- Gpm_Cinfo *cinfoPtr, *next; -- Gpm_Connect conn; -- static Gpm_Event event; -- static struct vt_stat stat; -- -- gpm_report(GPM_PR_INFO,GPM_MESS_CON_REQUEST, ci->fd, vc); -- if (vc>MAX_VC) return -1; -- -- /* itz 10-22-96 this shouldn't happen now */ -- if (vc==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_UNKNOWN_FD); -- -- i=get_data(&conn,ci->fd); -- -- if (!i) { /* no data */ -- gpm_report(GPM_PR_INFO,GPM_MESS_CLOSE); -- close(ci->fd); -- FD_CLR(ci->fd,&connSet); -- FD_CLR(ci->fd,&readySet); -- if (cinfo[vc]->fd == ci->fd) { /* it was on top of the stack */ -- cinfoPtr = cinfo[vc]; -- cinfo[vc]=cinfo[vc]->next; /* pop the stack */ -- free(cinfoPtr); -- return -1; -- } -- /* somewhere inside the stack, have to walk it */ -- cinfoPtr = cinfo[vc]; -- while (cinfoPtr && cinfoPtr->next) { -- if (cinfoPtr->next->fd == ci->fd) { -- next = cinfoPtr->next; -- cinfoPtr->next = next->next; -- free (next); -+ -+ if (attempt > 1) { /* continue interrupted cluster loop */ -+ if (opt->absolute) { -+ event->x = nEvent.x; -+ event->y = nEvent.y; -+ } -+ event->dx = nEvent.dx; -+ event->dy = nEvent.dy; -+ event->buttons = nEvent.buttons; -+ } else { -+ event->dx = event->dy = 0; -+ event->wdx = event->wdy = 0; -+ nEvent.modifiers = 0; /* some mice set them */ -+ i = 0; -+ -+ do { /* cluster loop */ -+ if (!timeout && (data = getMouseData(mouse->dev.fd, type, text_mode)) != NULL) { -+ GET_TIME(mouse->timestamp); -+ } -+ -+ /* in case of timeout data passed to typr->fun() is NULL */ -+ if ((!timeout && data == NULL) || -+ type->fun(&mouse->dev, &mouse->options, data, &nEvent) == -1) { -+ if (!i) return MOUSE_NO_DATA; -+ else break; -+ } -+ -+ event->modifiers = nEvent.modifiers; /* propagate modifiers */ -+ -+ /* propagate buttons */ -+ nEvent.buttons = multiplex_buttons(mouse, nEvent.buttons); -+ -+ if (!i) event->buttons = nEvent.buttons; -+ -+ if (oldB != nEvent.buttons) { -+ rslt = MOUSE_MORE_DATA; - break; - } -- cinfoPtr = cinfoPtr->next; -- } -- return -1; -- } /* not data */ -- -- if (i == -1) return -1; /* too few bytes */ - -- if (conn.pid!=0) { -- ci->data = conn; -- return 0; -- } -- -- /* Aha, request for information (so-called snapshot) */ -- switch(conn.vc) { -- case GPM_REQ_SNAPSHOT: -- i=open_console(O_RDONLY); -- ioctl(i,VT_GETSTATE,&stat); -- event.modifiers=6; /* code for the ioctl */ -- if (ioctl(i,TIOCLINUX,&(event.modifiers))<0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_GET_SHIFT_STATE); -- close(i); -- event.vc = stat.v_active; -- event.x=statusX; event.y=statusY; -- event.dx=maxx; event.dy=maxy; -- event.buttons= statusB; -- event.clicks=statusC; -- /* fall through */ -- /* missing break or do you want this ??? */ -- -- case GPM_REQ_BUTTONS: -- event.type= (opt_three==1 ? 3 : 2); /* buttons */ -- write(ci->fd,&event,sizeof(Gpm_Event)); -- break; -+ /* propagate movement */ -+ if (!opt->absolute) { /* mouse */ -+ if (abs(nEvent.dx) + abs(nEvent.dy) > opt->delta) -+ nEvent.dx *= opt->accel, nEvent.dy *= opt->accel; - -- case GPM_REQ_NOPASTE: -- disable_paste(vc); -- break; -+ /* increment the reported dx,dy */ -+ event->dx += nEvent.dx; -+ event->dy += nEvent.dy; -+ } else { /* a pen */ -+ /* get dx,dy to check if there has been movement */ -+ event->dx = nEvent.x - event->x; -+ event->dy = nEvent.y - event->y; -+ } -+ -+ /* propagate wheel */ -+ event->wdx += nEvent.wdx; -+ event->wdy += nEvent.wdy; -+ -+ } while (i++ < opt->cluster && more_data_waiting(mouse->dev.fd)); -+ } /* if(eventFlag) */ -+ -+ /*....................................... update the button number */ -+ -+ if ((event->buttons & GPM_B_MIDDLE) && !opt->three_button) opt->three_button++; -+ -+ /*....................................... we're a repeater, aren't we? */ -+ -+ if (!text_mode) { -+ if (repeater.fd != -1 && !repeater.raw) -+ handle_repeater(opt->absolute, &nEvent, event); -+ oldB = nEvent.buttons; -+ return MOUSE_NO_DATA; /* no events nor information for clients */ - } - -- return 0; --} -+/*....................................... no, we arent a repeater, go on */ - --/*-------------------------------------------------------------------*/ --static inline int processConn(int fd) /* returns newfd or -1 */ --{ -- Gpm_Cinfo *info; -- Gpm_Connect *request; -- Gpm_Cinfo *next; -- int vc, newfd; --#if !defined(__GLIBC__) -- int len; --#else /* __GLIBC__ */ -- size_t len; /* isn't that generally defined in C ??? -- nico */ --#endif /* __GLIBC__ */ -- struct sockaddr_un addr; /* reuse this each time */ -- struct stat statbuf; -- uid_t uid; -- char *tty = NULL; -- --/*....................................... Accept */ -- -- bzero((char *)&addr,sizeof(addr)); -- addr.sun_family=AF_UNIX; -- -- len=sizeof(addr); -- if ((newfd=accept(fd,(struct sockaddr *)&addr, &len))<0) { -- gpm_report(GPM_PR_ERR,GPM_MESS_ACCEPT_FAILED,strerror(errno)); -- return -1; -- } -- -- gpm_report(GPM_PR_INFO,GPM_MESS_CONECT_AT,newfd); -- -- info=malloc(sizeof(Gpm_Cinfo)); -- if (!info) gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -- request=&(info->data); -- -- if(get_data(request,newfd)==-1) { -- free(info); -- close(newfd); -- return -1; -- } -- -- if ((vc=request->vc)>MAX_VC) { -- gpm_report(GPM_PR_WARN,GPM_MESS_REQUEST_ON, vc, MAX_VC); -- free(info); -- close(newfd); -- return -1; -- } -- --#ifndef SO_PEERCRED -- if (stat (addr.sun_path, &statbuf) == -1 || !S_ISSOCK(statbuf.st_mode)) { -- gpm_report(GPM_PR_ERR,GPM_MESS_ADDRES_NSOCKET,addr.sun_path); -- free(info); /* itz 10-12-95 verify client's right */ -- close(newfd); -- return -1; /* to read requested tty */ -+ /* use fine delta values now, if delta is the information */ -+ if (!opt->absolute) { -+ fine_dx += event->dx; -+ fine_dy += event->dy; -+ event->dx = fine_dx / opt->scalex; -+ event->dy = fine_dy / opt->scaley; -+ fine_dx %= opt->scalex; -+ fine_dy %= opt->scaley; - } -- -- unlink(addr.sun_path); /* delete socket */ - -- staletime = time(0) - 30; -- if (statbuf.st_atime < staletime -- || statbuf.st_ctime < staletime -- || statbuf.st_mtime < staletime) { -- gpm_report(GPM_PR_ERR,GPM_MESS_SOCKET_OLD); -- free (info); -- close(newfd); -- return -1; /* socket is ancient */ -+ /* up and down, up and down, ... who does a do..while(0) loop ??? -+ and then makes a break into it... argh ! */ -+ -+ if (!event->dx && !event->dy && event->buttons == oldB) { -+ static time_t awaketime; -+ /* -+ * Ret information also if never happens, but enough time has elapsed. -+ * Note: return 1 will segfault due to missing event->vc; FIXME! -+ */ -+ if (time(NULL) <= awaketime) return MOUSE_NO_DATA; -+ awaketime = time(NULL) + 1; - } - -- uid = statbuf.st_uid; /* owner of socket */ --#else -- { -- struct ucred sucred; -- socklen_t credlen = sizeof(struct ucred); -- -- if(getsockopt(newfd, SOL_SOCKET, SO_PEERCRED, &sucred, &credlen) == -1) { -- gpm_report(GPM_PR_ERR,GPM_MESS_GETSOCKOPT, strerror(errno)); -- free(info); -- close(newfd); -- return -1; -- } -- uid = sucred.uid; -- gpm_report(GPM_PR_DEBUG,GPM_MESS_PEER_SCK_UID, uid); -- } --#endif -- if (uid != 0) { -- if(( tty = -- malloc(strlen(option.consolename)+Gpm_cnt_digits(vc) + sizeof(char))) == NULL) -- gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -- -- strncpy(tty,option.consolename,strlen(option.consolename)-1); -- sprintf(&tty[strlen(option.consolename)-1],"%d",vc); -+ /*....................................... fill missing fields */ -+ event->x += event->dx; event->y += event->dy; - -- if(stat(tty, &statbuf) == -1) { -- gpm_report(GPM_PR_ERR,GPM_MESS_STAT_FAILS,tty); -- free(info); -- free(tty); -- close(newfd); -- return -1; -- } -- if (uid != statbuf.st_uid) { -- gpm_report(GPM_PR_WARN,GPM_MESS_FAILED_CONNECT, uid, tty); /*SUSPECT!*/ -- free(info); -- free(tty); -- close(newfd); -- return -1; -+ event->vc = get_console_state(&shift_state); -+ if (event->vc != last_active) { -+ handle_console_resize(event); -+ last_active = event->vc; -+ } -+ event->modifiers |= shift_state; -+ -+ if (oldB == event->buttons) -+ event->type = (event->buttons ? (GPM_DRAG | GPM_MFLAG) : GPM_MOVE); -+ else { -+ if (event->buttons > oldB) -+ event->type = GPM_DOWN; -+ else { -+ event->type &= GPM_MFLAG; -+ event->type |= GPM_UP; -+ event->buttons ^= oldB; /* for button-up, tell which one */ - } -- free(tty); /* at least here it's not needed anymore */ - } -+ calculate_clicks(event, opt->time); -+ snap_to_screen_limits(event); -+ -+ gpm_report(GPM_PR_DEBUG,"M: %3i %3i (%3i %3i) - butt=%i vc=%i cl=%i", -+ event->dx, event->dy, event->x, event->y, -+ event->buttons, event->vc, event->clicks); - -- /* register the connection information in the right place */ -- info->next=next=cinfo[vc]; -- info->fd=newfd; -- cinfo[vc]=info; -- gpm_report(GPM_PR_DEBUG,GPM_MESS_LONG_STATUS, -- request->pid, request->vc, request->eventMask, request->defaultMask, -- request->minMod, request->maxMod); -- -- /* if the client gets motions, give it the current position */ -- if(request->eventMask & GPM_MOVE) { -- Gpm_Event event={0,0,vc,0,0,statusX,statusY,GPM_MOVE,0,0}; -- do_client(info, &event); -- } -+ oldB = nEvent.buttons; - -- return newfd; -+ if (opt_special && (event->type & GPM_DOWN) && !processSpecial(event)) -+ rslt = MOUSE_NO_DATA; -+ -+ return rslt; - } - --/*-------------------------------------------------------------------*/ --void get_console_size(Gpm_Event *ePtr) -+static int wait_for_data(fd_set *connSet, int maxfd, fd_set *selSet) - { -- int i, prevmaxx, prevmaxy; -- struct mouse_features *which_mouse; /* local */ -+ struct micetab *mouse; -+ struct timeval now, timeout = { 0, 0 }; -+ int mouse_tmo, tmo = INT_MAX; - -- /* before asking the new console size, save the previous values */ -- prevmaxx = maxx; prevmaxy = maxy; -+ GET_TIME(now); - -- i=open_console(O_RDONLY); -- ioctl(i, TIOCGWINSZ, &win); -- close(i); -- if (!win.ws_col || !win.ws_row) { -- gpm_report(GPM_PR_DEBUG,GPM_MESS_ZERO_SCREEN_DIM); -- win.ws_col=80; win.ws_row=25; -- } -- maxx=win.ws_col; maxy=win.ws_row; -- gpm_report(GPM_PR_DEBUG,GPM_MESS_SCREEN_SIZE,maxx,maxy); -- -- if (!prevmaxx) { /* first invocation, place the pointer in the middle */ -- statusX = ePtr->x = maxx/2; -- statusY = ePtr->y = maxy/2; -- } else { /* keep the pointer in the same position where it was */ -- statusX = ePtr->x = ePtr->x * maxx / prevmaxx; -- statusY = ePtr->y = ePtr->y * maxy / prevmaxy; -- } -- -- for (i=1; i <= 1+opt_double; i++) { -- which_mouse=mouse_table+i; /* used to access options */ -- /* -- * the following operation is based on the observation that 80x50 -- * has square cells. (An author-centric observation ;-) -- */ -- opt_scaley=opt_scale*50*maxx/80/maxy; -- gpm_report(GPM_PR_DEBUG,GPM_MESS_X_Y_VAL,opt_scale,opt_scaley); -+ *selSet = *connSet; -+ for (mouse = micelist; mouse; mouse = mouse->next) { -+ FD_SET(mouse->dev.fd, selSet); -+ maxfd = max(maxfd, mouse->dev.fd); -+ if (mouse->dev.timeout >= 0) { -+ mouse_tmo = mouse->dev.timeout - DIF_TIME(mouse->timestamp, now); -+ tmo = min(tmo, mouse_tmo); -+ } - } -+ -+ if (tmo == INT_MAX) -+ timeout.tv_sec = SELECT_TIME; -+ else if (tmo > 0) { -+ timeout.tv_sec = tmo / 1000; -+ timeout.tv_usec = (tmo % 1000) * 1000; -+ } -+ -+ return select(maxfd + 1, selSet, NULL_SET, NULL_SET, &timeout); - } - --/*-------------------------------------------------------------------*/ --static void gpm_killed(int signo) --{ -- if(signo==SIGWINCH) { -- gpm_report(GPM_PR_WARN,GPM_MESS_RESIZING, option.progname, getpid()); -- opt_resize++; -- return; -- } -- if (signo==SIGUSR1) -- gpm_report(GPM_PR_WARN,GPM_MESS_KILLED_BY,option.progname, getpid(),option.progname); -- exit(0); --} -+ - - /*-------------------------------------------------------------------*/ - int old_main() - { -- int ctlfd, newfd; -- struct sockaddr_un ctladdr; -- int i, len, kd_mode, fd; -- struct timeval timeout; -- int maxfd=-1; -- int pending; -+ int ctlfd; -+ int i, text_mode; -+ struct timeval now; -+ int maxfd = -1; -+ int pending, attempt; -+ int timed_out; - Gpm_Event event; -+ struct micetab *mouse; -+ struct client_info *ci; -+ fd_set selSet, connSet; -+ enum mouse_rslt rslt; - -- for (i = 1; i <= 1+opt_double; i++) { -- which_mouse=mouse_table+i; /* used to access options */ -- -- if (!opt_dev) gpm_report(GPM_PR_OOPS,GPM_MESS_NEED_MDEV); -- -- if(!strcmp(opt_dev,"-")) fd=0; /* use stdin */ -- else if( (fd=open(opt_dev,O_RDWR | O_NDELAY)) < 0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN,opt_dev); -- -- /* and then reset the flag */ -- fcntl(fd,F_SETFL,fcntl(fd,F_GETFL) & ~O_NDELAY); -- -- /* create argc and argv for this device */ -- mouse_argv[i] = build_argv(opt_type, opt_options, &mouse_argc[i], ','); -- -- /* init the device, and use the return value as new mouse type */ -- if (m_type->init) -- m_type=(m_type->init)(fd, m_type->flags, m_type, mouse_argc[i], -- mouse_argv[i]); -- if (!m_type) gpm_report(GPM_PR_OOPS,GPM_MESS_MOUSE_INIT); -- -- which_mouse->fd=fd; -- maxfd=max(fd, maxfd); -- } -- --/*....................................... catch interesting signals */ -- -+ /*....................................... catch interesting signals */ - signal(SIGTERM, gpm_killed); - signal(SIGINT, gpm_killed); - signal(SIGUSR1, gpm_killed); /* usr1 is used by a new gpm killing the old */ - signal(SIGWINCH,gpm_killed); /* winch can be sent if console is resized */ -+ signal(SIGPIPE, SIG_IGN); /* WARN */ - --/*....................................... create your nodes */ -- -- /* control node */ -- -- if((ctlfd=socket(AF_UNIX,SOCK_STREAM,0))==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_SOCKET_PROB); -- bzero((char *)&ctladdr,sizeof(ctladdr)); -- ctladdr.sun_family=AF_UNIX; -- strcpy(ctladdr.sun_path,GPM_NODE_CTL); -- unlink(GPM_NODE_CTL); -- -- len=sizeof(ctladdr.sun_family)+strlen(GPM_NODE_CTL); -- if(bind(ctlfd,(struct sockaddr *)(&ctladdr),len) == -1) -- gpm_report(GPM_PR_OOPS,GPM_MESS_BIND_PROB,ctladdr.sun_path); -- maxfd=max(maxfd,ctlfd); -- -- /* needs to be 0777, so all users can _try_ to access gpm */ -- chmod(GPM_NODE_CTL,0777); -- -- get_console_size(&event); /* get screen dimensions */ -- --/*....................................... wait for mouse and connections */ -- -- listen(ctlfd, 5); /* Queue up calls */ -- --#define NULL_SET ((fd_set *)NULL) --#define resetTimeout() (timeout.tv_sec=SELECT_TIME,timeout.tv_usec=0) -+ init_mice(); -+ handle_console_resize(&event); /* get screen dimensions */ -+ ctlfd = listen_for_clients(); - -+ /*....................................... wait for mouse and connections */ - FD_ZERO(&connSet); -- FD_SET(ctlfd,&connSet); -- -- if (opt_double) FD_SET(mouse_table[2].fd,&connSet); -- -- readySet=connSet; -- FD_SET(mouse_table[1].fd,&readySet); -- -- signal(SIGPIPE,SIG_IGN); /* WARN */ -- --/*--------------------------------------- main loop begins here */ -+ FD_SET(ctlfd, &connSet); -+ maxfd = max(maxfd, ctlfd); -+ -+ /*--------------------------------------- main loop begins here */ - -- while(1) { -- selSet=readySet; -- resetTimeout(); -- if (opt_test) timeout.tv_sec=0; -+ while (1) { - -- if (eventFlag) { /* an event left over by clustering */ -- pending=1; -- FD_ZERO(&selSet); -- FD_SET(mouse_table[eventFlag].fd,&selSet); -- } -- else -- while((pending=select(maxfd+1,&selSet,NULL_SET,NULL_SET,&timeout))==0){ -- selSet=readySet; -- resetTimeout(); -- } /* go on */ -- -- if(opt_resize) { /* did the console resize? */ -- get_console_size(&event); -- opt_resize--; -- signal(SIGWINCH,gpm_killed); /* reinstall handler */ -- -- /* and notify clients */ -- for(i=0; i<MAX_VC+1; i++) { -- Gpm_Cinfo *ci; -- for (ci = cinfo[i]; ci; ci = ci->next) kill(ci->data.pid,SIGWINCH); -- } -+ pending = wait_for_data(&connSet, maxfd, &selSet); -+ -+ if (console_resized) { /* did the console resize? */ -+ handle_console_resize(&event); -+ console_resized = 0; -+ signal(SIGWINCH, gpm_killed); /* reinstall handler */ -+ notify_clients_resize(); - } - - if (pending < 0) { -- if (errno==EBADF) gpm_report(GPM_PR_OOPS,GPM_MESS_SELECT_PROB); -- gpm_report(GPM_PR_ERR,GPM_MESS_SELECT_STRING,strerror(errno)); -- selSet=readySet; -- resetTimeout(); -+ if (errno == EBADF) gpm_report(GPM_PR_OOPS,GPM_MESS_SELECT_PROB); -+ gpm_report(GPM_PR_ERR, GPM_MESS_SELECT_STRING, strerror(errno)); - continue; - } - -- gpm_report(GPM_PR_DEBUG,GPM_MESS_SELECT_TIMES,pending); -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_SELECT_TIMES, pending); - --/*....................................... manage graphic mode */ -+ /*....................................... manage graphic mode */ - -- /* -- * Be sure to be in text mode. This used to be before select, -- * but actually it only matters if you have events. -- */ -- { -- int fd = open_console(O_RDONLY); -- if (ioctl(fd, KDGETMODE, &kd_mode) < 0) -- gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_KDGETMODE); -- close(fd); -- if(kd_mode != KD_TEXT && !option.repeater) { -- wait_text(&mouse_table[1].fd); -- maxfd=max(maxfd,mouse_table[1].fd); -- readySet=connSet; -- FD_SET(mouse_table[1].fd,&readySet); -+ /* -+ * Be sure to be in text mode. This used to be before select, -+ * but actually it only matters if you have events. -+ */ -+ text_mode = is_text_console(); -+ if (!text_mode && !repeater.type && !repeater.raw) { -+ /* if we don;t have repeater then there is only one mouse so -+ * we can safely use micelist -+ */ -+ close(micelist->dev.fd); -+ wait_text_console(); -+ /* reopen, reinit (the function is only used if we have one mouse device) */ -+ if ((micelist->dev.fd = open(micelist->device, O_RDWR)) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN, micelist->device); -+ if (micelist->type->init) -+ micelist->type->init(&micelist->dev, &micelist->options, micelist->type); - continue; /* reselect */ - } -- } - --/*....................................... got mouse, process event */ --/* -- * Well, actually, run a loop to maintain inlining of functions without -- * lenghtening the file. This is not too clean a code, but it works.... -- */ -- -- for (i=1; i <= 1+opt_double; i++) { -- which_mouse=mouse_table+i; /* used to access options */ -- if (FD_ISSET(which_mouse->fd,&selSet)) { -- FD_CLR(which_mouse->fd,&selSet); pending--; -- if (processMouse(which_mouse->fd, &event, m_type, kd_mode)) -- /* pass it to the client, if any -- * or to the default handler, if any -- * or to the selection handler -- */ /* FIXME -- check event.vc */ -- /* can't we please rewrite the following a bit nicer?*/ -- (cinfo[event.vc] && do_client(cinfo[event.vc], &event)) -- || (cinfo[0] && do_client(cinfo[0], &event)) -- || do_selection(&event); -+ /*....................................... got mouse, process event */ -+ /* -+ * Well, actually, run a loop to maintain inlining of functions without -+ * lenghtening the file. This is not too clean a code, but it works.... -+ */ -+ GET_TIME(now); -+ for (mouse = micelist; mouse; mouse = mouse->next) { -+ timed_out = mouse->dev.timeout >= 0 && -+ DIF_TIME(mouse->timestamp, now) >= mouse->dev.timeout; -+ if (timed_out || FD_ISSET(mouse->dev.fd, &selSet)) { -+ if (FD_ISSET(mouse->dev.fd, &selSet)) { -+ FD_CLR(mouse->dev.fd, &selSet); -+ pending--; - } -+ attempt = 0; -+ do { -+ rslt = processMouse(mouse, timed_out, ++attempt, &event, text_mode); -+ if (rslt != MOUSE_NO_DATA) { -+ /* pass it to the client or to the default handler, -+ * or to the selection handler -+ */ -+ if (event.vc > MAX_VC) event.vc = 0; -+ if (event.vc == 0 || !cinfo[event.vc] || !do_client(cinfo[event.vc], &event)) -+ if (!cinfo[0] || !do_client(cinfo[0], &event)) -+ do_selection(&event, mouse->options.three_button); -+ } -+ } while (rslt == MOUSE_MORE_DATA); -+ } - } - - /*..................... got connection, process it */ -- -- if (pending && FD_ISSET(ctlfd,&selSet)) { -- FD_CLR(ctlfd,&selSet); pending--; -- newfd=processConn(ctlfd); -- if (newfd>=0) { -- FD_SET(newfd,&connSet); -- FD_SET(newfd,&readySet); -- maxfd=max(maxfd,newfd); -+ if (pending && FD_ISSET(ctlfd, &selSet)) { -+ FD_CLR(ctlfd, &selSet); -+ pending--; -+ if ((ci = accept_client_connection(ctlfd))) { -+ if (ci->data.eventMask & GPM_MOVE) { -+ Gpm_Event e = { 0, 0, ci->data.vc, 0, 0, -+ event.x, event.y, GPM_MOVE, 0, 0 }; -+ do_client(ci, &e); -+ } -+ FD_SET(ci->fd, &connSet); -+ maxfd = max(maxfd, ci->fd); - } - } - - /*........................ got request */ -- -- /* itz 10-22-96 check _all_ clients, not just those on top! */ -- for (i=0; pending && (i<=MAX_VC); i++) { -- Gpm_Cinfo* ci; -+ /* itz 10-22-96 check _all_ clients, not just those on top! */ -+ for (i = 0; pending && i <= MAX_VC; i++) { - for (ci = cinfo[i]; pending && ci; ci = ci->next) { -- if (FD_ISSET(ci->fd,&selSet)) { -- FD_CLR(ci->fd,&selSet); pending--; -- /* itz Sat Sep 12 21:10:22 PDT 1998 */ -- /* this code is clearly incorrect; the next highest -- descriptor after the one we're closing is not necessarily -- being used. Fortunately, it doesn't hurt simply to leave this -- out. */ -- --#ifdef NOTDEF -- if ((processRequest(ci,i)==-1) && maxfd==ci->fd) maxfd--; --#else -- (void)processRequest(ci,i); --#endif -+ if (FD_ISSET(ci->fd, &selSet)) { -+ FD_CLR(ci->fd, &selSet); -+ pending--; -+ if (!process_client_request(ci, i, event.x, event.y, event.clicks, -+ event.buttons, micelist->options.three_button)) { -+ FD_CLR(ci->fd, &connSet); -+ remove_client(ci, i); -+ } - } - } - } - - /*.................. look for a spare fd */ -- - /* itz 10-22-96 this shouldn't happen now! */ -- for (i=0; pending && i<=maxfd; i++) { -- if (FD_ISSET(i,&selSet)) { -- FD_CLR(i,&selSet); -+ for (i = 0; pending && i <= maxfd; i++) { -+ if (FD_ISSET(i, &selSet)) { -+ FD_CLR(i, &selSet); - pending--; -- gpm_report(GPM_PR_WARN,GPM_MESS_STRANGE_DATA,i); -+ gpm_report(GPM_PR_WARN, GPM_MESS_STRANGE_DATA,i); - } - } - - /*................... all done. */ -- -- if(pending) gpm_report(GPM_PR_OOPS,GPM_MESS_SELECT_PROB); -+ if (pending) gpm_report(GPM_PR_OOPS, GPM_MESS_SELECT_PROB); - } /* while(1) */ - } -diff -urN gpm-1.20.1/src/gpn.c gpm/src/gpn.c ---- gpm-1.20.1/src/gpn.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/gpn.c 2003-10-02 01:22:42.000000000 -0500 -@@ -28,201 +28,104 @@ - #include <stdlib.h> - #include <string.h> /* strerror(); ?!? memcpy() */ - #include <ctype.h> /* isdigit */ --#include <signal.h> --#include <stdarg.h> /* Log uses it */ --#include <errno.h> - #include <unistd.h> /* getopt(),symlink() */ --#include <sys/stat.h> /* mkdir() */ --#include <sys/param.h> --#include <sys/time.h> /* timeval */ --#include <sys/wait.h> /* wait() */ --#include <sys/types.h> /* socket() */ --#include <sys/socket.h> /* socket() */ --#include <sys/un.h> /* struct sockaddr_un */ --#include <asm/types.h> /* __u32 */ -- --#ifdef SIGTSTP /* true if BSD system */ --#include <sys/file.h> --#include <sys/ioctl.h> --#endif -- --#ifndef HAVE___U32 --# ifndef _I386_TYPES_H /* /usr/include/asm/types.h */ --typedef unsigned int __u32; --# endif --#endif - - #include "headers/message.h" - #include "headers/gpmInt.h" - #include "headers/gpm.h" -+#include "headers/console.h" -+#include "headers/selection.h" - --extern int errno; -- --/*===================================================================*/ --/* octal digit */ --static int isodigit(const unsigned char c) -+/* usage: display for usage informations */ -+int usage(char *whofailed) - { -- return ((c & ~7) == '0'); -+ if (whofailed) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_SPEC_ERR, whofailed, option.progname); -+ return 1; -+ } -+ printf(GPM_MESS_USAGE, option.progname, DEF_ACCEL, DEF_BAUD, DEF_SEQUENCE, -+ DEF_DELTA, DEF_TIME, DEF_LUT, DEF_SCALE, DEF_SAMPLE, DEF_TYPE); -+ return 1; - } - --/* routine to convert digits from octal notation (Andries Brouwer) */ --static int getsym(const unsigned char *p0, unsigned char *res) -+/***************************************************************************** -+ * the function returns a valid type pointer or NULL if not found -+ *****************************************************************************/ -+static struct Gpm_Type *find_mouse_by_name(char *name) - { -- const unsigned char *p = p0; -- char c; -+ Gpm_Type *type; -+ char *s; -+ int len = strlen(name); - -- c = *p++; -- if (c == '\\' && *p) { -- c = *p++; -- if (isodigit(c)) { -- c -= '0'; -- if (isodigit(*p)) c = 8*c + (*p++ - '0'); -- if (isodigit(*p)) c = 8*c + (*p++ - '0'); -+ for (type = mice; type->fun; type++) { -+ if (!strcasecmp(name, type->name)) break; -+ /* otherwise, look in the synonym list */ -+ for (s = type->synonyms; s; s = strchr(s, ' ')) { -+ while (*s && isspace(*s)) s++; /* skip spaces */ -+ if (!strncasecmp(name, s, len) && !isprint(*(s + len))) break;/*found*/ - } -+ if (s) break; /* found a synonym */ - } -- *res = c; -- return (p - p0); -+ return type->fun ? type : NULL; - } - --/* description missing! FIXME */ --int loadlut(char *charset) -+static void init_button_sequence(struct miceopt *opt, char *arg) - { -- int i, c, fd; -- unsigned char this, next; -- static __u32 long_array[9]={ -- 0x05050505, /* ugly, but preserves alignment */ -- 0x00000000, /* control chars */ -- 0x00000000, /* digits */ -- 0x00000000, /* uppercase and '_' */ -- 0x00000000, /* lowercase */ -- 0x00000000, /* Latin-1 control */ -- 0x00000000, /* Latin-1 misc */ -- 0x00000000, /* Latin-1 uppercase */ -- 0x00000000 /* Latin-1 lowercase */ -+ int i; -+ static struct { -+ char *in; -+ char *out; -+ } seq[] = { -+ {"123", "01234567"}, -+ {"132", "02134657"}, -+ {"213", "01452367"}, /* warning: these must be readable as integers... */ -+ {"231", "02461357"}, -+ {"312", "04152637"}, -+ {"321", "04261537"}, -+ {NULL, NULL} - }; - -+ if (strlen(arg) != 3 || atoi(arg) < 100) -+ exit(usage("sequence")); - --#define inwordLut (long_array+1) -- -- for (i=0; charset[i]; ) { -- i += getsym(charset+i, &this); -- if (charset[i] == '-' && charset[i + 1] != '\0') -- i += getsym(charset+i+1, &next) + 1; -- else -- next = this; -- for (c = this; c <= next; c++) -- inwordLut[c>>5] |= 1 << (c&0x1F); -- } -- -- if ((fd=open(option.consolename, O_WRONLY)) < 0) { -- /* try /dev/console, if /dev/tty0 failed -- is that really senseful ??? */ -- free(option.consolename); /* allocated by main */ -- if((option.consolename=malloc(strlen(GPM_SYS_CONSOLE)+1)) == NULL) -- gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -- strcpy(option.consolename,GPM_SYS_CONSOLE); -- -- if ((fd=open(option.consolename, O_WRONLY)) < 0) gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN_CON); -- } -- if (ioctl(fd, TIOCLINUX, &long_array) < 0) { /* fd <0 is checked */ -- if (errno==EPERM && getuid()) -- gpm_report(GPM_PR_WARN,GPM_MESS_ROOT); /* why do we still continue?*/ -- else if (errno==EINVAL) -- gpm_report(GPM_PR_OOPS,GPM_MESS_CSELECT); -- } -- close(fd); -- -- return 0; -+ for (i = 0; seq[i].in && strcmp(seq[i].in, arg); i++); -+ if (!seq[i].in) -+ exit(usage("button sequence")); -+ opt->sequence = strdup(seq[i].out); /* I can rewrite on it */ - } - --/* usage: display for usage informations */ --int usage(char *whofailed) -+static void validate_mouse(struct micetab *mouse, int mouse_no) - { -- if (whofailed) { -- gpm_report(GPM_PR_ERR,GPM_MESS_SPEC_ERR,whofailed,option.progname); -- return 1; -- } -- printf(GPM_MESS_USAGE,option.progname, DEF_ACCEL, DEF_BAUD, DEF_SEQUENCE, -- DEF_DELTA, DEF_TIME, DEF_LUT,DEF_SCALE, DEF_SAMPLE, DEF_TYPE); -- return 1; --} -- --/* itz Sat Sep 12 10:55:51 PDT 1998 Added this as replacement for the -- unwanted functionality in check_uniqueness. */ -- --void check_kill(void) --{ -- int old_pid; -- FILE* fp = fopen(GPM_NODE_PID, "r"); -- -- /* if we cannot find the old pid file, leave */ -- if (fp == NULL) gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN, GPM_NODE_PID); -- -- /* else read the pid */ -- if (fscanf(fp,"%d",&old_pid) != 1) -- gpm_report(GPM_PR_OOPS,GPM_MESS_READ_PROB,GPM_NODE_PID); -- fclose(fp); -- -- gpm_report(GPM_PR_DEBUG,GPM_MESS_KILLING,old_pid); -- -- /* first check if we run */ -- if (kill(old_pid,0) == -1) { -- gpm_report(GPM_PR_INFO,GPM_MESS_STALE_PID, GPM_NODE_PID); -- unlink(GPM_NODE_PID); -+ if (!mouse->device) { -+ if (!mouse->type && mouse_no > 1) -+ gpm_report(GPM_PR_OOPS, -+ "No device/protocol specified for mouse #%d, probably extra -M option?", mouse_no); -+ else -+ gpm_report(GPM_PR_OOPS, "No device specified for mouse #%d", mouse_no); - } -- /* then kill us (not directly, but the other instance ... ) */ -- if (kill(old_pid,SIGTERM) == -1) -- gpm_report(GPM_PR_OOPS,GPM_MESS_CANT_KILL, old_pid); - -- gpm_report(GPM_PR_INFO,GPM_MESS_KILLED,old_pid); -- exit(0); --} -+ if (!mouse->type) -+ mouse->type = find_mouse_by_name(DEF_TYPE); - --/* itz Sat Sep 12 10:30:05 PDT 1998 this function used to mix two -- completely different things; opening a socket to a running daemon -- and checking that a running daemon existed. Ugly. */ --/* rewritten mostly on 20th of February 2002 - nico */ --void check_uniqueness(void) --{ -- FILE *fp = 0; -- int old_pid = -1; -+ mouse->options.absolute = mouse->type->absolute; - -- if((fp = fopen(GPM_NODE_PID, "r")) != NULL) { -- fscanf(fp, "%d", &old_pid); -- if (kill(old_pid,0) == -1) { -- gpm_report(GPM_PR_INFO,GPM_MESS_STALE_PID, GPM_NODE_PID); -- unlink(GPM_NODE_PID); -- } else /* we are really running, exit asap! */ -- gpm_report(GPM_PR_OOPS,GPM_MESS_ALREADY_RUN, old_pid); -- } -- /* now try to sign ourself */ -- if ((fp = fopen(GPM_NODE_PID,"w")) != NULL) { -- fprintf(fp,"%d\n",getpid()); -- fclose(fp); -- } else { -- gpm_report(GPM_PR_OOPS,GPM_MESS_NOTWRITE,GPM_NODE_PID); -- } -+ if (!mouse->options.sequence) -+ init_button_sequence(&mouse->options, DEF_SEQUENCE); - } - --/***************************************************************************** -- * the function returns a valid type pointer or NULL if not found -- *****************************************************************************/ --struct Gpm_Type *find_mouse_by_name(char *name) -+static void validate_repeater(char *type) - { -- Gpm_Type *type; -- char *s; -- int len = strlen(name); -- -- for (type=mice; type->fun; type++) { -- if (!strcasecmp(name, type->name)) break; -- /* otherwise, look in the synonym list */ -- for (s = type->synonyms; s; s = strchr(s, ' ')) { -- while (*s && isspace(*s)) s++; /* skip spaces */ -- if(!strncasecmp(name, s, len) && !isprint(*(s + len))) break;/*found*/ -- } -- if(s) break; /* found a synonym */ -+ if (strcmp(type, "raw") == 0) -+ repeater.raw = 1; -+ else { -+ repeater.raw = 0; -+ -+ if (!(repeater.type = find_mouse_by_name(type))) -+ exit(M_listTypes()); /* not found */ -+ -+ if (!repeater.type->repeat_fun) /* unsupported translation */ -+ gpm_report(GPM_PR_OOPS, GPM_MESS_NO_REPEAT, type); - } -- if (!type->fun) return NULL; -- return type; - } - - /***************************************************************************** -@@ -230,60 +133,86 @@ - * Can't believe it, today cmdline() really does what the name tries to say - *****************************************************************************/ - void cmdline(int argc, char **argv) --{ -- extern struct options option; -+{ -+ struct micetab *mouse; -+ struct miceopt *opt; - char options[]="a:A::b:B:d:Dg:hi:kl:m:Mo:pr:R::s:S:t:TuvV::23"; -- int opt; -+ int opt_char, tmp; -+ int mouse_no = 1; -+ -+ mouse = add_mouse(); -+ opt = &mouse->options; - -- /* initialize for the dual mouse */ -- mouse_table[2]=mouse_table[1]=mouse_table[0]; /* copy defaults */ -- which_mouse=mouse_table+1; /* use the first */ -- -- while ((opt = getopt(argc, argv, options)) != -1) { -- switch (opt) { -- case 'a': opt_accel = atoi(optarg); break; -- case 'A': opt_aged++; -- if (optarg) -- opt_age_limit = atoi(optarg); break; -- case 'b': opt_baud = atoi(optarg); break; -- case 'B': opt_sequence = optarg; break; -- case 'd': opt_delta = atoi(optarg); break; -- case 'D': option.run_status = GPM_RUN_DEBUG; break; -- case 'g': opt_glidepoint_tap=atoi(optarg); break; -- case 'h': exit(usage(NULL)); -- case 'i': opt_time=atoi(optarg); break; -- case 'k': check_kill(); break; -- case 'l': opt_lut = optarg; break; -- case 'm': add_mouse(GPM_ADD_DEVICE,optarg); -- opt_dev = optarg; break; /* GO AWAY!*/ -- case 'M': opt_double++; option.repeater++; -- if (option.repeater_type == 0) -- option.repeater_type = "msc"; -- which_mouse=mouse_table+2; break; -- case 'o': add_mouse(GPM_ADD_OPTIONS,optarg); -- gpm_report(GPM_PR_DEBUG,"options: %s",optarg); -- opt_options = optarg; break; /* GO AWAY */ -- case 'p': opt_ptrdrag = 0; break; -- case 'r': -- /* being called responsiveness, I must take the inverse */ -- opt_scale=atoi(optarg); -- if(!opt_scale || opt_scale > 100) opt_scale=100; /* the maximum */ -- else opt_scale=100/opt_scale; break; -- case 'R': -- option.repeater++; -- if (optarg) option.repeater_type = optarg; -- else option.repeater_type = "msc"; break; -- case 's': opt_sample = atoi(optarg); break; -- case 'S': if (optarg) opt_special = optarg; -- else opt_special=""; break; -- case 't': add_mouse(GPM_ADD_TYPE,optarg); -- opt_type = optarg; break; /* GO AWAY */ -- case 'u': option.autodetect = 1; break; -- case 'T': opt_test++; break; -- case 'v': printf(GPM_MESS_VERSION "\n"); exit(0); -- case '2': opt_three = -1; break; -- case '3': opt_three = 1; break; -- default: exit(usage("commandline")); -+ while ((opt_char = getopt(argc, argv, options)) != -1) { -+ switch (opt_char) { -+ case 'a': if ((opt->accel = atoi(optarg)) < 1) -+ exit(usage("acceleration")); -+ break; -+ case 'A': sel_opts.aged = 1; -+ if (optarg) -+ sel_opts.age_limit = atoi(optarg); -+ break; -+ case 'b': opt->baud = atoi(optarg); -+ break; -+ case 'B': init_button_sequence(opt, optarg); -+ break; -+ case 'd': if ((opt->delta = atoi(optarg)) < 2) -+ exit(usage("delta")); -+ break; -+ case 'D': option.run_status = GPM_RUN_DEBUG; -+ break; -+ case 'g': if (atoi(optarg) > 3) -+ exit(usage("glidepoint tap button")); -+ opt->glidepoint_tap = GPM_B_LEFT >> (atoi(optarg) - 1); -+ break; -+ case 'h': exit(usage(NULL)); -+ case 'i': opt->time = atoi(optarg); -+ break; -+ case 'k': kill_gpm(); -+ break; -+ case 'l': console.charset = optarg; -+ break; -+ case 'm': mouse->device = optarg; -+ break; -+ case 'M': validate_mouse(mouse, mouse_no); -+ mouse = add_mouse(); -+ opt = &mouse->options; -+ mouse_no++; -+ if (!repeater.type && !repeater.raw) -+ repeater.type = find_mouse_by_name(DEF_REP_TYPE); -+ break; -+ case 'o': gpm_report(GPM_PR_DEBUG,"options: %s", optarg); -+ opt->text = optarg; -+ break; -+ case 'p': sel_opts.ptrdrag = 0; -+ break; -+ case 'r': /* being called responsiveness, I must take the inverse */ -+ tmp = atoi(optarg); -+ if (!tmp || tmp > 100) tmp = 1; -+ opt->scalex = 100 / tmp; -+ break; -+ case 'R': validate_repeater((optarg) ? optarg : DEF_REP_TYPE); -+ break; -+ case 's': opt->sample = atoi(optarg); -+ break; -+ case 'S': if (optarg) opt_special = optarg; -+ else opt_special=""; -+ break; -+ case 't': mouse->type = find_mouse_by_name(optarg); -+ if (!mouse->type) -+ exit(M_listTypes()); -+ break; -+ case 'u': option.autodetect = 1; -+ break; -+ case 'v': printf(GPM_MESS_VERSION "\n"); -+ exit(0); -+ case '2': opt->three_button = -1; -+ break; -+ case '3': opt->three_button = 1; -+ break; -+ default: exit(usage("commandline")); - } - } -+ -+ validate_mouse(micelist, mouse_no); - } -diff -urN gpm-1.20.1/src/headers/client.h gpm/src/headers/client.h ---- gpm-1.20.1/src/headers/client.h 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/headers/client.h 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,57 @@ -+/* -*-mode:C;tab-width:3-*- -+ * client.h - GPM client handling (server side) -+ * -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#ifndef __GPM_CLIENT_H -+#define __GPM_CLIENT_H_ -+ -+#ifdef HAVE_LINUX_TTY_H -+#include <linux/tty.h> -+#endif -+ -+#include "headers/gpm.h" -+ -+/* FIXME: still needed ?? */ -+/* How many virtual consoles are managed? */ -+#ifndef MAX_NR_CONSOLES -+# define MAX_NR_CONSOLES 64 /* this is always sure */ -+#endif -+ -+#define MAX_VC MAX_NR_CONSOLES /* doesn't work before 1.3.77 */ -+ -+struct client_info { -+ Gpm_Connect data; -+ int fd; -+ struct client_info *next; -+}; -+ -+struct Gpm_Event; -+ -+extern struct client_info *cinfo[MAX_VC + 1]; -+ -+int listen_for_clients(void); -+struct client_info *accept_client_connection(int fd); -+void remove_client(struct client_info *ci, int vc); -+void notify_clients_resize(void); -+int do_client(struct client_info *cinfo, struct Gpm_Event *event); -+int process_client_request(struct client_info *ci, int vc, -+ int x, int y, int buttons, int clicks, -+ int three_button_mouse); -+ -+#endif /* __GPM_CLIENT_H_ */ -diff -urN gpm-1.20.1/src/headers/console.h gpm/src/headers/console.h ---- gpm-1.20.1/src/headers/console.h 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/headers/console.h 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,42 @@ -+/* -*-mode:C;tab-width:3-*- -+ * console.h - GPM console and selection/paste handling -+ * -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#ifndef __GPM_CONSOLE_H_ -+#define __GPM_CONSOLE_H_ -+ -+struct gpm_console { -+ char *device; -+ char *charset; -+ int max_x, max_y; -+}; -+ -+extern struct gpm_console console; -+ -+int open_console(int mode); -+char *get_console_name(); -+char *compose_vc_name(int vc); -+int is_text_console(void); -+void wait_text_console(void); -+void refresh_console_size(void); -+int is_console_owner(int vc, uid_t uid); -+int get_console_state(unsigned char *shift_state); -+void console_load_lut(void); -+ -+#endif /* __GPM_CONSOLE_H_ */ -diff -urN gpm-1.20.1/src/headers/gpmInt.h gpm/src/headers/gpmInt.h ---- gpm-1.20.1/src/headers/gpmInt.h 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/headers/gpmInt.h 2003-10-02 01:22:42.000000000 -0500 -@@ -23,8 +23,7 @@ - #ifndef _GPMINT_INCLUDED - #define _GPMINT_INCLUDED - --#include <sys/types.h> /* time_t */ /* for whom ???? FIXME */ -- -+#include <sys/time.h> /* timeval */ - #include "gpm.h" - - #if !defined(__GNUC__) -@@ -35,23 +34,12 @@ - /* timeout for the select() syscall */ - #define SELECT_TIME 86400 /* one day */ - --#ifdef HAVE_LINUX_TTY_H --#include <linux/tty.h> --#endif -- --/* FIXME: still needed ?? */ --/* How many virtual consoles are managed? */ --#ifndef MAX_NR_CONSOLES --# define MAX_NR_CONSOLES 64 /* this is always sure */ --#endif -- --#define MAX_VC MAX_NR_CONSOLES /* doesn't work before 1.3.77 */ -- - /* How many buttons may the mouse have? */ - /* #define MAX_BUTTONS 3 ===> not used, it is hardwired :-( */ - - /* all the default values */ - #define DEF_TYPE "ms" -+#define DEF_REP_TYPE "msc" - #define DEF_DEV NULL /* use the type-related one */ - #define DEF_LUT "-a-zA-Z0-9_./\300-\326\330-\366\370-\377" - #define DEF_SEQUENCE "123" /* how buttons are reordered */ -@@ -62,12 +50,10 @@ - #define DEF_SCALE 10 - #define DEF_TIME 250 /* time interval (ms) for multiple clicks */ - #define DEF_THREE 0 /* have three buttons? */ --#define DEF_KERNEL 0 /* no kernel module, by default */ - - /* 10 on old computers (<=386), 0 on current machines */ - #define DEF_CLUSTER 0 /* maximum number of clustered events */ - --#define DEF_TEST 0 - #define DEF_PTRDRAG 1 /* double or triple click */ - #define DEF_GLIDEPOINT_TAP 0 /* tapping emulates no buttons by default */ - -@@ -84,11 +70,6 @@ - #define GPM_DEVFS_CONSOLE "/dev/vc/0" - #define GPM_OLD_CONSOLE "/dev/tty0" - --/* for adding a mouse; add_mouse */ --#define GPM_ADD_DEVICE 0 --#define GPM_ADD_TYPE 1 --#define GPM_ADD_OPTIONS 2 -- - /*** mouse commands ***/ - - #define GPM_AUX_SEND_ID 0xF2 -@@ -117,126 +98,95 @@ - - /*....................................... Structures */ - -+struct micedev { -+ int fd; -+ int timeout; /* the protocol driver wants to be called -+ after X msec even if there is no new data -+ arrived (-1 to disable/default) */ -+ void *private; /* private data maintained by protocol driver */ -+}; -+ -+struct miceopt { -+ char *sequence; -+ int baud; -+ int sample; -+ int delta; -+ int accel; -+ int scalex, scaley; -+ int time; -+ int cluster; -+ int three_button; -+ int glidepoint_tap; -+ int absolute; /* device reports absolute coordinates - initially copied -+ from Gpm_Type; allows same protocol (type) control devices -+ in absolute and relative mode */ -+ char *text; /* extra textual options supplied via '-o text' */ -+}; -+ - /* - * and this is the entry in the mouse-type table - */ - typedef struct Gpm_Type { -- char *name; -- char *desc; /* a descriptive line */ -- char *synonyms; /* extra names (the XFree name etc) as a list */ -- int (*fun)(Gpm_Event *state, unsigned char *data); -- struct Gpm_Type *(*init)(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv); -- unsigned short flags; -- unsigned char proto[4]; -- int packetlen; -- int howmany; /* how many bytes to read at a time */ -- int getextra; /* does it get an extra byte? (only mouseman) */ -- int absolute; /* flag indicating absolute pointing device */ -+ char *name; -+ char *desc; /* a descriptive line */ -+ char *synonyms; /* extra names (the XFree name etc) as a list */ -+ int (*fun)(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state); -+ int (*init)(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type); -+ unsigned short flags; -+ unsigned char proto[4]; -+ int packetlen; -+ int howmany; /* how many bytes to read at a time */ -+ int getextra; /* does it get an extra byte? (only mouseman) */ -+ int absolute; /* flag indicating absolute pointing device */ - -- int (*repeat_fun)(Gpm_Event *state, int fd); /* repeat this event into fd */ -+ int (*repeat_fun)(Gpm_Event *state, int fd); /* repeat this event into fd */ - /* itz Mon Jan 11 23:27:54 PST 1999 */ - } Gpm_Type; - - #define GPM_EXTRA_MAGIC_1 0xAA - #define GPM_EXTRA_MAGIC_2 0x55 - --typedef struct Gpm_Cinfo { -- Gpm_Connect data; -- int fd; -- struct Gpm_Cinfo *next; --} Gpm_Cinfo; -- -- --/*....................................... Global variables */ -- --/* this structure is used to hide the dual-mouse stuff */ -- --struct mouse_features { -- char *opt_type, *opt_dev, *opt_sequence; -- int opt_baud,opt_sample,opt_delta, opt_accel, opt_scale, opt_scaley; -- int opt_time, opt_cluster, opt_three, opt_glidepoint_tap; -- char *opt_options; /* extra textual configuration */ -- Gpm_Type *m_type; -- int fd; --}; -- --extern struct mouse_features mouse_table[3], *which_mouse; /*the current one*/ -- --// looks unused; delete --//typedef struct Opt_struct_type {int a,B,d,i,p,r,V,A;} Opt_struct_type; -- --/* this is not very clean, actually, but it works fine */ --#define opt_type (which_mouse->opt_type) --#define opt_dev (which_mouse->opt_dev) --#define opt_sequence (which_mouse->opt_sequence) --#define opt_baud (which_mouse->opt_baud) --#define opt_sample (which_mouse->opt_sample) --#define opt_delta (which_mouse->opt_delta) --#define opt_accel (which_mouse->opt_accel) --#define opt_scale (which_mouse->opt_scale) --#define opt_scaley (which_mouse->opt_scaley) --#define opt_time (which_mouse->opt_time) --#define opt_cluster (which_mouse->opt_cluster) --#define opt_three (which_mouse->opt_three) --#define opt_glidepoint_tap (which_mouse->opt_glidepoint_tap) --#define opt_options (which_mouse->opt_options) -- --#define m_type (which_mouse->m_type) -- --/* the other variables */ -- --extern char *opt_lut; --extern int opt_test, opt_ptrdrag; --extern int opt_kill; --extern int opt_kernel, opt_explicittype; --extern int opt_aged; --extern time_t opt_age_limit; - extern char *opt_special; --extern int opt_rawrep; --extern int fifofd; --extern int opt_double; -- --extern Gpm_Type *repeated_type; - extern Gpm_Type mice[]; /* where the hell are the descriptions...*/ --extern struct winsize win; --extern int maxx, maxy; --extern Gpm_Cinfo *cinfo[MAX_VC+1]; - - /* new variables <CLEAN> */ - - /* structure prototypes */ -+struct repeater { -+ int fd; -+ int raw; -+ Gpm_Type *type; -+}; - - /* contains all mice */ - struct micetab { - struct micetab *next; -- char *device; -- char *protocol; -- char *options; -+ struct micedev dev; -+ struct miceopt options; -+ Gpm_Type *type; -+ char *device; -+ int buttons; /* mouse's button state from last read */ -+ struct timeval timestamp; /* last time mouse data arrived */ - }; - - struct options { - int autodetect; /* -u [aUtodetect..'A' is not available] */ -- int no_mice; /* number of mice */ -- int repeater; /* repeat data */ -- char *repeater_type; /* repeat data as which mouse type */ - int run_status; /* startup/daemon/debug */ - char *progname; /* hopefully gpm ;) */ -- struct micetab *micelist; /* mice and their options */ -- char *consolename; /* /dev/tty0 || /dev/vc/0 */ - }; - - /* global variables */ - struct options option; /* one should be enough for us */ -+extern struct repeater repeater; /* again, only one */ -+extern struct micetab *micelist; - - /* new variables </CLEAN> */ - -- - /*....................................... Prototypes */ - /* server_tools.c */ --void add_mouse (int type, char *value); --int init_mice (struct micetab *micelist); --int reset_mice(struct micetab *micelist); -+struct micetab *add_mouse(void); -+void init_mice(void); -+void cleanup_mice(void); - - /* startup.c */ - void startup(int argc, char **argv); -@@ -246,17 +196,15 @@ - - /* gpn.c */ - void cmdline(int argc, char **argv); --int giveInfo(int request, int fd); --int loadlut(char *charset); --int usage(char *whofailed); --struct Gpm_Type *find_mouse_by_name(char *name); -+int giveInfo(int request, int fd); -+int usage(char *whofailed); - void check_uniqueness(void); --void check_kill(void); -- -+void kill_gpm(void); - - /* mice.c */ - extern int M_listTypes(void); -- /* special.c */ -+ -+ /* special.c */ - int processSpecial(Gpm_Event *event); - int twiddler_key(unsigned long message); - int twiddler_key_init(void); -diff -urN gpm-1.20.1/src/headers/input-defines.h gpm/src/headers/input-defines.h ---- gpm-1.20.1/src/headers/input-defines.h 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/headers/input-defines.h 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,81 @@ -+/* -+ * input-defines.h - complements <linux/input.h> adding missing bits -+ * -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+#ifndef __GPM_INPUT_DEFINES_H -+#define __GPM_INPUT_DEFINES_H -+ -+#include <linux/input.h> -+#include "headers/config.h" -+ -+#ifndef ABS_TOOL_WIDTH -+#define ABS_TOOL_WIDTH 0x1c -+#endif -+ -+#ifndef BTN_TOOL_FINGER -+#define BTN_TOOL_FINGER 0x145 -+#endif -+ -+#ifndef BTN_TOUCH -+#define BTN_TOUCH 0x14a -+#endif -+ -+#ifndef BTN_TOOL_DOUBLETAP -+#define BTN_TOOL_DOUBLETAP 0x14d -+#endif -+ -+#ifndef BTN_TOOL_TRIPLETAP -+#define BTN_TOOL_TRIPLETAP 0x14e -+#endif -+ -+#ifndef MSC_GESTURE -+#define MSC_GESTURE 2 -+#endif -+ -+#ifndef EV_SYNC -+#define EV_SYNC 0 -+#endif -+ -+#ifndef SYN_REPORT -+#define SYN_REPORT 0 -+#endif -+ -+#ifndef PSMOUSE_SYNAPTICS -+#define PSMOUSE_SYNAPTICS 7 -+#endif -+ -+#ifndef HAVE_INPUT_ID -+struct input_id { -+ unsigned short bustype; -+ unsigned short vendor; -+ unsigned short product; -+ unsigned short version; -+}; -+#endif -+ -+#ifndef HAVE_INPUT_ABSINFO -+struct input_absinfo { -+ int value; -+ int minimum; -+ int maximum; -+ int fuzz; -+ int flat; -+}; -+#endif -+ -+#endif -diff -urN gpm-1.20.1/src/headers/message.h gpm/src/headers/message.h ---- gpm-1.20.1/src/headers/message.h 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/headers/message.h 2003-10-02 01:22:42.000000000 -0500 -@@ -96,7 +96,6 @@ - " -S [commands] enable special commands (see man page)\n" \ - " -t mouse-type sets mouse type (default '%s')\n" \ - " Use a non-existent type (e.g. \"help\") to get a list\n" \ -- " -T test: read mouse, no clients\n" \ - " -v print version and exit\n" \ - " -V verbosity increase number of logged messages\n\n\n" \ - " Examples:\n\n" \ -@@ -168,7 +167,8 @@ - #define GPM_MESS_SELECT_TIMES "selected %i times" - - #define GPM_MESS_OPTION_NO_ARG "%s: Option \"%s\" takes no argument: ignoring \"%s\"" --#define GPM_MESS_INVALID_ARG "%s: Invalid arg. \"%s\" to \"%s\"" -+#define GPM_MESS_INVALID_ARG "%s: Invalid argument \"%s\" for option \"%s\"" -+#define GPM_MESS_MISSING_ARG "%s: Option \"%s\" requires an argument" - #define GPM_MESS_CONT_WITH_ERR "%s: Continuing despite errors in option parsing" - #define GPM_MESS_TOO_MANY_OPTS "%s: Too many options for \"-t %s\"" - -@@ -196,7 +196,7 @@ - - /* warnings */ - #define GPM_MESS_REQUEST_ON "Request on vc %i > %i" --#define GPM_MESS_FAILED_CONNECT "Failed gpm connect attempt by uid %d for vc %s" -+#define GPM_MESS_FAILED_CONNECT "Failed gpm connect attempt by uid %d for vc %d" - #define GPM_MESS_ZERO_SCREEN_DIM "zero screen dimension, assuming 80x25" - #define GPM_MESS_STRANGE_DATA "Data on strange file descriptor %d" - #define GPM_MESS_RESIZING "%s pid %i is resizing :-)" -diff -urN gpm-1.20.1/src/headers/optparser.h gpm/src/headers/optparser.h ---- gpm-1.20.1/src/headers/optparser.h 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/headers/optparser.h 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,50 @@ -+/* -+ * optparser.h - GPM mouse options parser -+ * -+ * Copyright (C) 1993 Andrew Haylett <ajh@gec-mrc.co.uk> -+ * Copyright (C) 1994-2000 Alessandro Rubini <rubini@linux.it> -+ * Copyright (C) 1998,1999 Ian Zimmerman <itz@rahul.net> -+ * Copyright (C) 2001,2002 Nico Schottelius <nicos@pcsystems.de> -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+#ifndef __GPM_OPTPARSER_H_ -+#define __GPM_OPTPARSER_H_ -+ -+enum option_type { -+ OPT_BOOL = 1, -+ OPT_INT, /* "%i" */ -+ OPT_DEC, /* "%d" */ -+ OPT_STRING, -+ /* other types must be added */ -+ OPT_END = 0 -+}; -+ -+struct option_helper { -+ char *name; -+ enum option_type type; -+ union u { -+ int *iptr; /* used for int and bool arguments */ -+ char **sptr; /* used for string arguments, by strdup()ing the value */ -+ } u; -+ int value; /* used for boolean arguments */ -+ int present; -+}; -+ -+int parse_options(const char *who, const char *opt, char sep, struct option_helper *info); -+int check_no_options(const char *proto, const char *opts, char sep); -+int is_option_present(struct option_helper *info, const char *name); -+#endif -diff -urN gpm-1.20.1/src/headers/selection.h gpm/src/headers/selection.h ---- gpm-1.20.1/src/headers/selection.h 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/headers/selection.h 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,37 @@ -+/* -+ * console.h - GPM selection/paste handling -+ * -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#ifndef __GPM_SELECTION_H_ -+#define __GPM_SELECTION_H_ -+ -+struct sel_options { -+ int aged; -+ int age_limit; -+ int ptrdrag; -+}; -+ -+struct Gpm_Event; -+ -+extern struct sel_options sel_opts; /* only one exists */ -+ -+void do_selection(struct Gpm_Event *event, int three_button_mode); -+void selection_disable_paste(void); -+ -+#endif /* __GPM_CONSOLE_H_ */ -diff -urN gpm-1.20.1/src/headers/synaptics.h gpm/src/headers/synaptics.h ---- gpm-1.20.1/src/headers/synaptics.h 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/headers/synaptics.h 2003-10-02 01:22:42.000000000 -0500 -@@ -62,7 +62,7 @@ - ** - ** Process the touchpad 6/7/8 byte data. - */ --void syn_process_serial_data (Gpm_Event *state, -+void syn_process_serial_data (int fd, Gpm_Event *state, - unsigned char *data); - - -@@ -72,7 +72,7 @@ - ** - ** Process the touchpad 6 byte data. - */ --void syn_process_ps2_data (Gpm_Event *state, -+void syn_process_ps2_data (int fd, Gpm_Event *state, - unsigned char *data); - - -diff -urN gpm-1.20.1/src/lib/liblow.c gpm/src/lib/liblow.c ---- gpm-1.20.1/src/lib/liblow.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/lib/liblow.c 2003-10-02 01:22:42.000000000 -0500 -@@ -80,6 +80,8 @@ - int gpm_consolefd=-1; /* used to invoke ioctl() */ - int gpm_morekeys=0; - -+static char *consolename; -+ - int gpm_convert_event(unsigned char *mdata, Gpm_Event *ePtr); - - /*----------------------------------------------------------------------------* -@@ -192,14 +194,13 @@ - char *tty = NULL; - char *term = NULL; - int i; -- extern struct options option; - static int checked_con = 0; - struct sockaddr_un addr; - struct winsize win; - Gpm_Stst *new = NULL; - char* sock_name = 0; - -- option.consolename = NULL; -+ consolename = NULL; - - gpm_report(GPM_PR_DEBUG,"VC: %d",flag); - -@@ -216,7 +217,7 @@ - - /* check whether we know what name the console is: what's with the lib??? */ - if(checked_con == 0) { -- option.consolename = Gpm_get_console(); -+ consolename = Gpm_get_console(); - checked_con++; - } - -@@ -245,10 +246,10 @@ - conn->vc=0; /* default handler */ - if (flag > 0) { /* forced vc number */ - conn->vc=flag; -- if((tty = malloc(strlen(option.consolename)+Gpm_cnt_digits(flag))) == NULL) -+ if((tty = malloc(strlen(consolename)+Gpm_cnt_digits(flag))) == NULL) - gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -- memcpy(tty,option.consolename,strlen(option.consolename)-1); -- sprintf(&tty[strlen(option.consolename)-1],"%i",flag); -+ memcpy(tty,consolename,strlen(consolename)-1); -+ sprintf(&tty[strlen(consolename)-1],"%i",flag); - } else { /* use your current vc */ - if (isatty(0)) tty = ttyname(0); /* stdin */ - if (!tty && isatty(1)) tty = ttyname(1); /* stdout */ -@@ -258,13 +259,13 @@ - goto err; - } - /* do we really need this check ? */ -- if(strncmp(tty,option.consolename,strlen(option.consolename)-1) -- || !isdigit(tty[strlen(option.consolename)-1])) { -- gpm_report(GPM_PR_ERR,"strncmp/isdigit/option.consolename failed"); -+ if(strncmp(tty,consolename,strlen(consolename)-1) -+ || !isdigit(tty[strlen(consolename)-1])) { -+ gpm_report(GPM_PR_ERR,"strncmp/isdigit/consolename failed"); - goto err; - } - -- conn->vc=atoi(&tty[strlen(option.consolename)-1]); -+ conn->vc=atoi(&tty[strlen(consolename)-1]); - } - - if (gpm_consolefd == -1) -@@ -272,6 +273,8 @@ - gpm_report(GPM_PR_ERR,GPM_MESS_DOUBLE_S,tty,strerror(errno)); - goto err; - } -+ -+ if (flag > 0) free(tty); - } - - new->info=*conn; -diff -urN gpm-1.20.1/src/lib/tools.c gpm/src/lib/tools.c ---- gpm-1.20.1/src/lib/tools.c 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/lib/tools.c 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,93 @@ -+/* -+ * tools.c - tools which are needed by client and server -+ * -+ * Copyright (c) 2001 Nico Schottelius <nico@schottelius.org> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#include <stdio.h> /* NULL */ -+#include <string.h> -+#include <stdlib.h> -+#include <sys/types.h> /* these three are */ -+#include <sys/stat.h> /* needed for */ -+#include <unistd.h> /* stat() */ -+ -+#include "headers/gpmInt.h" /* only used for some defines */ -+#include "headers/message.h" -+ -+/***************************************************************************** -+ * check, whether devfs is used or not. -+ * See /usr/src/linux/Documentation/filesystems/devfs/ for details. -+ * Returns: the name of the console (/dev/tty0 or /dev/vc/0) -+ *****************************************************************************/ -+char *Gpm_get_console( void ) -+{ -+ -+ char *back = NULL, *tmp = NULL; -+ struct stat buf; -+ -+ /* first try the devfs device, because in the next time this will be -+ * the preferred one. If that fails, take the old console */ -+ -+ /* Check for open new console */ -+ if (stat(GPM_DEVFS_CONSOLE,&buf) == 0) -+ tmp = GPM_DEVFS_CONSOLE; -+ -+ /* Failed, try OLD console */ -+ else if(stat(GPM_OLD_CONSOLE,&buf) == 0) -+ tmp = GPM_OLD_CONSOLE; -+ -+ if(tmp != NULL) -+ if((back = malloc(strlen(tmp) + sizeof(char)) ) != NULL) -+ strcpy(back,tmp); -+ -+ return(back); -+} -+ -+/* what's the english name for potenz ? */ -+int Gpm_x_high_y(int base, int pot_y) -+{ -+ int val = 1; -+ -+ if(pot_y == 0) val = 1; -+ else if(pot_y < 0) val = 0; /* ugly hack ;) */ -+ else while(pot_y > 0) { -+ val = val * base; -+ pot_y--; -+ } -+ return val; -+} -+ -+/* return characters needed to display int */ -+int Gpm_cnt_digits(int number) -+{ -+ /* 0-9 = 1 10^0 <-> (10^1)-1 -+ * 10 - 99 = 2 10^1 <-> (10^2)-1 -+ * 100 - 999 = 3 10^2 <-> (10^3)-1 -+ * 1000 - 9999 = 4 ... */ -+ -+ int ret = 0, num = 0; -+ -+ /* non negative, please */ -+ if(number < 0) number *= -1; -+ else if(number == 0) ret = 1; -+ else while(number > num) { -+ ret++; -+ num = (Gpm_x_high_y(10,ret) - 1); -+ } -+ -+ return(ret); -+} -diff -urN gpm-1.20.1/src/Makefile.in gpm/src/Makefile.in ---- gpm-1.20.1/src/Makefile.in 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/Makefile.in 2003-10-02 01:22:42.000000000 -0500 -@@ -12,15 +12,16 @@ - include $(top_builddir)/Makefile.include - - # Main portion: regular build rules -+MICESRC = mice.c twiddler.c synaptics.c @EVDEV_SRCS@ - --GSRC = main.c gpm.c gpn.c mice.c special.c twiddler.c synaptics.c \ -- startup.c server_tools.c -+GSRC = main.c gpm.c gpn.c special.c startup.c server_tools.c console.c \ -+ selection.c client.c optparser.c $(MICESRC) - --GOBJ = $(GSRC:.c=.o) report.o tools.o -+GOBJ = $(GSRC:.c=.o) report.o - --LSRC = lib/liblow.c lib/libhigh.c lib/libxtra.c lib/report-lib.c -+LSRC = lib/liblow.c lib/libhigh.c lib/libxtra.c lib/report-lib.c lib/tools.c - --LOBJ = $(LSRC:.c=.o) tools.o @CURSES_OBJS@ -+LOBJ = $(LSRC:.c=.o) @CURSES_OBJS@ - - PICS = $(LOBJ:.o=.lo) - -@@ -143,7 +144,7 @@ - $(CC) -I. @CPPFLAGS@ $(CPPFLAGS) @CFLAGS@ $(CFLAGS) -c -o $@.o $< - $(CC) @LDFLAGS@ $(LDFLAGS) -o $@ $@.o @LIBS@ $(LIBS) lib/libgpm.a - --prog/mouse-test: mice.o twiddler.o synaptics.o -+prog/mouse-test: $(MICESRC:.c=.o) console.o optparser.o - - $(PROG): lib/libgpm.so lib/@SHLIB@ lib/libgpm.a - -diff -urN gpm-1.20.1/src/mice.c gpm/src/mice.c ---- gpm-1.20.1/src/mice.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/mice.c 2003-10-02 01:22:42.000000000 -0500 -@@ -46,15 +46,11 @@ - #include <string.h> - #include <stdlib.h> - #include <termios.h> --#include <fcntl.h> --#include <termios.h> - #include <errno.h> - #include <unistd.h> - #include <ctype.h> - --#include <sys/types.h> - #include <sys/stat.h> /* stat() */ --#include <sys/time.h> /* select() */ - - #include <linux/kdev_t.h> /* MAJOR */ - #include <linux/keyboard.h> -@@ -72,135 +68,40 @@ - - - #include "headers/gpmInt.h" -+#include "headers/console.h" - #include "headers/twiddler.h" - #include "headers/synaptics.h" - #include "headers/message.h" -- --/*========================================================================*/ --/* Parsing argv: helper dats struct function (should they get elsewhere?) */ --/*========================================================================*/ -- --enum argv_type { -- ARGV_BOOL = 1, -- ARGV_INT, /* "%i" */ -- ARGV_DEC, /* "%d" */ -- ARGV_STRING, -- /* other types must be added */ -- ARGV_END = 0 --}; -- --typedef struct argv_helper { -- char *name; -- enum argv_type type; -- union u { -- int *iptr; /* used for int and bool arguments */ -- char **sptr; /* used for string arguments, by strdup()ing the value */ -- } u; -- int value; /* used for boolean arguments */ --} argv_helper; -- --static int parse_argv(argv_helper *info, int argc, char **argv) --{ -- int i, j = 0, errors = 0; -- long l; -- argv_helper *p; -- char *s, *t; -- int base = 0; /* for strtol */ -- -- -- for (i=1; i<argc; i++) { -- for (p = info; p->type != ARGV_END; p++) { -- j = strlen(p->name); -- if (strncmp(p->name, argv[i], j)) -- continue; -- if (isalnum(argv[i][j])) -- continue; -- break; -- } -- if (p->type == ARGV_END) { /* not found */ -- fprintf(stderr, "%s: Uknown option \"%s\" for pointer \"%s\"\n", -- option.progname, argv[i], argv[0]); -- errors++; -- continue; -- } -- /* Found. Look for trailing stuff, if any */ -- s = argv[i]+j; -- while (*s && isspace(*s)) s++; /* skip spaces */ -- if (*s == '=') s++; /* skip equal */ -- while (*s && isspace(*s)) s++; /* skip other spaces */ -- -- /* Now parse what s is */ -- switch(p->type) { -- case ARGV_BOOL: -- if (*s) { -- gpm_report(GPM_PR_ERR,GPM_MESS_OPTION_NO_ARG,option.progname,p->name,s); -- errors++; -- } -- *(p->u.iptr) = p->value; -- break; -- -- case ARGV_DEC: -- base = 10; /* and fall through */ -- case ARGV_INT: -- l = strtol(s, &t, base); -- if (*t) { -- gpm_report(GPM_PR_ERR,GPM_MESS_INVALID_ARG, option.progname, s, p->name); -- errors++; -- break; -- } -- *(p->u.iptr) = (int)l; -- break; -- -- case ARGV_STRING: -- *(p->u.sptr) = strdup(s); -- break; -- -- case ARGV_END: /* let's please "-Wall" */ -- break; -- } -- } /* for i in argc */ -- if (errors) gpm_report(GPM_PR_ERR,GPM_MESS_CONT_WITH_ERR, option.progname); -- return errors; --} -- --/*========================================================================*/ --/* Provide a common error engine by parsing with an empty option-set */ --/*========================================================================*/ --static volatile int check_no_argv(int argc, char **argv) --{ -- static argv_helper optioninfo[] = { -- {"", ARGV_END} -- }; -- return parse_argv(optioninfo, argc, argv); --} -+#include "headers/optparser.h" - - /*========================================================================*/ - /* Parse the "old" -o options */ - /*========================================================================*/ --static int option_modem_lines(int fd, int argc, char **argv) -+static int option_modem_lines(int fd, char *proto, char *opts) - { -- static unsigned int err, lines, reallines; -+ static unsigned int lines, reallines; -+ static struct option_helper optioninfo[] = { -+ {"dtr", OPT_BOOL, u: {iptr: &lines}, value: TIOCM_DTR}, -+ {"rts", OPT_BOOL, u: {iptr: &lines}, value: TIOCM_RTS}, -+ {"both", OPT_BOOL, u: {iptr: &lines}, value: TIOCM_DTR | TIOCM_RTS}, -+ {"", OPT_END} -+ }; - -- static argv_helper optioninfo[] = { -- {"dtr", ARGV_BOOL, u: {iptr: &lines}, value: TIOCM_DTR}, -- {"rts", ARGV_BOOL, u: {iptr: &lines}, value: TIOCM_RTS}, -- {"both", ARGV_BOOL, u: {iptr: &lines}, value: TIOCM_DTR | TIOCM_RTS}, -- {"", ARGV_END} -- }; -+ int rslt = parse_options(proto, opts, ',', optioninfo); - -- if (argc<2) return 0; -- if (argc > 2) { -- gpm_report(GPM_PR_ERR,GPM_MESS_TOO_MANY_OPTS,option.progname, argv[0]); -+ if (rslt < 0) { -+ errno = EINVAL; -+ return -1; -+ } else if (rslt > 1) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_TOO_MANY_OPTS, option.progname, proto); - errno = EINVAL; /* used by gpm_oops(), if the caller reports failure */ - return -1; -+ } else if (rslt == 1) { -+ /* ok, move the lines */ -+ ioctl(fd, TIOCMGET, &reallines); -+ reallines &= ~lines; -+ ioctl(fd, TIOCMSET, &reallines); - } -- err = parse_argv(optioninfo, argc, argv); -- if(err) return 0; /* a message has been printed, but go on as good */ -- -- /* ok, move the lines */ -- ioctl(fd, TIOCMGET, &reallines); -- reallines &= ~lines; -- ioctl(fd, TIOCMSET, &reallines); - return 0; - } - -@@ -233,28 +134,12 @@ - /*========================================================================*/ - - #ifdef HAVE_LINUX_INPUT_H --static int M_evdev (Gpm_Event * state, unsigned char *data) --{ -- struct input_event thisevent; -- (void) memcpy (&thisevent, data, sizeof (struct input_event)); -- if (thisevent.type == EV_REL) { -- if (thisevent.code == REL_X) -- state->dx = (signed char) thisevent.value; -- else if (thisevent.code == REL_Y) -- state->dy = (signed char) thisevent.value; -- } else if (thisevent.type == EV_KEY) { -- switch(thisevent.code) { -- case BTN_LEFT: state->buttons ^= GPM_B_LEFT; break; -- case BTN_MIDDLE: state->buttons ^= GPM_B_MIDDLE; break; -- case BTN_RIGHT: state->buttons ^= GPM_B_RIGHT; break; -- case BTN_SIDE: state->buttons ^= GPM_B_MIDDLE; break; -- } -- } -- return 0; --} -+/* defined in evdev.c */ -+extern int M_evdev(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state); -+extern int I_evdev(struct micedev *dev, struct miceopt *opt, Gpm_Type *type); - #endif /* HAVE_LINUX_INPUT_H */ - --static int M_ms(Gpm_Event *state, unsigned char *data) -+static int M_ms(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* - * some devices report a change of middle-button state by -@@ -273,7 +158,7 @@ - return 0; - } - --static int M_ms_plus(Gpm_Event *state, unsigned char *data) -+static int M_ms_plus(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - static unsigned char prev=0; - -@@ -293,7 +178,7 @@ - return 0; - } - --static int M_ms_plus_lr(Gpm_Event *state, unsigned char *data) -+static int M_ms_plus_lr(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* - * Same as M_ms_plus but with an addition by Edmund GRIMLEY EVANS -@@ -329,19 +214,19 @@ - int SUMMA_BORDER=100; - int summamaxx,summamaxy; - char summaid=-1; --static int M_summa(Gpm_Event *state, unsigned char *data) -+static int M_summa(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - int x, y; - - x = ((data[2]<<7) | data[1])-SUMMA_BORDER; - if (x<0) x=0; - if (x>summamaxx) x=summamaxx; -- state->x = (x * win.ws_col / summamaxx); -+ state->x = (x * console.max_x / summamaxx); - realposx = (x * 16383 / summamaxx); - - y = ((data[4]<<7) | data[3])-SUMMA_BORDER; - if (y<0) y=0; if (y>summamaxy) y=summamaxy; -- state->y = 1 + y * (win.ws_row-1)/summamaxy; -+ state->y = 1 + y * (console.max_y-1)/summamaxy; - realposy = y * 16383 / summamaxy; - - state->buttons= -@@ -396,7 +281,7 @@ - - - /* 'Genitizer' (kw@dtek.chalmers.se 11/12/97) */ --static int M_geni(Gpm_Event *state, unsigned char *data) -+static int M_geni(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* this is a little confusing. If we use the stylus, we - * have three buttons (tip, lower, upper), and if -@@ -419,7 +304,7 @@ - - - /* m$ 'Intellimouse' (steveb 20/7/97) */ --static int M_ms3(Gpm_Event *state, unsigned char *data) -+static int M_ms3(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->wdx = state->wdy = 0; - state->buttons= ((data[0] & 0x20) >> 3) /* left */ -@@ -470,7 +355,7 @@ - } - - /* M_brw is a variant of m$ 'Intellimouse' the middle button is different */ --static int M_brw(Gpm_Event *state, unsigned char *data) -+static int M_brw(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= ((data[0] & 0x20) >> 3) /* left */ - | ((data[3] & 0x20) >> 4) /* middle */ -@@ -491,7 +376,7 @@ - return 0; - } - --static int M_bare(Gpm_Event *state, unsigned char *data) -+static int M_bare(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* a bare ms protocol */ - state->buttons= ((data[0] & 0x20) >> 3) | ((data[0] & 0x10) >> 4); -@@ -500,7 +385,7 @@ - return 0; - } - --static int M_sun(Gpm_Event *state, unsigned char *data) -+static int M_sun(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= (~data[0]) & 0x07; - state->dx= (signed char)(data[1]); -@@ -508,7 +393,7 @@ - return 0; - } - --static int M_msc(Gpm_Event *state, unsigned char *data) -+static int M_msc(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= (~data[0]) & 0x07; - state->dx= (signed char)(data[1]) + (signed char)(data[3]); -@@ -558,7 +443,7 @@ - - } - --static int M_logimsc(Gpm_Event *state, unsigned char *data) /* same as msc */ -+static int M_logimsc(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= (~data[0]) & 0x07; - state->dx= (signed char)(data[1]) + (signed char)(data[3]); -@@ -566,7 +451,7 @@ - return 0; - } - --static int M_mm(Gpm_Event *state, unsigned char *data) -+static int M_mm(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= data[0] & 0x07; - state->dx= (data[0] & 0x10) ? data[1] : - data[1]; -@@ -574,7 +459,7 @@ - return 0; - } - --static int M_logi(Gpm_Event *state, unsigned char *data) /* equal to mm */ -+static int M_logi(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= data[0] & 0x07; - state->dx= (data[0] & 0x10) ? data[1] : - data[1]; -@@ -582,7 +467,7 @@ - return 0; - } - --static int M_bm(Gpm_Event *state, unsigned char *data) /* equal to sun */ -+static int M_bm(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - state->buttons= (~data[0]) & 0x07; - state->dx= (signed char)data[1]; -@@ -590,7 +475,7 @@ - return 0; - } - --static int M_ps2(Gpm_Event *state, unsigned char *data) -+static int M_ps2(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - static int tap_active=0; /* there exist glidepoint ps2 mice */ - -@@ -599,8 +484,8 @@ - !!(data[0]&2) * GPM_B_RIGHT + - !!(data[0]&4) * GPM_B_MIDDLE; - -- if (data[0]==0 && opt_glidepoint_tap) /* by default this is false */ -- state->buttons = tap_active = opt_glidepoint_tap; -+ if (data[0]==0 && opt->glidepoint_tap) /* by default this is false */ -+ state->buttons = tap_active = opt->glidepoint_tap; - else if (tap_active) { - if (data[0]==8) - state->buttons = tap_active = 0; -@@ -623,10 +508,11 @@ - state->dy= -((data[0] & 0x20) ? data[2]-256 : data[2]); - else - state->dy = 0; -+ - return 0; - } - --static int M_imps2(Gpm_Event *state, unsigned char *data) -+static int M_imps2(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - - static int tap_active=0; /* there exist glidepoint ps2 mice */ -@@ -636,8 +522,8 @@ - state->buttons= ((data[0] & 1) << 2) /* left */ - | ((data[0] & 6) >> 1); /* middle and right */ - -- if (data[0]==0 && opt_glidepoint_tap) // by default this is false -- state->buttons = tap_active = opt_glidepoint_tap; -+ if (data[0]==0 && opt->glidepoint_tap) // by default this is false -+ state->buttons = tap_active = opt->glidepoint_tap; - else if (tap_active) { - if (data[0]==8) - state->buttons = tap_active = 0; -@@ -667,7 +553,7 @@ - - } - --static int M_netmouse(Gpm_Event *state, unsigned char *data) -+static int M_netmouse(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* Avoid these beasts if you can. They connect to normal PS/2 port, - * but their protocol is one byte longer... So if you have notebook -@@ -706,47 +592,45 @@ - } - - /* standard ps2 */ --static Gpm_Type *I_ps2(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+int I_ps2(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - static unsigned char s[] = { 246, 230, 244, 243, 100, 232, 3, }; -- write (fd, s, sizeof (s)); -+ write(dev->fd, s, sizeof (s)); - usleep (30000); -- tcflush (fd, TCIFLUSH); -- return type; -+ tcflush (dev->fd, TCIFLUSH); -+ return 0; - } - --static Gpm_Type *I_netmouse(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_netmouse(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - unsigned char magic[6] = { 0xe8, 0x03, 0xe6, 0xe6, 0xe6, 0xe9 }; - int i; - -- if (check_no_argv(argc, argv)) return NULL; -+ if (!check_no_options(type->name, opt->text, ',')) return -1; - for (i=0; i<6; i++) { - unsigned char c = 0; -- write( fd, magic+i, 1 ); -- read( fd, &c, 1 ); -+ write(dev->fd, magic+i, 1 ); -+ read(dev->fd, &c, 1 ); - if (c != 0xfa) { - gpm_report(GPM_PR_ERR,GPM_MESS_NETM_NO_ACK,c); -- return NULL; -+ return -1; - } - } - { - unsigned char rep[3] = { 0, 0, 0 }; -- read( fd, rep, 1 ); -- read( fd, rep+1, 1 ); -- read( fd, rep+2, 1 ); -+ read( dev->fd, rep, 1 ); -+ read( dev->fd, rep+1, 1 ); -+ read( dev->fd, rep+2, 1 ); - if (rep[0] || (rep[1] != 0x33) || (rep[2] != 0x55)) { - gpm_report(GPM_PR_ERR,GPM_MESS_NETM_INV_MAGIC, rep[0], rep[1], rep[2]); -- return NULL; -+ return -1; - } - } -- return type; -+ return 0; - } - - #define GPM_B_BOTH (GPM_B_LEFT|GPM_B_RIGHT) --static int M_mman(Gpm_Event *state, unsigned char *data) -+static int M_mman(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* - * the damned MouseMan has 3/4 bytes packets. The extra byte -@@ -784,7 +668,7 @@ - mytype->getextra=1; - } else { - if (b & 0x2) prev |= GPM_B_MIDDLE; -- if (b & 0x1) prev |= opt_glidepoint_tap; -+ if (b & 0x1) prev |= opt->glidepoint_tap; - } - } - state->buttons=prev; -@@ -828,7 +712,7 @@ - - #define IsA(m) ((WacomModell==(-1))? 0:!strcmp(#m,wcmodell[WacomModell].name)) - --static int M_wacom(Gpm_Event *state, unsigned char *data) -+static int M_wacom(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - static int ox=-1, oy; - int x, y; -@@ -878,8 +762,8 @@ - if (WacomAbsoluteWanted) { /* Absolute Mode */ - if (x>wmaxx) x=wmaxx; if (x<0) x=0; - if (y>wmaxy) y=wmaxy; if (y<0) y=0; -- state->x = (x * win.ws_col / wmaxx); -- state->y = (y * win.ws_row / wmaxy); -+ state->x = (x * console.max_x / wmaxx); -+ state->y = (y * console.max_y / wmaxy); - - realposx = (x / wmaxx); /* this two lines come from the summa driver. */ - realposy = (y / wmaxy); /* they seem to be buggy (always give zero). */ -@@ -889,8 +773,8 @@ - if( abs(x-ox)>(wmaxx/wcmodell[WacomModell].treshold) - || abs(y-oy)>(wmaxy/wcmodell[WacomModell].treshold) ) ox=x; oy=y; - -- state->dx= (x-ox) / (wmaxx / win.ws_col / wcmodell[WacomModell].treshold); -- state->dy= (y-oy) / (wmaxy / win.ws_row / wcmodell[WacomModell].treshold); -+ state->dx= (x-ox) / (wmaxx / console.max_x / wcmodell[WacomModell].treshold); -+ state->dy= (y-oy) / (wmaxy / console.max_y / wcmodell[WacomModell].treshold); - } - - ox=x; oy=y; -@@ -918,7 +802,7 @@ - #define CAL_Y_MAX 0xF40 - #define CAL_Y_SIZE (CAL_Y_MAX - CAL_Y_MIN) - --static int M_calus(Gpm_Event *state, unsigned char *data) -+static int M_calus(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - int x, y; - -@@ -932,12 +816,12 @@ - state->dx = 0; state->dy = 0; - - state->x = x < CAL_X_MIN ? 0 -- : x > CAL_X_MAX ? win.ws_col+1 -- : (long)(x-CAL_X_MIN) * (long)(win.ws_col-1) / CAL_X_SIZE+2; -+ : x > CAL_X_MAX ? console.max_x+1 -+ : (long)(x-CAL_X_MIN) * (long)(console.max_x-1) / CAL_X_SIZE+2; - -- state->y = y < CAL_Y_MIN ? win.ws_row + 1 -+ state->y = y < CAL_Y_MIN ? console.max_y + 1 - : y > CAL_Y_MAX ? 0 -- : (long)(CAL_Y_MAX-y) * (long)win.ws_row / CAL_Y_SIZE + 1; -+ : (long)(CAL_Y_MAX-y) * (long)console.max_y / CAL_Y_SIZE + 1; - - realposx = x < CAL_X_MIN ? 0 - : x > CAL_X_MAX ? 16384 -@@ -950,7 +834,7 @@ - return 0; - } - --static int M_calus_rel(Gpm_Event *state, unsigned char *data) -+static int M_calus_rel(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - static int ox=-1, oy; - int x, y; -@@ -984,7 +868,7 @@ - #define NCR_DELTA_X (NCR_RIGHT_X - NCR_LEFT_X) - #define NCR_DELTA_Y (NCR_TOP_Y - NCR_BOTTOM_Y) - --static int M_ncr(Gpm_Event *state, unsigned char *data) -+static int M_ncr(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - int x,y; - -@@ -1002,14 +886,14 @@ - state->x = x < NCR_LEFT_X - ? 0 - : x > NCR_RIGHT_X -- ? win.ws_col+1 -- : (long)(x-NCR_LEFT_X) * (long)(win.ws_col-1) / NCR_DELTA_X+2; -+ ? console.max_x+1 -+ : (long)(x-NCR_LEFT_X) * (long)(console.max_x-1) / NCR_DELTA_X+2; - - state->y = y < NCR_BOTTOM_Y -- ? win.ws_row + 1 -+ ? console.max_y + 1 - : y > NCR_TOP_Y - ? 0 -- : (long)(NCR_TOP_Y-y) * (long)win.ws_row / NCR_DELTA_Y + 1; -+ : (long)(NCR_TOP_Y-y) * (long)console.max_y / NCR_DELTA_Y + 1; - - realposx = x < NCR_LEFT_X - ? 0 -@@ -1026,7 +910,7 @@ - return 0; - } - --static int M_twid(Gpm_Event *state, unsigned char *data) -+static int M_twid(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - unsigned long message=0UL; int i,h,v; - static int lasth, lastv, lastkey, key, lock=0, autorepeat=0; -@@ -1144,7 +1028,7 @@ - #ifdef HAVE_LINUX_JOYSTICK_H - /* Joystick mouse emulation (David Given) */ - --static int M_js(Gpm_Event *state, unsigned char *data) -+static int M_js(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - struct JS_DATA_TYPE *jdata = (void*)data; - static int centerx = 0; -@@ -1193,21 +1077,21 @@ - #endif /* have joystick.h */ - - /* Synaptics TouchPad mouse emulation (Henry Davies) */ --static int M_synaptics_serial(Gpm_Event *state, unsigned char *data) -+static int M_synaptics_serial(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { -- syn_process_serial_data (state, data); -+ syn_process_serial_data(dev->fd, state, data); - return 0; - } - - - /* Synaptics TouchPad mouse emulation (Henry Davies) */ --static int M_synaptics_ps2(Gpm_Event *state, unsigned char *data) -+static int M_synaptics_ps2(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { -- syn_process_ps2_data(state, data); -+ syn_process_ps2_data(dev->fd, state, data); - return 0; - } - --static int M_mtouch(Gpm_Event *state, unsigned char *data) -+static int M_mtouch(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* - * This is a simple decoder for the MicroTouch touch screen -@@ -1219,8 +1103,8 @@ - static int upx, upy; /* keep track of last finger-up place */ - static struct timeval uptv, tv; /* time of last up, and down events */ - -- #define REAL_TO_XCELL(x) (x * win.ws_col / 0x3FFF) -- #define REAL_TO_YCELL(y) (y * win.ws_row / 0x3FFF) -+ #define REAL_TO_XCELL(x) (x * console.max_x / 0x3FFF) -+ #define REAL_TO_YCELL(y) (y * console.max_y / 0x3FFF) - - #define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL)) - #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \ -@@ -1245,7 +1129,7 @@ - - if (avgx < 0) { /* press event */ - GET_TIME(tv); -- if (DIF_TIME(uptv, tv) < opt_time) { -+ if (DIF_TIME(uptv, tv) < opt->time) { - /* count as button press placed at finger-up pixel */ - state->buttons = GPM_B_LEFT; - realposx = avgx = upx; state->x = REAL_TO_XCELL(realposx); -@@ -1287,7 +1171,7 @@ - static int gunze_calib[4]; /* x0,y0 x1,y1 (measured at 1/8 and 7/8) */ - static int gunze_debounce = 100; /* milliseconds: ignore shorter taps */ - --static int M_gunze(Gpm_Event *state, unsigned char *data) -+static int M_gunze(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - /* - * This generates button-1 events, by now. -@@ -1300,8 +1184,8 @@ - static struct timeval uptv, tv; /* time of last up, and down events */ - int timediff; - -- #define REAL_TO_XCELL(x) (x * win.ws_col / 0x3FFF) -- #define REAL_TO_YCELL(y) (y * win.ws_row / 0x3FFF) -+ #define REAL_TO_XCELL(x) (x * console.max_x / 0x3FFF) -+ #define REAL_TO_YCELL(y) (y * console.max_y / 0x3FFF) - - #define GET_TIME(tv) (gettimeofday(&tv, (struct timezone *)NULL)) - #define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \ -@@ -1350,7 +1234,7 @@ - GET_TIME(tv); - timediff = DIF_TIME(uptv, tv); - released = 0; -- if (timediff > gunze_debounce && timediff < opt_time) { -+ if (timediff > gunze_debounce && timediff < opt->time) { - /* count as button press placed at finger-up pixel */ - dragging = 1; - state->buttons = GPM_B_LEFT; -@@ -1399,7 +1283,7 @@ - /* corresponding correction of the protocol identification */ - /* mask) 2001/07/12 by Maciej W. Rozycki (macro@ds2.pg.gda.pl) */ - --static int M_vsxxx_aa(Gpm_Event *state, unsigned char *data) -+static int M_vsxxx_aa(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - - /* The mouse protocol is as follows: -@@ -1449,16 +1333,16 @@ - /* Genius Wizardpad tablet -- Matt Kimball (mkimball@xmission.com) */ - static int wizardpad_width = -1; - static int wizardpad_height = -1; --static int M_wp(Gpm_Event *state, unsigned char *data) -+static int M_wp(struct micedev *dev, struct miceopt *opt, unsigned char *data, Gpm_Event *state) - { - int x, y, pressure; - - x = ((data[4] & 0x1f) << 12) | ((data[3] & 0x3f) << 6) | (data[2] & 0x3f); -- state->x = x * win.ws_col / (wizardpad_width * 40); -+ state->x = x * console.max_x / (wizardpad_width * 40); - realposx = x * 16383 / (wizardpad_width * 40); - - y = ((data[7] & 0x1f) << 12) | ((data[6] & 0x3f) << 6) | (data[5] & 0x3f); -- state->y = win.ws_row - y * win.ws_row / (wizardpad_height * 40) - 1; -+ state->y = console.max_y - y * console.max_y / (wizardpad_height * 40) - 1; - realposy = 16383 - y * 16383 / (wizardpad_height * 40) - 1; - - pressure = ((data[9] & 0x0f) << 4) | (data[8] & 0x0f); -@@ -1475,11 +1359,9 @@ - /*========================================================================*/ - /* Then, mice should be initialized */ - --static Gpm_Type* I_empty(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_empty(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { -- if (check_no_argv(argc, argv)) return NULL; -- return type; -+ return check_no_options(type->name, opt->text, ',') ? 0 : -1; - } - - static int setspeed(int fd,int old,int new,int needtowrite,unsigned short flags) -@@ -1536,28 +1418,27 @@ - {125,"Q"}, - {1E9,"N"}, }; - --static Gpm_Type* I_serial(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_serial(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - int i; unsigned char c; - fd_set set; struct timeval timeout={0,0}; /* used when not debugging */ - - /* accept "-o dtr", "-o rts" and "-o both" */ -- if (option_modem_lines(fd, argc, argv)) return NULL; -+ if (option_modem_lines(dev->fd, type->name, opt->text)) return -1; - - #ifndef DEBUG - /* flush any pending input (thanks, Miguel) */ - FD_ZERO(&set); - for(i=0; /* always */ ; i++) { -- FD_SET(fd,&set); -- switch(select(fd+1,&set,(fd_set *)NULL,(fd_set *)NULL,&timeout/*zero*/)){ -- case 1: if (read(fd,&c,1)==0) break; -+ FD_SET(dev->fd,&set); -+ switch(select(dev->fd+1,&set,(fd_set *)NULL,(fd_set *)NULL,&timeout/*zero*/)){ -+ case 1: if (read(dev->fd,&c,1)==0) break; - case -1: continue; - } - break; - } - -- if (type->fun==M_logimsc) write(fd, "QU", 2 ); -+ if (type->fun==M_logimsc) write(dev->fd, "QU", 2 ); - - #if 0 /* Did this ever work? -- I don't know, but should we not remove it, - * if it doesn't work ??? -- Nico */ -@@ -1570,7 +1451,7 @@ - - /* Non mman: change from any available speed to the chosen one */ - for (i=9600; i>=1200; i/=2) -- setspeed(fd, i, opt_baud, (type->fun != M_mman) /* write */, flags); -+ setspeed(dev->fd, i, opt->baud, (type->fun != M_mman) /* write */, type->flags); - - /* - * reset the MouseMan/TrackMan to use the 3/4 byte protocol -@@ -1578,51 +1459,50 @@ - * Changed after 1.14; why not having "I_mman" now? - */ - if (type->fun==M_mman) { -- setspeed(fd, 1200, 1200, 0, flags); /* no write */ -- write(fd, "*X", 2); -- setspeed(fd, 1200, opt_baud, 0, flags); /* no write */ -- return type; -+ setspeed(dev->fd, 1200, 1200, 0, type->flags); /* no write */ -+ write(dev->fd, "*X", 2); -+ setspeed(dev->fd, 1200, opt->baud, 0, type->flags); /* no write */ -+ return 0; - } - - if(type->fun==M_geni) { - gpm_report(GPM_PR_INFO,GPM_MESS_INIT_GENI); -- setspeed(fd, 1200, 9600, 1, flags); /* write */ -- write(fd, ":" ,1); -- write(fd, "E" ,1); /* setup tablet. relative mode, resolution... */ -- write(fd, "@" ,1); /* setup tablet. relative mode, resolution... */ -+ setspeed(dev->fd, 1200, 9600, 1, type->flags); /* write */ -+ write(dev->fd, ":" ,1); -+ write(dev->fd, "E" ,1); /* setup tablet. relative mode, resolution... */ -+ write(dev->fd, "@" ,1); /* setup tablet. relative mode, resolution... */ - } - - if (type->fun==M_synaptics_serial) { - int packet_length; - -- setspeed (fd, 1200, 1200, 1, flags); -- packet_length = syn_serial_init (fd); -- setspeed (fd, 1200, 9600, 1, flags); -+ setspeed (dev->fd, 1200, 1200, 1, type->flags); -+ packet_length = syn_serial_init (dev->fd); -+ setspeed (dev->fd, 1200, 9600, 1, type->flags); - - type->packetlen = packet_length; - type->howmany = packet_length; - } - - if (type->fun==M_vsxxx_aa) { -- setspeed (fd, 4800, 4800, 0, flags); /* no write */ -- write(fd, "R", 1); /* initialize a mouse; without getting an "R" */ -+ setspeed (dev->fd, 4800, 4800, 0, type->flags); /* no write */ -+ write(dev->fd, "R", 1); /* initialize a mouse; without getting an "R" */ - /* a mouse does not send a bytestream */ - } - -- return type; -+ return 0; - } - --static Gpm_Type* I_logi(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_logi(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - int i; - struct stat buf; - int busmouse; - -- if (check_no_argv(argc, argv)) return NULL; -+ if (!check_no_options(type->name, opt->text, ',')) return -1; - - /* is this a serial- or a bus- mouse? */ -- if(fstat(fd,&buf)==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_FSTAT); -+ if(fstat(dev->fd,&buf)==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_FSTAT); - i=MAJOR(buf.st_rdev); - - /* I don't know why this is herein, but I remove it. I don't think a -@@ -1635,21 +1515,20 @@ - type->howmany = busmouse ? 3 : 1; - - /* change from any available speed to the chosen one */ -- for (i=9600; i>=1200; i/=2) setspeed(fd, i, opt_baud, 1 /* write */, flags); -+ for (i=9600; i>=1200; i/=2) setspeed(dev->fd, i, opt->baud, 1 /* write */, type->flags); - - /* this stuff is peculiar of logitech mice, also for the serial ones */ -- write(fd, "S", 1); -- setspeed(fd, opt_baud, opt_baud, 1 /* write */, -+ write(dev->fd, "S", 1); -+ setspeed(dev->fd, opt->baud, opt->baud, 1 /* write */, - CS8 |PARENB |PARODD |CREAD |CLOCAL |HUPCL); - - /* configure the sample rate */ -- for (i=0;opt_sample<=sampletab[i].sample;i++) ; -- write(fd,sampletab[i].code,1); -- return type; -+ for (i=0;opt->sample<=sampletab[i].sample;i++) ; -+ write(dev->fd,sampletab[i].code,1); -+ return 0; - } - --static Gpm_Type *I_wacom(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_wacom(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - /* wacom graphire tablet */ - #define UD_RESETBAUD "\r$" /* reset baud rate to default (wacom V) */ -@@ -1664,19 +1543,19 @@ - { - /* Init Wacom communication; this is modified from xf86Wacom.so module */ - /* Set speed to 19200 */ -- setspeed (fd, 1200, 19200, 0, B19200|CS8|CREAD|CLOCAL|HUPCL); -+ setspeed (dev->fd, 1200, 19200, 0, B19200|CS8|CREAD|CLOCAL|HUPCL); - /* Send Reset Baudrate Command */ -- write(fd, UD_RESETBAUD, strlen(UD_RESETBAUD)); -+ write(dev->fd, UD_RESETBAUD, strlen(UD_RESETBAUD)); - usleep(250000); - /* Send Reset Command */ -- write(fd, UD_RESET, strlen(UD_RESET)); -+ write(dev->fd, UD_RESET, strlen(UD_RESET)); - usleep(75000); - /* Set speed to 9600bps */ -- setspeed (fd, 1200, 9600, 0, B9600|CS8|CREAD|CLOCAL|HUPCL); -+ setspeed (dev->fd, 1200, 9600, 0, B9600|CS8|CREAD|CLOCAL|HUPCL); - /* Send Reset Command */ -- write(fd, UD_RESET, strlen(UD_RESET)); -+ write(dev->fd, UD_RESET, strlen(UD_RESET)); - usleep(250000); -- write(fd, UD_STOP, strlen(UD_STOP)); -+ write(dev->fd, UD_STOP, strlen(UD_STOP)); - usleep(100000); - } - -@@ -1690,7 +1569,7 @@ - struct timeval timeout; - fd_set readfds; - int err; -- FD_ZERO(&readfds); FD_SET(fd, &readfds); -+ FD_ZERO(&readfds); FD_SET(dev->fd, &readfds); - timeout.tv_sec = 0; timeout.tv_usec = 200000; - err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout); - return((err>0)?1:err); -@@ -1706,11 +1585,11 @@ - * Get Data to buffer until full or timeout. - * Give back 0 for timeout and !0 for buffer full - */ -- if (cmd) write(fd,cmd,strlen(cmd)); -+ if (cmd) write(dev->fd,cmd,strlen(cmd)); - memset(buffer,0,sizeof(buffer)); p=buffer; - err=wait_wacom(); - while (err != -1 && err && (p-buffer)<(sizeof(buffer)-1)) { -- p+= read(fd,p,(sizeof(buffer)-1)-(p-buffer)); -+ p+= read(dev->fd,p,(sizeof(buffer)-1)-(p-buffer)); - err=wait_wacom(); - } - /* return 1 for buffer full */ -@@ -1728,13 +1607,14 @@ - */ - - /* accept boolean options absolute and relative */ -- static argv_helper optioninfo[] = { -- {"absolute", ARGV_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: !0}, -- {"relative", ARGV_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: 0}, -- {"", ARGV_END} -+ static struct option_helper optioninfo[] = { -+ {"absolute", OPT_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: !0}, -+ {"relative", OPT_BOOL, u: {iptr: &WacomAbsoluteWanted}, value: 0}, -+ {"", OPT_END} - }; -- parse_argv(optioninfo, argc, argv); -- type->absolute = WacomAbsoluteWanted; -+ -+ parse_options(type->name, opt->text, ',', optioninfo); -+ opt->absolute = WacomAbsoluteWanted; - reset_wacom(); - - /* "Flush" input queque */ -@@ -1756,7 +1636,7 @@ - } - if(WacomModell >= (sizeof(wcmodell) / sizeof(struct WC_MODELL))) - WacomModell=-1; -- gpm_report(GPM_PR_INFO,GPM_MESS_WACOM_MOD, type->absolute? 'A':'R', -+ gpm_report(GPM_PR_INFO,GPM_MESS_WACOM_MOD, opt->absolute? 'A':'R', - (WacomModell==(-1))? "Unknown" : wcmodell[WacomModell].name, - buffer+2); - -@@ -1767,24 +1647,23 @@ - wmaxx = (wmaxx-wcmodell[WacomModell].border); - wmaxy = (wmaxy-wcmodell[WacomModell].border); - } -- write(fd,UD_SENDCOORDS,4); -+ write(dev->fd,UD_SENDCOORDS,4); - -- return type; -+ return 0; - } - --static Gpm_Type *I_pnp(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_pnp(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - struct termios tty; - - /* accept "-o dtr", "-o rts" and "-o both" */ -- if (option_modem_lines(fd, argc, argv)) return NULL; -+ if (option_modem_lines(dev->fd, type->name, opt->text)) return -1; - - /* - * Just put the device to 1200 baud. Thanks to Francois Chastrette - * for his great help and debugging with his own pnp device. - */ -- tcgetattr(fd, &tty); -+ tcgetattr(dev->fd, &tty); - - tty.c_iflag = IGNBRK | IGNPAR; - tty.c_oflag = 0; -@@ -1792,15 +1671,15 @@ - tty.c_line = 0; - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; -- tty.c_cflag = flags | B1200; -- tcsetattr(fd, TCSAFLUSH, &tty); /* set parameters */ -+ tty.c_cflag = type->flags | B1200; -+ tcsetattr(dev->fd, TCSAFLUSH, &tty); /* set parameters */ - - /* - * Don't read the silly initialization string. I don't want to see - * the vendor name: it is only propaganda, with no information. - */ - -- return type; -+ return 0; - } - - /* -@@ -1848,8 +1727,7 @@ - - /* intellimouse, ps2 version: Ben Pfaff and Colin Plumb */ - /* Autodetect: Steve Bennett */ --static Gpm_Type *I_imps2(int fd, unsigned short flags, struct Gpm_Type *type, -- int argc, char **argv) -+static int I_imps2(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - int id; - static unsigned char basic_init[] = { GPM_AUX_ENABLE_DEV, GPM_AUX_SET_SAMPLE, 100 }; -@@ -1857,36 +1735,36 @@ - static unsigned char ps2_init[] = { GPM_AUX_SET_SCALE11, GPM_AUX_ENABLE_DEV, GPM_AUX_SET_SAMPLE, 100, GPM_AUX_SET_RES, 3, }; - - /* Do a basic init in case the mouse is confused */ -- write_to_mouse(fd, basic_init, sizeof (basic_init)); -+ write_to_mouse(dev->fd, basic_init, sizeof (basic_init)); - - /* Now try again and make sure we have a PS/2 mouse */ -- if (write_to_mouse(fd, basic_init, sizeof (basic_init)) != 0) { -+ if (write_to_mouse(dev->fd, basic_init, sizeof (basic_init)) != 0) { - gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_INIT); -- return(NULL); -+ return -1; - } - - /* Try to switch to 3 button mode */ -- if (write_to_mouse(fd, imps2_init, sizeof (imps2_init)) != 0) { -+ if (write_to_mouse(dev->fd, imps2_init, sizeof (imps2_init)) != 0) { - gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_FAILED); -- return(NULL); -+ return -1; - } - - /* Read the mouse id */ -- id = read_mouse_id(fd); -+ id = read_mouse_id(dev->fd); - if (id == GPM_AUX_ID_ERROR) { - gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_MID_FAIL); - id = GPM_AUX_ID_PS2; - } - - /* And do the real initialisation */ -- if (write_to_mouse(fd, ps2_init, sizeof (ps2_init)) != 0) { -+ if (write_to_mouse(dev->fd, ps2_init, sizeof (ps2_init)) != 0) { - gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_SETUP_FAIL); - } - - if (id == GPM_AUX_ID_IMPS2) { - /* Really an intellipoint, so initialise 3 button mode (4 byte packets) */ - gpm_report(GPM_PR_INFO,GPM_MESS_IMPS2_AUTO); -- return type; -+ return 0; - } - if (id != GPM_AUX_ID_PS2) { - gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_BAD_ID, id); -@@ -1894,69 +1772,64 @@ - else gpm_report(GPM_PR_INFO,GPM_MESS_IMPS2_PS2); - - for (type=mice; type->fun; type++) -- if (strcmp(type->name, "ps2") == 0) return(type); -+ if (strcmp(type->name, "ps2") == 0) return 0; - - /* ps2 was not found!!! */ -- return(NULL); -+ return -1; - } - - /* - * This works with Dexxa Optical Mouse, but because in X same initstring - * is named ExplorerPS/2 so I named it in the same way. - */ --static Gpm_Type *I_exps2(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_exps2(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - static unsigned char s1[] = { 243, 200, 243, 200, 243, 80, }; - -- if (check_no_argv(argc, argv)) return NULL; -+ if (!check_no_options(type->name, opt->text, ',')) return -1; - -- write (fd, s1, sizeof (s1)); -+ write (dev->fd, s1, sizeof (s1)); - usleep (30000); -- tcflush (fd, TCIFLUSH); -- return type; -+ tcflush (dev->fd, TCIFLUSH); -+ return 0; - } - --static Gpm_Type *I_twid(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_twid(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - -- if (check_no_argv(argc, argv)) return NULL; -+ if (!check_no_options(type->name, opt->text, ',')) return -1; - -- if (twiddler_key_init() != 0) return NULL; -+ if (twiddler_key_init() != 0) return -1; - /* - * the twiddler is a serial mouse: just drop dtr - * and run at 2400 (unless specified differently) - */ -- if(opt_baud==DEF_BAUD) opt_baud = 2400; -- argv[1] = "dtr"; /* argv[1] is guaranteed to be NULL (this is dirty) */ -- return I_serial(fd, flags, type, argc, argv); -+ if (opt->baud == DEF_BAUD) opt->baud = 2400; -+ opt->text = "dtr"; -+ return I_serial(dev, opt, type); - } - --static Gpm_Type *I_calus(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_calus(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { -- if (check_no_argv(argc, argv)) return NULL; -+ if (!check_no_options(type->name, opt->text, ',')) return -1; - -- if (opt_baud == 1200) opt_baud=9600; /* default to 9600 */ -- return I_serial(fd, flags, type, argc, argv); -+ if (opt->baud == 1200) opt->baud = 9600; /* default to 9600 */ -+ return I_serial(dev, opt, type); - } - - /* synaptics touchpad, ps2 version: Henry Davies */ --static Gpm_Type *I_synps2(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_synps2(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { -- syn_ps2_init (fd); -- return type; -+ syn_ps2_init (dev->fd); -+ return 0; - } - - --static Gpm_Type *I_summa(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_summa(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - void resetsumma() - { -- write(fd,0,1); /* Reset */ -+ write(dev->fd,0,1); /* Reset */ - usleep(400000); /* wait */ - } - int waitsumma() -@@ -1964,7 +1837,7 @@ - struct timeval timeout; - fd_set readfds; - int err; -- FD_ZERO(&readfds); FD_SET(fd, &readfds); -+ FD_ZERO(&readfds); FD_SET(dev->fd, &readfds); - timeout.tv_sec = 0; timeout.tv_usec = 200000; - err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout); - return(err); -@@ -1987,34 +1860,34 @@ - char GEN_MODELL=0x7f; - - /* Set speed to 9600bps */ -- setspeed (fd, 1200, 9600, 1, B9600|CS8|CREAD|CLOCAL|HUPCL|PARENB|PARODD); -+ setspeed (dev->fd, 1200, 9600, 1, B9600|CS8|CREAD|CLOCAL|HUPCL|PARENB|PARODD); - resetsumma(); - -- write(fd, SS_PROMPT_MODE, strlen(SS_PROMPT_MODE)); -+ write(dev->fd, SS_PROMPT_MODE, strlen(SS_PROMPT_MODE)); - - if (strstr(type->name,"acecad")!=NULL) summaid=11; - - if (summaid<0) { /* Summagraphics test */ - /* read the Summa Firm-ID */ -- write(fd, SS_FIRMID, strlen(SS_FIRMID)); -+ write(dev->fd, SS_FIRMID, strlen(SS_FIRMID)); - err=waitsumma(); - if (!((err == -1) || (!err))) { - summaid=10; /* Original Summagraphics */ -- read(fd, buffer, 255); /* Read Firm-ID */ -+ read(dev->fd, buffer, 255); /* Read Firm-ID */ - } - } - - if (summaid<0) { /* Genius-test */ - resetsumma(); -- write(fd,GEN_MMSERIES,1); -- write(fd,&GEN_MODELL,1); /* Read modell */ -+ write(dev->fd,GEN_MMSERIES,1); -+ write(dev->fd,&GEN_MODELL,1); /* Read modell */ - err=waitsumma(); - if (!((err == -1) || (!err))) { /* read Genius-ID */ - err=waitsumma(); - if (!((err == -1) || (!err))) { - err=waitsumma(); - if (!((err == -1) || (!err))) { -- read(fd,&config,1); -+ read(dev->fd,&config,1); - summaid=(config[0] & 224) >> 5; /* genius tablet-id (0-7)*/ - } - } -@@ -2024,30 +1897,29 @@ - /* unknown tablet ?*/ - if ((summaid<0) || (summaid==11)) { - resetsumma(); -- write(fd, SS_BINARY_FMT SS_PROMPT_MODE, 3); -+ write(dev->fd, SS_BINARY_FMT SS_PROMPT_MODE, 3); - } - - /* read tablet size */ - err=waitsumma(); -- if (!((err == -1) || (!err))) read(fd,buffer,sizeof(buffer)); -- write(fd,SS_READCONFIG,1); -- read(fd,&config,5); -+ if (!((err == -1) || (!err))) read(dev->fd,buffer,sizeof(buffer)); -+ write(dev->fd,SS_READCONFIG,1); -+ read(dev->fd,&config,5); - summamaxx=(config[2]<<7 | config[1])-(SUMMA_BORDER*2); - summamaxy=(config[4]<<7 | config[3])-(SUMMA_BORDER*2); - -- write(fd,SS_ABSOLUTE SS_STREAM_MODE SS_UPPER_ORIGIN,3); -- if (summaid<0) write(fd,SS_500LPI SS_TABID0 SS_BINARY_FMT,4); -+ write(dev->fd,SS_ABSOLUTE SS_STREAM_MODE SS_UPPER_ORIGIN,3); -+ if (summaid<0) write(dev->fd,SS_500LPI SS_TABID0 SS_BINARY_FMT,4); - -- return type; -+ return 0; - } - --static Gpm_Type *I_mtouch(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_mtouch(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - struct termios tty; - - /* Set speed to 9600bps (copied from I_summa, above :) */ -- tcgetattr(fd, &tty); -+ tcgetattr(dev->fd, &tty); - tty.c_iflag = IGNBRK | IGNPAR; - tty.c_oflag = 0; - tty.c_lflag = 0; -@@ -2055,18 +1927,17 @@ - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; - tty.c_cflag = B9600|CS8|CREAD|CLOCAL|HUPCL; -- tcsetattr(fd, TCSAFLUSH, &tty); -+ tcsetattr(dev->fd, TCSAFLUSH, &tty); - - - /* Turn it to "format tablet" and "mode stream" */ -- write(fd,"\001MS\r\n\001FT\r\n",10); -+ write(dev->fd,"\001MS\r\n\001FT\r\n",10); - -- return type; -+ return 0; - } - - /* simple initialization for the gunze touchscreen */ --static Gpm_Type *I_gunze(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_gunze(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - struct termios tty; - FILE *f; -@@ -2075,29 +1946,29 @@ - - #define GUNZE_CALIBRATION_FILE SYSCONFDIR "/gpm-calibration" - /* accept a few options */ -- static argv_helper optioninfo[] = { -- {"smooth", ARGV_INT, u: {iptr: &gunze_avg}}, -- {"debounce", ARGV_INT, u: {iptr: &gunze_debounce}}, -+ static struct option_helper optioninfo[] = { -+ {"smooth", OPT_INT, u: {iptr: &gunze_avg}}, -+ {"debounce", OPT_INT, u: {iptr: &gunze_debounce}}, - /* FIXME: add corner tapping */ -- {"", ARGV_END} -+ {"", OPT_END} - }; -- parse_argv(optioninfo, argc, argv); -+ parse_options(type->name, opt->text, ',', optioninfo); - - /* check that the baud rate is valid */ -- if (opt_baud == DEF_BAUD) opt_baud = 19200; /* force 19200 as default */ -- if (opt_baud != 9600 && opt_baud != 19200) { -- gpm_report(GPM_PR_ERR,GPM_MESS_GUNZE_WRONG_BAUD,option.progname, argv[0]); -- opt_baud = 19200; -+ if (opt->baud == DEF_BAUD) opt->baud = 19200; /* force 19200 as default */ -+ if (opt->baud != 9600 && opt->baud != 19200) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_GUNZE_WRONG_BAUD, option.progname, type->name); -+ opt->baud = 19200; - } -- tcgetattr(fd, &tty); -+ tcgetattr(dev->fd, &tty); - tty.c_iflag = IGNBRK | IGNPAR; - tty.c_oflag = 0; - tty.c_lflag = 0; - tty.c_line = 0; - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; -- tty.c_cflag = (opt_baud == 9600 ? B9600 : B19200) |CS8|CREAD|CLOCAL|HUPCL; -- tcsetattr(fd, TCSAFLUSH, &tty); -+ tty.c_cflag = (opt->baud == 9600 ? B9600 : B19200) |CS8|CREAD|CLOCAL|HUPCL; -+ tcsetattr(dev->fd, TCSAFLUSH, &tty); - - /* FIXME: try to find some information about the device */ - -@@ -2120,19 +1991,18 @@ - gunze_calib[0] = gunze_calib[1] = 128; /* 1/8 */ - gunze_calib[2] = gunze_calib[3] = 896; /* 7/8 */ - } -- return type; -+ return 0; - } - - /* Genius Wizardpad tablet -- Matt Kimball (mkimball@xmission.com) */ --static Gpm_Type *I_wp(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) -+static int I_wp(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type) - { - struct termios tty; - char tablet_info[256]; - int count, pos, size; - - /* Set speed to 9600bps (copied from I_summa, above :) */ -- tcgetattr(fd, &tty); -+ tcgetattr(dev->fd, &tty); - tty.c_iflag = IGNBRK | IGNPAR; - tty.c_oflag = 0; - tty.c_lflag = 0; -@@ -2140,22 +2010,22 @@ - tty.c_cc[VTIME] = 0; - tty.c_cc[VMIN] = 1; - tty.c_cflag = B9600|CS8|CREAD|CLOCAL|HUPCL; -- tcsetattr(fd, TCSAFLUSH, &tty); -+ tcsetattr(dev->fd, TCSAFLUSH, &tty); - - /* Reset the tablet (':') and put it in remote mode ('S') so that - it isn't sending anything to us. */ -- write(fd, ":S", 2); -- tcsetattr(fd, TCSAFLUSH, &tty); -+ write(dev->fd, ":S", 2); -+ tcsetattr(dev->fd, TCSAFLUSH, &tty); - - /* Query the model of the tablet */ -- write(fd, "T", 1); -+ write(dev->fd, "T", 1); - sleep(1); -- count = read(fd, tablet_info, 255); -+ count = read(dev->fd, tablet_info, 255); - - /* The tablet information should start with "KW" followed by the rest of - the model number. If it isn't there, it probably isn't a WizardPad. */ -- if(count < 2) return NULL; -- if(tablet_info[0] != 'K' || tablet_info[1] != 'W') return NULL; -+ if(count < 2) return -1; -+ if(tablet_info[0] != 'K' || tablet_info[1] != 'W') return -1; - - /* Now, we want the width and height of the tablet. They should be - of the form "X###" and "Y###" where ### is the number of units of -@@ -2177,9 +2047,9 @@ - } - - /* Set the tablet to stream mode with 180 updates per sec. ('O') */ -- write(fd, "O", 1); -+ write(dev->fd, "O", 1); - -- return type; -+ return 0; - } - - /*========================================================================*/ -@@ -2241,7 +2111,7 @@ - {0x80, 0x80, 0x80, 0x00}, 6, 6, 0, 0, 0}, - #ifdef HAVE_LINUX_INPUT_H - {"evdev", "Linux Event Device", -- "", M_evdev, I_empty, STD_FLG, -+ "", M_evdev, I_evdev, STD_FLG, - {0x00, 0x00, 0x00, 0x00} , 16, 16, 0, 0, NULL}, - #endif /* HAVE_LINUX_INPUT_H */ - {"exps2", "IntelliMouse Explorer (ps2) - 3 buttons, wheel unused", -diff -urN gpm-1.20.1/src/optparser.c gpm/src/optparser.c ---- gpm-1.20.1/src/optparser.c 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/optparser.c 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,155 @@ -+/* -+ * optparser.c - GPM mouse options parser -+ * -+ * Copyright (C) 1993 Andrew Haylett <ajh@gec-mrc.co.uk> -+ * Copyright (C) 1994-2000 Alessandro Rubini <rubini@linux.it> -+ * Copyright (C) 1998,1999 Ian Zimmerman <itz@rahul.net> -+ * Copyright (C) 2001,2002 Nico Schottelius <nicos@pcsystems.de> -+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#include <stdio.h> -+#include <string.h> -+#include <stdlib.h> -+#include <ctype.h> -+ -+#include "headers/gpmInt.h" -+#include "headers/message.h" -+#include "headers/optparser.h" -+ -+int parse_options(const char *proto, const char *opts, char sep, struct option_helper *info) -+{ -+ int len, n, n_opts = 0, errors = 0; -+ long l; -+ struct option_helper *p; -+ char *s, *t, *str; -+ int base; /* for strtol */ -+ -+ for (p = info; p->type != OPT_END; p++) -+ p->present = 0; -+ -+ if (!opts) -+ return 0; -+ -+ if (!(str = strdup(opts))) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_ALLOC_FAILED); -+ -+ /* split input string */ -+ for (s = str, n = 1; sep && (s = strchr(s, sep)); s++, n++) -+ *s = '\0'; -+ -+ for (s = str; n; s += strlen(s) + 1, n--) { -+ if (strlen(s) == 0) -+ continue; -+ -+ for (p = info; p->type != OPT_END; p++) { -+ len = strlen(p->name); -+ if (!strncmp(p->name, s, len) && !isalnum(s[len])) -+ break; -+ } -+ if (p->type == OPT_END) { /* not found */ -+ gpm_report(GPM_PR_ERR, "%s: Uknown option \"%s\" for protocol \"%s\"\n", -+ option.progname, s, proto); -+ errors++; -+ continue; -+ } -+ if (p->present) { -+ gpm_report(GPM_PR_ERR, "%s: option \"%s\" has already been seen, ignored (\"%s\")\n", -+ option.progname, s, proto); -+ continue; -+ } -+ p->present = 1; -+ n_opts++; -+ /* Found. Look for trailing stuff, if any */ -+ s += len; -+ while (*s && isspace(*s)) s++; /* skip spaces */ -+ if (*s == '=') s++; /* skip equal */ -+ while (*s && isspace(*s)) s++; /* skip other spaces */ -+ -+ /* Now parse what s is */ -+ base = 0; -+ switch(p->type) { -+ case OPT_BOOL: -+ if (*s) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_OPTION_NO_ARG, option.progname, p->name, s); -+ errors++; -+ } -+ *(p->u.iptr) = p->value; -+ break; -+ -+ case OPT_DEC: -+ base = 10; /* and fall through */ -+ -+ case OPT_INT: -+ if (*s == '\0') { -+ gpm_report(GPM_PR_ERR, GPM_MESS_MISSING_ARG, option.progname, p->name); -+ } else { -+ l = strtol(s, &t, base); -+ if (*t) { -+ gpm_report(GPM_PR_ERR, GPM_MESS_INVALID_ARG, option.progname, s, p->name); -+ errors++; -+ break; -+ } -+ *(p->u.iptr) = (int)l; -+ } -+ break; -+ -+ case OPT_STRING: -+ if (*s == '\0') -+ gpm_report(GPM_PR_ERR, GPM_MESS_MISSING_ARG, option.progname, p->name); -+ else -+ *(p->u.sptr) = strdup(s); -+ break; -+ -+ case OPT_END: /* let's please "-Wall" */ -+ break; -+ } -+ } /* for i in argc */ -+ -+ free(str); -+ -+ if (errors) { -+ gpm_report(GPM_PR_ERR,GPM_MESS_CONT_WITH_ERR, option.progname); -+ return -errors; -+ } -+ return n_opts; -+} -+ -+int check_no_options(const char *proto, const char *opts, char sep) -+{ -+ static struct option_helper info[] = { -+ { "", OPT_END } -+ }; -+ -+ return parse_options(proto, opts, sep, info) == 0; -+} -+ -+int is_option_present(struct option_helper *info, const char *name) -+{ -+ struct option_helper *p; -+ int len; -+ -+ for (p = info; p->type != OPT_END; p++) { -+ len = strlen(p->name); -+ if (!strncmp(p->name, name, len) && !isalnum(name[len])) -+ return p->present; -+ } -+ -+ gpm_report(GPM_PR_ERR, "%s: Uknown option \"%s\"\n", option.progname, name); -+ return 0; -+} -+ -diff -urN gpm-1.20.1/src/prog/mouse-test.c gpm/src/prog/mouse-test.c ---- gpm-1.20.1/src/prog/mouse-test.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/prog/mouse-test.c 2003-10-02 01:22:42.000000000 -0500 -@@ -50,22 +50,9 @@ - #define max(a,b) ((a)>(b)?(a):(b)) - #endif - -- --/* this material is needed to pass options to mice.c */ --struct mouse_features mymouse = { -- DEF_TYPE, DEF_DEV, DEF_SEQUENCE, -- DEF_BAUD, DEF_SAMPLE, DEF_DELTA, DEF_ACCEL, DEF_SCALE, DEF_SCALE /*scaley*/, -- DEF_TIME, DEF_CLUSTER, DEF_THREE, DEF_GLIDEPOINT_TAP, -- (char *)NULL /* extra */, -- (Gpm_Type *)NULL, -- -1 /* fd */ --}; -- - /* and this is a workaroud */ - struct winsize win; - --struct mouse_features *which_mouse=&mymouse; -- - char *progname; - char *consolename; - int devcount=0; -@@ -78,9 +65,9 @@ - - struct device { - char *name; -- int fd; -+ struct micedev mdev; - struct device *next; --}; -+} *devlist; - - static int message(void) - { -@@ -148,47 +135,48 @@ - /*----------------------------------------------------------------------------- - Place the description here. - -----------------------------------------------------------------------------*/ --struct device **gpm_makedev(struct device **current, char *name) -+void gpm_makedev(char *name) - { -- int fd; int modes; -+ struct device *dev; -+ int fd; -+ int modes; -+ - if ((fd=open(name,O_RDWR|O_NONBLOCK))==-1) { - perror(name); -- return current; -- } -- modes = fcntl(fd, F_GETFL); -- if (0 > fcntl(fd, F_SETFL, modes & ~O_NONBLOCK)) { -- close(fd); -- perror(name); -- return current; -+ } else { -+ modes = fcntl(fd, F_GETFL); -+ if (0 > fcntl(fd, F_SETFL, modes & ~O_NONBLOCK)) { -+ close(fd); -+ perror(name); -+ } else { -+ dev = malloc(sizeof(struct device)); -+ if (!dev) gpm_report(GPM_PR_OOPS,"malloc()"); -+ dev->name=strdup(name); -+ if (!dev->name) gpm_report(GPM_PR_OOPS,"malloc()"); -+ dev->mdev.fd=fd; -+ dev->mdev.private = NULL; -+ dev->next=devlist; -+ devlist = dev; -+ devcount++; -+ } - } -- -- *current=malloc(sizeof(struct device)); -- if (!*current) gpm_report(GPM_PR_OOPS,"malloc()"); -- (*current)->name=strdup(name); -- if (!(*current)->name) gpm_report(GPM_PR_OOPS,"malloc()"); -- (*current)->fd=fd; -- (*current)->next=NULL; -- devcount++; -- return &((*current)->next); - } - --Gpm_Type *(*I_serial)(int fd, unsigned short flags, struct Gpm_Type *type, -- int argc, char **argv); -+int (*I_serial)(struct micedev *dev, struct miceopt *opt, struct Gpm_Type *type); - - - /*----------------------------------------------------------------------------- - Place the description here. - -----------------------------------------------------------------------------*/ --int mousereopen(int oldfd, char *name, Gpm_Type *type) -+int mousereopen(struct micedev *dev, char *name, Gpm_Type *type, struct miceopt *opts) - { -- int fd; - if (!type) type=mice+1; /* ms */ -- close(oldfd); -+ close(dev->fd); - usleep(100000); -- fd=open(name,O_RDWR); -- if (fd < 0) gpm_report(GPM_PR_OOPS,name); -- (*I_serial)(fd,type->flags,type,1,&type->name); /* ms initialization */ -- return fd; -+ dev->fd=open(name,O_RDWR); -+ if (dev->fd < 0) gpm_report(GPM_PR_OOPS,name); -+ I_serial(dev, opts, type); /* ms initialization */ -+ return dev->fd; - } - - int noneofthem(void) -@@ -281,10 +269,9 @@ - { - struct item *list=NULL; - struct item **nextitem; -- struct device *devlist=NULL; -- struct device **nextdev; -+ struct device *nextdev; - Gpm_Type *cursor; -- int i, mousefd; -+ int i; - char *mousename; - #define BUFLEN 512 - char buf[BUFLEN]; -@@ -294,6 +281,9 @@ - int trial, readamount,packetsize,got; - int baudtab[4]={1200,9600,4800,2400}; - #define BAUD(i) (baudtab[(i)%4]) -+ struct miceopt opt = {0}; -+ struct micedev mdev = {0}; -+ - consolename = Gpm_get_console(); - - if (!isatty(fileno(stdin))) { -@@ -306,8 +296,8 @@ - - /* init the list of possible devices */ - -- for (nextdev=&devlist, i=1; i<argc; i++) -- nextdev=gpm_makedev(nextdev,argv[i]); -+ for (i=1; i<argc; i++) -+ gpm_makedev(argv[i]); - - if (argc==1) { /* no cmdline, get all devices */ - FILE *f; -@@ -320,7 +310,7 @@ - if (!f) gpm_report(GPM_PR_OOPS,"popen()"); - while (fgets(s,64,f)) { - s[strlen(s)-1]='\0'; /* trim '\n' */ -- nextdev=gpm_makedev(nextdev,s); -+ gpm_makedev(s); - } - pclose(f); - } -@@ -345,19 +335,18 @@ - - /* BUG */ /* Logitech initialization is not performed */ - -- opt_baud=BAUD(trial); -- printf("\r\nTrying with %i baud\r\n",opt_baud); -+ opt.baud=BAUD(trial); -+ printf("\r\nTrying with %i baud\r\n",opt.baud); - trial++; - - FD_ZERO(&devSet); FD_ZERO(&gotSet); - FD_SET(fileno(stdin),&devSet); maxfd=fileno(stdin); - printf("\r\n The possible device nodes are:\r\n"); -- for (nextdev=&devlist; *nextdev; nextdev=&((*nextdev)->next)) { -- printf("\t%s\r\n", (*nextdev)->name); -- FD_SET((*nextdev)->fd,&devSet); -- maxfd=max((*nextdev)->fd,maxfd); -- (*I_serial)((*nextdev)->fd,(mice+1)->flags,mice+1, -- 1, &(mice+1)->name); /* try ms mode */ -+ for (nextdev=devlist; nextdev; nextdev=nextdev->next) { -+ printf("\t%s\r\n", nextdev->name); -+ FD_SET(nextdev->mdev.fd, &devSet); -+ maxfd=max(nextdev->mdev.fd,maxfd); -+ I_serial(&nextdev->mdev, &opt, mice+1); /* try ms mode */ - } - - savSet=devSet; -@@ -379,43 +368,43 @@ - getchar(); - break; - } -- for (nextdev=&devlist; *nextdev; nextdev=&((*nextdev)->next)) -- if (FD_ISSET((*nextdev)->fd,&devSet)) { -+ for (nextdev=devlist; nextdev; nextdev=nextdev->next) -+ if (FD_ISSET(nextdev->mdev.fd,&devSet)) { - gotthem++; -- FD_CLR((*nextdev)->fd,&savSet); -- FD_SET((*nextdev)->fd,&gotSet); -+ FD_CLR(nextdev->mdev.fd,&savSet); -+ FD_SET(nextdev->mdev.fd,&gotSet); - } - } -- if (gotthem) for (nextdev=&devlist; *nextdev; /* nothing */ ) { -- cur=*nextdev; -- if (!FD_ISSET(cur->fd,&gotSet)) { -+ if (gotthem) for (nextdev=devlist; nextdev; /* nothing */ ) { -+ cur=nextdev; -+ if (!FD_ISSET(cur->mdev.fd,&gotSet)) { - printf("removing \"%s\" from the list\r\n",cur->name); -- *nextdev=cur->next; -- close(cur->fd); -+ nextdev=cur->next; -+ close(cur->mdev.fd); - free(cur->name); - free(cur); - devcount--; - } else { -- read(cur->fd,buf,80); /* flush */ -- nextdev=&(cur->next); /* follow list */ -+ read(cur->mdev.fd,buf,80); /* flush */ -+ nextdev=cur->next; /* follow list */ - } - } - - } /* devcount>1 */ - -- mousefd=devlist->fd; -+ mdev=devlist->mdev; - mousename=devlist->name; - free(devlist); - printf("\r\nOk, so your mouse device is \"%s\"\r\n",mousename); - - /* now close and reopen it, complete with initialization */ -- opt_baud=BAUD(0); -- mousefd=mousereopen(mousefd,mousename,NULL); -- -+ opt.baud=BAUD(0); -+ mousereopen(&mdev, mousename, NULL,&opt); -+ - FD_ZERO(&checkSet); -- FD_SET(mousefd,&checkSet); -+ FD_SET(mdev.fd,&checkSet); - FD_SET(fileno(stdin),&checkSet); -- maxfd=max(mousefd,fileno(stdin)); -+ maxfd=max(mdev.fd, fileno(stdin)); - - /*====================================== Identify mouse type */ - -@@ -440,7 +429,7 @@ - printf("\r\nNow please press and release your left mouse button,\r\n" - "one time only\r\n\r\n"); - -- i=read(mousefd,buf,1); -+ i=read(mdev.fd, buf, 1); - if (i==-1 && errno==EINVAL) - readamount=3; - else -@@ -466,7 +455,7 @@ - else - nextitem=&(cur->next); - } -- read(mousefd,buf,BUFLEN); /* flush */ -+ read(mdev.fd, buf, BUFLEN); /* flush */ - - /*====================================== Packet size - second step */ - -@@ -484,12 +473,12 @@ - while (packetsize==1) { - int success3=0,success5=0; - -- opt_baud=BAUD(trial); -- printf("\tBaud rate is %i\r\n",opt_baud); -- mousefd=mousereopen(mousefd,mousename,NULL); -+ opt.baud=BAUD(trial); -+ printf("\tBaud rate is %i\r\n",opt.baud); -+ mousereopen(&mdev, mousename,NULL, &opt); - - printf("\r\n==> Detecting the packet size\r\n"); -- got=eventlist(mousefd,buf,BUFLEN,GPM_B_LEFT,readamount); -+ got=eventlist(mdev.fd,buf,BUFLEN,GPM_B_LEFT,readamount); - - /* try three -- look at repeating arrays of 6 bytes */ - for (i=0;i<got-12;i++) -@@ -512,8 +501,7 @@ - trial++; - } - --/*====================================== Use that info to discard protocols */ -- -+/*====================================== Use that info to discard protocols */ - for (nextitem=&list; *nextitem; /* nothing */) { - struct item *cur=*nextitem; - int packetheads=0; -@@ -530,7 +518,7 @@ - if ( ((buf[i] &(cur->this->proto)[0]) == (cur->this->proto)[1]) - && ((buf[i+1]&(cur->this->proto)[2]) == (cur->this->proto)[3]) ) { - packetheads++; -- if ((*(cur->this->fun))(&event,buf+i)==-1) { -+ if ((*(cur->this->fun))(&mdev, &opt, buf+i, &event)==-1) { - packetheads--; - continue; - } -@@ -594,7 +582,7 @@ - * First trial: remove the "-t ms" extension if spurious buttons come in - */ - -- got=eventlist(mousefd,buf,BUFLEN,0,readamount); -+ got=eventlist(mdev.fd,buf,BUFLEN,0,readamount); - pending=0; - for (nextitem=&list; *nextitem; /* nothing */) { - struct item *cur=*nextitem; -@@ -604,7 +592,7 @@ - for (i=0;i<got;i++) { - if ( ((buf[i] &(cur->this->proto)[0]) == (cur->this->proto)[1]) - && ((buf[i+1]&(cur->this->proto)[2]) == (cur->this->proto)[3]) ) { -- if ((*(cur->this->fun))(&event,buf+i)==-1) continue; -+ if ((*(cur->this->fun))(&mdev, &opt, buf+i, &event)==-1) continue; - i+=packetsize-1; - if (event.buttons) pending--; - } -@@ -624,8 +612,8 @@ - */ - - printf("\r\n==> Looking for '-t mman'and enhanced ms\r\n"); -- mousefd=mousereopen(mousefd,mousename, mice /* mman */); -- got=eventlist(mousefd,buf,BUFLEN,GPM_B_MIDDLE,readamount); -+ mousereopen(&mdev, mousename, mice /* mman */, &opt); -+ got=eventlist(mdev.fd, buf, BUFLEN, GPM_B_MIDDLE, readamount); - - /* if it uses the 4-byte protocol, find it in a rude way */ - for (pending=0,i=0;i<got-16;i++) -@@ -646,7 +634,7 @@ - for (i=0;i<got;i++) { - if ( ((buf[i] &(cur->this->proto)[0]) == (cur->this->proto)[1]) - && ((buf[i+1]&(cur->this->proto)[2]) == (cur->this->proto)[3]) ) { -- if ((*(cur->this->fun))(&event,buf+i)==-1) continue; -+ if ((*(cur->this->fun))(&mdev,&opt,buf+i,&event)==-1) continue; - i+=packetsize-1; - if (event.buttons && event.buttons!=GPM_B_MIDDLE) pending--; - if (event.buttons==GPM_B_MIDDLE) pending++; -@@ -677,16 +665,16 @@ - char *Xtognames[3]={"'ClearDTR' and 'ClearRTS'","'ClearDTR'","'ClearRTS'"}; - int alllines,lines, index; - -- ioctl(mousefd, TIOCMGET, &alllines); -+ ioctl(mdev.fd, TIOCMGET, &alllines); - - printf("\r\nSome mice change protocol to three-buttons-aware if some\r\n" - "\r\ncontrol lines are toggled after opening\r\n"); - for (index=0;index<3;index++) { -- mousereopen(mousefd,mousename,NULL); -+ mousereopen(&mdev, mousename, NULL, &opt); - lines = alllines & ~toggle[index]; -- ioctl(mousefd, TIOCMSET, &lines); -+ ioctl(mdev.fd, TIOCMSET, &lines); - printf("\r\n==> Trying with '-o %s'\r\n",tognames[index]); -- got=eventlist(mousefd,buf,BUFLEN,GPM_B_MIDDLE,readamount); -+ got=eventlist(mdev.fd, buf, BUFLEN, GPM_B_MIDDLE, readamount); - - /* if it uses the 5-byte protocol, find it in a rude way */ - for (pending=0,i=0;i<got-20;i++) -@@ -717,7 +705,7 @@ - - getchar(); - -- got=eventlist(mousefd,buf,BUFLEN,GPM_B_MIDDLE,readamount); -+ got=eventlist(mdev.fd,buf,BUFLEN,GPM_B_MIDDLE,readamount); - - /* if it uses the 5-byte protocol, find it in a rude way */ - for (pending=0,i=0;i<got-20;i++) -diff -urN gpm-1.20.1/src/report.c gpm/src/report.c ---- gpm-1.20.1/src/report.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/report.c 2003-10-02 01:22:42.000000000 -0500 -@@ -31,6 +31,7 @@ - - #include "headers/gpmInt.h" - #include "headers/message.h" -+#include "headers/console.h" - - /* - * gpm_report -@@ -70,7 +71,7 @@ - - void gpm_report(int line, char *file, int stat, char *text, ... ) - { -- FILE *console = NULL; -+ FILE *f = NULL; - va_list ap; - - va_start(ap,text); -@@ -138,11 +139,11 @@ - syslog(LOG_DAEMON | LOG_WARNING, GPM_STRING_WARN); - vsyslog(LOG_DAEMON | LOG_WARNING, text, ap); - #endif -- if((console = fopen(GPM_SYS_CONSOLE,"a")) != NULL) { -- fprintf(console,GPM_STRING_WARN); -- vfprintf(console,text,ap); -- fprintf(console,"\n"); -- fclose(console); -+ if ((f = fopen(GPM_SYS_CONSOLE, "a")) != NULL) { -+ fprintf(f, GPM_STRING_WARN); -+ vfprintf(f, text, ap); -+ fprintf(f, "\n"); -+ fclose(f); - } - break; - -@@ -151,18 +152,18 @@ - syslog(LOG_DAEMON | LOG_ERR, GPM_STRING_ERR); - vsyslog(LOG_DAEMON | LOG_ERR, text, ap); - #endif -- if((console = fopen(GPM_SYS_CONSOLE,"a")) != NULL) { -- fprintf(console,GPM_STRING_ERR); -- vfprintf(console,text,ap); -- fprintf(console,"\n"); -- fclose(console); -+ if ((f = fopen(GPM_SYS_CONSOLE, "a")) != NULL) { -+ fprintf(f, GPM_STRING_ERR); -+ vfprintf(f, text, ap); -+ fprintf(f, "\n"); -+ fclose(f); - } - -- if((console = fopen(option.consolename,"a")) != NULL) { -- fprintf(console,GPM_STRING_ERR); -- vfprintf(console,text,ap); -- fprintf(console,"\n"); -- fclose(console); -+ if ((f = fopen(console.device, "a")) != NULL) { -+ fprintf(f, GPM_STRING_ERR); -+ vfprintf(f, text, ap); -+ fprintf(f, "\n"); -+ fclose(f); - } - break; - -@@ -184,24 +185,24 @@ - case GPM_RUN_DEBUG: - switch(stat) { - case GPM_STAT_INFO: -- console = stdout; -- fprintf(console,GPM_STRING_INFO); break; -+ f = stdout; -+ fprintf(f, GPM_STRING_INFO); break; - case GPM_STAT_WARN: -- console = stderr; -- fprintf(console,GPM_STRING_WARN); break; -+ f = stderr; -+ fprintf(f, GPM_STRING_WARN); break; - case GPM_STAT_ERR: -- console = stderr; -- fprintf(console,GPM_STRING_ERR); break; -+ f = stderr; -+ fprintf(f, GPM_STRING_ERR); break; - case GPM_STAT_DEBUG: -- console = stderr; -- fprintf(console,GPM_STRING_DEBUG); break; -+ f = stderr; -+ fprintf(f, GPM_STRING_DEBUG); break; - case GPM_STAT_OOPS: -- console = stderr; -- fprintf(console,GPM_STRING_OOPS); break; -+ f = stderr; -+ fprintf(f, GPM_STRING_OOPS); break; - } - -- vfprintf(console,text,ap); -- fprintf(console,"\n"); -+ vfprintf(f, text, ap); -+ fprintf(f, "\n"); - - if(stat == GPM_STAT_OOPS) exit(1); - -diff -urN gpm-1.20.1/src/selection.c gpm/src/selection.c ---- gpm-1.20.1/src/selection.c 1969-12-31 19:00:00.000000000 -0500 -+++ gpm/src/selection.c 2003-10-02 01:22:42.000000000 -0500 -@@ -0,0 +1,156 @@ -+/* -+ * console.c - GPM console and selection/paste handling -+ * -+ * Copyright (C) 1993 Andreq Haylett <ajh@gec-mrc.co.uk> -+ * Copyright (C) 1994-1999 Alessandro Rubini <rubini@linux.it> -+ * Copyright (C) 1998 Ian Zimmerman <itz@rahul.net> -+ * Copyright (c) 2001,2002 Nico Schottelius <nico@schottelius.org> -+ * Copyright (c) 2003 Dmitry Torokhov <dtor@mail.ru> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ ********/ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> /* strerror(); ?!? */ -+#include <errno.h> -+#include <unistd.h> /* select(); */ -+#include <time.h> /* time() */ -+#include <sys/fcntl.h> /* O_RDONLY */ -+#include <sys/stat.h> /* mkdir() */ -+#include <asm/types.h> /* __u32 */ -+ -+#include <linux/vt.h> /* VT_GETSTATE */ -+#include <sys/kd.h> /* KDGETMODE */ -+#include <termios.h> /* winsize */ -+ -+#include "headers/gpmInt.h" -+#include "headers/message.h" -+#include "headers/console.h" -+#include "headers/selection.h" -+ -+struct sel_options sel_opts = { 0, 0, DEF_PTRDRAG }; -+static time_t last_selection_time; -+ -+/*-------------------------------------------------------------------*/ -+static void selection_copy(int x1, int y1, int x2, int y2, int mode) -+{ -+/* -+ * The approach in "selection" causes a bus error when run under SunOS 4.1 -+ * due to alignment problems... -+ */ -+ unsigned char buf[6 * sizeof(short)]; -+ unsigned short *arg = (unsigned short *)buf + 1; -+ int fd; -+ -+ buf[sizeof(short) - 1] = 2; /* set selection */ -+ -+ arg[0] = (unsigned short)x1; -+ arg[1] = (unsigned short)y1; -+ arg[2] = (unsigned short)x2; -+ arg[3] = (unsigned short)y2; -+ arg[4] = (unsigned short)mode; -+ -+ if ((fd = open_console(O_WRONLY)) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN_CON); -+ -+ gpm_report(GPM_PR_DEBUG, "ctl %i, mode %i", (int)*buf, arg[4]); -+ if (ioctl(fd, TIOCLINUX, buf + sizeof(short) - 1) < 0) -+ gpm_report(GPM_PR_OOPS,GPM_MESS_IOCTL_TIOCLINUX); -+ close(fd); -+ -+ if (mode < 3) { -+ sel_opts.aged = 0; -+ last_selection_time = time(0); -+ } -+} -+ -+/*-------------------------------------------------------------------*/ -+static void selection_paste(void) -+{ -+ char c = 3; -+ int fd; -+ -+ if (!sel_opts.aged && -+ sel_opts.age_limit != 0 && -+ last_selection_time + sel_opts.age_limit < time(0)) { -+ sel_opts.aged = 1; -+ } -+ -+ if (sel_opts.aged) { -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_SKIP_PASTE); -+ } else { -+ fd = open_console(O_WRONLY); -+ if (ioctl(fd, TIOCLINUX, &c) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_IOCTL_TIOCLINUX); -+ close(fd); -+ } -+} -+ -+/*-------------------------------------------------------------------*/ -+void do_selection(Gpm_Event *event, int three_button_mode) -+{ -+ static int x1 = 1, y1 = 1; -+ int x2, y2; -+ -+ x2 = event->x; y2 = event->y; -+ switch(GPM_BARE_EVENTS(event->type)) { -+ case GPM_MOVE: -+ if (x2 < 1) x2++; else if (x2 > console.max_x) x2--; -+ if (y2 < 1) y2++; else if (y2 > console.max_y) y2--; -+ selection_copy(x2, y2, x2, y2, 3); /* just highlight pointer */ -+ break; -+ -+ case GPM_DRAG: -+ if (event->buttons == GPM_B_LEFT) { -+ switch(event->margin) { /* fix margins */ -+ case GPM_TOP: x2 = 1; y2++; break; -+ case GPM_BOT: x2 = console.max_x; y2--; break; -+ case GPM_RGT: x2--; break; -+ case GPM_LFT: y2 <= y1 ? x2++ : (x2 = console.max_x, y2--); break; -+ default: break; -+ } -+ selection_copy(x1, y1, x2, y2, event->clicks); -+ if (event->clicks >= sel_opts.ptrdrag && !event->margin) /* pointer */ -+ selection_copy(x2, y2, x2, y2, 3); -+ } /* if */ -+ break; -+ -+ case GPM_DOWN: -+ switch (event->buttons) { -+ case GPM_B_LEFT: -+ x1 = x2; y1 = y2; -+ selection_copy(x1, y1, x2, y2, event->clicks); /* start selection */ -+ break; -+ -+ case GPM_B_MIDDLE: -+ selection_paste(); -+ break; -+ -+ case GPM_B_RIGHT: -+ if (three_button_mode == 1) -+ selection_copy(x1, y1, x2, y2, event->clicks); -+ else -+ selection_paste(); -+ break; -+ } -+ } /* switch above */ -+} -+ -+/*-------------------------------------------------------------------*/ -+void selection_disable_paste(void) -+{ -+ sel_opts.aged = 1; -+} -diff -urN gpm-1.20.1/src/server_tools.c gpm/src/server_tools.c ---- gpm-1.20.1/src/server_tools.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/server_tools.c 2003-10-02 01:22:42.000000000 -0500 -@@ -21,151 +21,80 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - ********/ - -+#include <string.h> -+#include <stdlib.h> /* malloc() */ -+#include <sys/fcntl.h> -+ - #include "headers/gpmInt.h" - #include "headers/message.h" - --#include <stdlib.h> /* malloc() */ -+struct micetab *micelist; - --/* DESCR: add this to the list of mice. initialization follows later */ --/* RETURN: - */ -+/* DESCR: allocate a new mouse and to the list of mice. initialization follows later */ -+/* RETURN: new mouse structure */ - /* COMMENT: does error handling and exiting itself */ --void add_mouse(int type, char *value) -+struct micetab *add_mouse(void) - { -- struct micetab *tmp = option.micelist; -+ struct micetab *mouse; - -- /* PREAMBLE for all work: */ -- /* -m /dev/misc/psaux -t ps2 [ -o options ] */ -+ gpm_report(GPM_PR_DEBUG, "adding mouse device"); -+ if (!(mouse = malloc(sizeof(struct micetab)))) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_NO_MEM); -+ -+ memset(mouse, 0, sizeof(struct micetab)); -+ -+ mouse->dev.timeout = -1; -+ -+ mouse->options.sequence = NULL; -+ mouse->options.sample = DEF_SAMPLE; -+ mouse->options.delta = DEF_DELTA; -+ mouse->options.accel = DEF_ACCEL; -+ mouse->options.scalex = DEF_SCALE; -+ mouse->options.scaley = DEF_SCALE; -+ mouse->options.time = DEF_TIME; -+ mouse->options.cluster = DEF_CLUSTER; -+ mouse->options.three_button = DEF_THREE; -+ mouse->options.glidepoint_tap = DEF_GLIDEPOINT_TAP; -+ mouse->options.text = NULL; - -- switch(type) { -+ mouse->next = micelist; -+ micelist = mouse; - -- /*---------------------------------------------------------------------*/ -- /********************** -m mousedevice *********************************/ -- /*---------------------------------------------------------------------*/ -- -- case GPM_ADD_DEVICE: -- -- /* first invocation */ -- if(option.micelist == NULL) { -- gpm_report(GPM_PR_DEBUG,"adding mouse device: %s",value); -- option.micelist = (struct micetab *) malloc(sizeof(struct micetab)); -- if(!option.micelist) gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -- option.micelist->next = NULL; -- option.micelist->device = value; -- option.micelist->protocol = NULL; -- option.micelist->options = NULL; -- return; -- } -- -- /* find actual mouse */ -- while(tmp->device != NULL && tmp->protocol != NULL && tmp->next !=NULL) -- tmp = tmp->next; -- -- gpm_report(GPM_PR_DEBUG,"finished searching"); -- -- /* found end of micelist, add new mouse */ -- if(tmp->next == NULL && tmp->protocol != NULL) { -- gpm_report(GPM_PR_DEBUG,"next mouse making"); -- tmp->next = (struct micetab *) malloc(sizeof(struct micetab)); -- if(!tmp) gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM); -- tmp->next = NULL; -- tmp->device = value; -- tmp->protocol = NULL; -- tmp->options = NULL; -- return; -- } else gpm_report(GPM_PR_OOPS,GPM_MESS_FIRST_DEV); -- -- //} else if(tmp->device != NULL && tmp->protocol == NULL) -- // gpm_report(GPM_PR_OOPS,GPM_MESS_FIRST_DEV); /* -m -m */ -- -- -- break; -- -- /*---------------------------------------------------------------------*/ -- /************************* -t type / protocol **************************/ -- /*---------------------------------------------------------------------*/ -- -- case GPM_ADD_TYPE: -- if(option.micelist == NULL) gpm_report(GPM_PR_OOPS,GPM_MESS_FIRST_DEV); -- -- /* skip to next mouse, where either device or protocol is missing */ -- while(tmp->device != NULL && tmp->protocol != NULL && tmp->next !=NULL) -- tmp = tmp->next; -- -- /* check whether device (-m) is there, if so, write protocol */ -- if(tmp->device == NULL) gpm_report(GPM_PR_OOPS,GPM_MESS_FIRST_DEV); -- else { -- gpm_report(GPM_PR_DEBUG,"adding mouse type: %s",value); -- tmp->protocol = value; -- option.no_mice++; /* finally we got our mouse */ -- } -- -- break; -- -- /*---------------------------------------------------------------------*/ -- /*************************** -o options ********************************/ -- /*---------------------------------------------------------------------*/ -- -- case GPM_ADD_OPTIONS: -- if(option.micelist == NULL) gpm_report(GPM_PR_OOPS,GPM_MESS_FIRST_DEV); -- -- /* look for the last mouse */ -- tmp = option.micelist; -- while(tmp->next != NULL) tmp = tmp->next; -- -- /* if -m or -t are missing exit */ -- if(tmp->device == NULL || tmp->protocol == NULL) -- gpm_report(GPM_PR_OOPS,GPM_MESS_FIRST_DEV); -- else { -- gpm_report(GPM_PR_DEBUG,"adding mouse options: %s",value); -- tmp->options = value; -- } -- break; -- } -+ return mouse; - } - --/* DESCR: mice initialization. currently print mice. */ --/* RETURN: 0 - failed to init one or more devices -- 1 - init was fine */ -+/* DESCR: mice initialization. calls appropriate init functions. */ - /* COMMENT: does error handling and exiting itself */ --int init_mice(struct micetab *micelist) -+void init_mice(void) - { -- struct micetab *tmp = micelist; -+ struct micetab *mouse; -+ -+ for (mouse = micelist; mouse; mouse = mouse->next) { -+ if (!strcmp(mouse->device, "-")) -+ mouse->dev.fd = 0; /* use stdin */ -+ else if ((mouse->dev.fd = open(mouse->device, O_RDWR | O_NDELAY)) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN, mouse->device); - -- while(tmp != NULL) { /* there are still mice to init */ -- gpm_report(GPM_PR_DEBUG,"initialize %s with proto %s",tmp->device,tmp->protocol); -- if(tmp->options != NULL) { -- gpm_report(GPM_PR_DEBUG,"and options %s",tmp->options); -- } -- tmp = tmp->next; -+ /* and then reset the flag */ -+ fcntl(mouse->dev.fd, F_SETFL, fcntl(mouse->dev.fd, F_GETFL) & ~O_NDELAY); -+ -+ /* init the device, and use the return value as new mouse type */ -+ if (mouse->type->init) -+ if (mouse->type->init(&mouse->dev, &mouse->options, mouse->type)) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_MOUSE_INIT); - } -- -- gpm_report(GPM_PR_DEBUG,"finished initialization"); -- return 1; - } - - /* DESCR: when leaving, we should reset mice to their normal state */ --/* RETURN: 0 - failed to reset one or more devices -- 1 - reset was fine */ - /* COMMENT: does error handling and exiting itself */ --int reset_mice(struct micetab *micelist) -+void cleanup_mice(void) - { -- struct micetab *tmp = micelist; -- struct micetab *end = tmp; -- -- while(tmp != NULL) { /* FIXME! I never get NULL, as free()d before */ -- end = tmp; -- while(tmp->next != NULL) { /* set end to the last mouse */ -- end = tmp; -- tmp = tmp->next; -- } -- -- gpm_report(GPM_PR_DEBUG,"reset: %s with proto %s",end->device,end->protocol); -- if(tmp->options != NULL) { -- gpm_report(GPM_PR_DEBUG,"and options %s",end->options); -- } -- free(end); /* be clean() */ -- tmp = micelist; /* reset to the first mice again */ -+ struct micetab *tmp; -+ -+ while ((tmp = micelist)) { -+ if (micelist->dev.private) -+ free(micelist->dev.private); -+ micelist = micelist->next; -+ free(tmp); - } -- -- return 1; - } -diff -urN gpm-1.20.1/src/special.c gpm/src/special.c ---- gpm-1.20.1/src/special.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/special.c 2003-10-02 01:22:42.000000000 -0500 -@@ -37,6 +37,7 @@ - #include <sys/param.h> - - #include "headers/gpmInt.h" -+#include "headers/console.h" - - /* - * This function is only called at button press, to avoid unnecessary -@@ -78,7 +79,7 @@ - return 1; - - /* devfs change */ -- consolef=fopen(option.consolename,"w"); -+ consolef = fopen(console.device, "w"); - if (!consolef) consolef=stderr; - if (event->type & GPM_TRIPLE) /* just triggered: make noise and return */ - { -@@ -153,7 +154,7 @@ - case 0: /* child */ - close(0); close(1); close(2); - open(GPM_NULL_DEV,O_RDONLY); /* stdin */ -- open(option.consolename,O_WRONLY); /* stdout */ -+ open(console.device, O_WRONLY); /* stdout */ - dup(1); /* stderr */ - for (i=3;i<OPEN_MAX; i++) close(i); - execl("/bin/sh","sh","-c",command,(char *)NULL); -diff -urN gpm-1.20.1/src/startup.c gpm/src/startup.c ---- gpm-1.20.1/src/startup.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/startup.c 2003-10-02 01:22:42.000000000 -0500 -@@ -26,6 +26,7 @@ - #include <string.h> /* strlen() */ - #include <errno.h> /* errno */ - #include <unistd.h> /* unlink,geteuid */ -+#include <signal.h> - #include <sys/types.h> /* geteuid, mknod */ - #include <sys/stat.h> /* mknod */ - #include <fcntl.h> /* mknod */ -@@ -34,11 +35,13 @@ - - #include "headers/gpmInt.h" - #include "headers/message.h" -+#include "headers/console.h" -+#include "headers/selection.h" - - /* what todo atexit */ - static void gpm_exited(void) - { -- gpm_report(GPM_PR_DEBUG,GPM_MESS_REMOVE_FILES, GPM_NODE_PID, GPM_NODE_CTL); -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_REMOVE_FILES, GPM_NODE_PID, GPM_NODE_CTL); - unlink(GPM_NODE_PID); - unlink(GPM_NODE_CTL); - } -@@ -48,34 +51,12 @@ - extern struct options option; - extern int errno; - -- int i,opt; -- -- static struct { -- char *in; -- char *out; -- } seq[] = { -- {"123","01234567"}, -- {"132","02134657"}, -- {"213","01452367"}, /* warning: these must be readable as integers... */ -- {"231","02461357"}, -- {"312","04152637"}, -- {"321","04261537"}, -- {NULL,NULL} -- }; -- - /* basic settings */ - option.run_status = GPM_RUN_STARTUP; /* 10,9,8,... let's go */ - option.autodetect = 0; /* no mouse autodection */ - option.progname = argv[0]; /* who we are */ -- option.consolename = Gpm_get_console(); /* get consolename */ -- -- /* basic2: are not necessary for oops()ing, if not root */ -- option.no_mice = 0; /* counts -m + -t */ -- option.micelist = NULL; /* no mice found yet */ -- option.repeater = 0; /* repeat data */ -- option.repeater_type = NULL; /* type of */ -- - -+ get_console_name(); - cmdline(argc, argv); /* parse command line */ - - if (geteuid() != 0) gpm_report(GPM_PR_OOPS,GPM_MESS_ROOT); /* root or exit */ -@@ -87,54 +68,18 @@ - /****************** OLD CODE from gpn.c ***********************/ - - openlog(option.progname, LOG_PID, -- option.run_status != GPM_RUN_DEBUG ? LOG_DAEMON : LOG_USER); -- loadlut(opt_lut); -- -- if (option.repeater) { -- if(mkfifo(GPM_NODE_FIFO,0666) && errno!=EEXIST) -- gpm_report(GPM_PR_OOPS,GPM_MESS_CREATE_FIFO,GPM_NODE_FIFO); -- if((fifofd=open(GPM_NODE_FIFO, O_RDWR|O_NONBLOCK)) < 0) -- gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN, GPM_NODE_FIFO); -- } -- -- /* duplicate initialization */ -- for (i=1; i <= 1+opt_double; i++) { -- which_mouse=mouse_table+i; /* used to access options */ -- if (opt_accel < 1) exit(usage("acceleration")); -- if (opt_delta < 2) exit(usage("delta")); -- if (strlen(opt_sequence) != 3 || atoi(opt_sequence)<100) -- exit(usage("sequence")); -- if (opt_glidepoint_tap > 3) exit(usage("glidepoint tap button")); -- if (opt_glidepoint_tap) -- opt_glidepoint_tap=GPM_B_LEFT >> (opt_glidepoint_tap-1); -- -- /* choose the sequence */ -- for (opt=0; seq[opt].in && strcmp(seq[opt].in,opt_sequence); opt++) ; -- if(!seq[opt].in) exit(usage("button sequence")); -- opt_sequence=strdup(seq[opt].out); /* I can rewrite on it */ -- -- /* look for the mouse type */ -- m_type = find_mouse_by_name(opt_type); -- if (!m_type) /* not found */ -- exit(M_listTypes()); -- } -+ option.run_status != GPM_RUN_DEBUG ? LOG_DAEMON : LOG_USER); - -- /* Check repeater status */ -- if (option.repeater) { -- if (strcmp(option.repeater_type,"raw") == 0) -- opt_rawrep = 1; -- else { -- /* look for the type */ -- repeated_type = find_mouse_by_name(option.repeater_type); -+ console_load_lut(); - -- if(!repeated_type) exit(M_listTypes()); /* not found */ -- -- if (!(repeated_type->repeat_fun)) /* unsupported translation */ -- gpm_report(GPM_PR_OOPS,GPM_MESS_NO_REPEAT,option.repeater_type); -- } -+ if (repeater.raw || repeater.type) { -+ if (mkfifo(GPM_NODE_FIFO, 0666) && errno != EEXIST) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_CREATE_FIFO, GPM_NODE_FIFO); -+ if ((repeater.fd = open(GPM_NODE_FIFO, O_RDWR|O_NONBLOCK)) < 0) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_OPEN, GPM_NODE_FIFO); - } - -- if(option.run_status == GPM_RUN_STARTUP ) { /* else is debugging */ -+ if(option.run_status == GPM_RUN_STARTUP) { /* else is debugging */ - /* goto background and become a session leader (Stefan Giessler) */ - switch(fork()) { - case -1: gpm_report(GPM_PR_OOPS,GPM_MESS_FORK_FAILED); /* error */ -@@ -152,13 +97,63 @@ - /* is changing to root needed, because of relative paths ? or can we just - * remove and ignore it ?? FIXME */ - if (chdir("/") < 0) gpm_report(GPM_PR_OOPS,GPM_MESS_CHDIR_FAILED); -- - -- //return mouse_table[1].fd; /* the second is handled in the main() */ -+ atexit(gpm_exited); /* call gpm_exited at the end */ -+} - -- /****************** OLD CODE from gpn.c END ***********************/ -+/* itz Sat Sep 12 10:30:05 PDT 1998 this function used to mix two -+ completely different things; opening a socket to a running daemon -+ and checking that a running daemon existed. Ugly. */ -+/* rewritten mostly on 20th of February 2002 - nico */ -+void check_uniqueness(void) -+{ -+ FILE *fp = 0; -+ int old_pid = -1; - -- init_mice(option.micelist); /* reads option.micelist */ -- atexit(gpm_exited); /* call gpm_exited at the end */ -+ if ((fp = fopen(GPM_NODE_PID, "r")) != NULL) { -+ fscanf(fp, "%d", &old_pid); -+ if (kill(old_pid, 0) == -1) { -+ gpm_report(GPM_PR_INFO,GPM_MESS_STALE_PID, GPM_NODE_PID); -+ unlink(GPM_NODE_PID); -+ } else /* we are really running, exit asap! */ -+ gpm_report(GPM_PR_OOPS, GPM_MESS_ALREADY_RUN, old_pid); -+ } -+ /* now try to sign ourself */ -+ if ((fp = fopen(GPM_NODE_PID,"w")) != NULL) { -+ fprintf(fp,"%d\n",getpid()); -+ fclose(fp); -+ } else { -+ gpm_report(GPM_PR_OOPS,GPM_MESS_NOTWRITE,GPM_NODE_PID); -+ } -+} - -+/* itz Sat Sep 12 10:55:51 PDT 1998 Added this as replacement for the -+ unwanted functionality in check_uniqueness. */ -+void kill_gpm(void) -+{ -+ int old_pid; -+ FILE* fp = fopen(GPM_NODE_PID, "r"); -+ -+ /* if we cannot find the old pid file, leave */ -+ if (fp == NULL) gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN, GPM_NODE_PID); -+ -+ /* else read the pid */ -+ if (fscanf(fp, "%d", &old_pid) != 1) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_READ_PROB, GPM_NODE_PID); -+ fclose(fp); -+ -+ gpm_report(GPM_PR_DEBUG, GPM_MESS_KILLING, old_pid); -+ -+ /* first check if we run */ -+ if (kill(old_pid,0) == -1) { -+ gpm_report(GPM_PR_INFO, GPM_MESS_STALE_PID, GPM_NODE_PID); -+ unlink(GPM_NODE_PID); -+ } -+ /* then kill us (not directly, but the other instance ... ) */ -+ if (kill(old_pid, SIGTERM) == -1) -+ gpm_report(GPM_PR_OOPS, GPM_MESS_CANT_KILL, old_pid); -+ -+ gpm_report(GPM_PR_INFO, GPM_MESS_KILLED, old_pid); -+ exit(0); - } -+ -diff -urN gpm-1.20.1/src/synaptics.c gpm/src/synaptics.c ---- gpm-1.20.1/src/synaptics.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/synaptics.c 2003-10-02 01:22:42.000000000 -0500 -@@ -865,7 +865,7 @@ - static int scrolling_speed_timer = 0; - static int scrolling_amount_left = 0; /* Tells how much to scroll up or down */ - -- -+static int mouse_fd; - - - -@@ -882,6 +882,7 @@ - ** which makes reading the debug data harder, only dump the report if it is different - ** than the previously dumped. - */ -+#if DEBUG_REPORTS - static void tp_dump_report_data (report_type report, - int edges, - Gpm_Event* state) -@@ -934,7 +935,7 @@ - (multi_finger_pressure>4500 && multi_finger_xy>50000? 'f':' ')); - - } -- -+#endif - - /* syn_dump_info - ** -@@ -1158,8 +1159,8 @@ - status = GPM_B_NOT_SET; - break; - case Reset_Touchpad_Action: -- syn_ps2_reset(which_mouse->fd); -- syn_ps2_absolute_mode(which_mouse->fd); -+ syn_ps2_reset(mouse_fd); -+ syn_ps2_absolute_mode(mouse_fd); - status = GPM_B_NOT_SET; - break; - case Toggle_Four_Way_Button_Action: -@@ -2950,10 +2951,8 @@ - data [0],data [1],data [2],data [3],data [4],data [5]); - - if (reset_on_error_enabled) { -- /* Hack to get the fd: which_mouse is the current mouse, -- and as the synaptic code is called, it is the current mouse. */ -- syn_ps2_reset(which_mouse->fd); -- syn_ps2_absolute_mode(which_mouse->fd); -+ syn_ps2_reset(mouse_fd); -+ syn_ps2_absolute_mode(mouse_fd); - } - - report->left = 0; -@@ -3108,7 +3107,7 @@ - ** - ** Process the touchpad 6 byte report. - */ --void syn_process_serial_data (Gpm_Event *state, -+void syn_process_serial_data (int fd, Gpm_Event *state, - unsigned char *data) - { - /* initialize the state */ -@@ -3116,6 +3115,8 @@ - state->dx = 0; - state->dy = 0; - -+ mouse_fd = fd; /* cheat */ -+ - syn_serial_translate_data (data, &cur_report); - if (wmode_enabled){ - syn_process_wmode_report(&cur_report); -@@ -3196,7 +3197,7 @@ - ** - ** Process the touchpad 6 byte report. - */ --void syn_process_ps2_data (Gpm_Event *state, -+void syn_process_ps2_data (int fd, Gpm_Event *state, - unsigned char *data) - { - /* gpm_report(GPM_PR_DEBUG,"Data %02x %02x %02x %02x %02x %02x",data[0],data[1],data[2],data[3],data[4],data[5]); */ -@@ -3206,6 +3207,7 @@ - state->dx = 0; - state->dy = 0; - -+ mouse_fd = fd; /* cheat */ - - if (wmode_enabled) { - syn_ps2_translate_wmode_data (data, &cur_report); -diff -urN gpm-1.20.1/src/tools.c gpm/src/tools.c ---- gpm-1.20.1/src/tools.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/tools.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,93 +0,0 @@ --/* -- * tools.c - tools which are needed by client and server -- * -- * Copyright (c) 2001 Nico Schottelius <nico@schottelius.org> -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program 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 General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -- ********/ -- --#include <stdio.h> /* NULL */ --#include <string.h> --#include <stdlib.h> --#include <sys/types.h> /* these three are */ --#include <sys/stat.h> /* needed for */ --#include <unistd.h> /* stat() */ -- --#include "headers/gpmInt.h" /* only used for some defines */ --#include "headers/message.h" -- --/***************************************************************************** -- * check, whether devfs is used or not. -- * See /usr/src/linux/Documentation/filesystems/devfs/ for details. -- * Returns: the name of the console (/dev/tty0 or /dev/vc/0) -- *****************************************************************************/ --char *Gpm_get_console( void ) --{ -- -- char *back = NULL, *tmp = NULL; -- struct stat buf; -- -- /* first try the devfs device, because in the next time this will be -- * the preferred one. If that fails, take the old console */ -- -- /* Check for open new console */ -- if (stat(GPM_DEVFS_CONSOLE,&buf) == 0) -- tmp = GPM_DEVFS_CONSOLE; -- -- /* Failed, try OLD console */ -- else if(stat(GPM_OLD_CONSOLE,&buf) == 0) -- tmp = GPM_OLD_CONSOLE; -- -- if(tmp != NULL) -- if((back = malloc(strlen(tmp) + sizeof(char)) ) != NULL) -- strcpy(back,tmp); -- -- return(back); --} -- --/* what's the english name for potenz ? */ --int Gpm_x_high_y(int base, int pot_y) --{ -- int val = 1; -- -- if(pot_y == 0) val = 1; -- else if(pot_y < 0) val = 0; /* ugly hack ;) */ -- else while(pot_y > 0) { -- val = val * base; -- pot_y--; -- } -- return val; --} -- --/* return characters needed to display int */ --int Gpm_cnt_digits(int number) --{ -- /* 0-9 = 1 10^0 <-> (10^1)-1 -- * 10 - 99 = 2 10^1 <-> (10^2)-1 -- * 100 - 999 = 3 10^2 <-> (10^3)-1 -- * 1000 - 9999 = 4 ... */ -- -- int ret = 0, num = 0; -- -- /* non negative, please */ -- if(number < 0) number *= -1; -- else if(number == 0) ret = 1; -- else while(number > num) { -- ret++; -- num = (Gpm_x_high_y(10,ret) - 1); -- } -- -- return(ret); --} -diff -urN gpm-1.20.1/src/twiddler.c gpm/src/twiddler.c ---- gpm-1.20.1/src/twiddler.c 2002-12-24 17:57:16.000000000 -0500 -+++ gpm/src/twiddler.c 2003-10-02 01:22:42.000000000 -0500 -@@ -54,6 +54,7 @@ - #include "headers/gpm.h" - #include "headers/gpmInt.h" - #include "headers/message.h" -+#include "headers/console.h" - #include "headers/twiddler.h" - - -@@ -134,17 +135,6 @@ - int (*fun)(char *string); - }; - -- --/* The same silly function as in gpm.c */ --static inline int open_console(const int mode) --{ -- int fd; -- extern struct options option; -- if ((fd=open(option.consolename, mode)) < 0) gpm_report(GPM_PR_OOPS,GPM_MESS_OPEN,option.consolename); -- return fd; --} -- -- - /*===================================================================*/ - /* This part deals with pushing keys */ - -@@ -175,7 +165,7 @@ - int twiddler_exec(char *s) - { - int pid; -- extern struct options option; -+ - switch(pid=fork()) { - case -1: return -1; - case 0: -@@ -184,7 +174,7 @@ - close(2); /* very rude! */ - - open(GPM_NULL_DEV,O_RDONLY); -- open(option.consolename,O_WRONLY); -+ open(console.device, O_WRONLY); - dup(1); - execl("/bin/sh", "sh", "-c", s, NULL); - exit(1); /* shouldn't happen */ |