summaryrefslogtreecommitdiffstats
path: root/source/a/gpm/gpm-evdev-cumulative.patch
diff options
context:
space:
mode:
Diffstat (limited to 'source/a/gpm/gpm-evdev-cumulative.patch')
-rw-r--r--source/a/gpm/gpm-evdev-cumulative.patch7023
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 2fd86d10c..000000000
--- 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 */