[w3m-dev-en 00020] FreeBSD sysmouse support

From: w3m-dev-en@mips.rhein-neckar.de
Date: Fri Jan 21 2000 - 21:16:24 CST


This is a first cut at FreeBSD sysmouse (i.e. console mouse) support.
It is mostly intended for testing--of which I have done very little
as yet. The official FreeBSD port is still at 991203, but I can
provide updated versions for 0.1.4, 0.1.6, or 0.1.6 plus the patches
below. Mail me at <naddy@mips.rhein-neckar.de>.

The implementation mirrors the already included Linux GPM support.
Overview:

terms.c: mouse_init():
- Tell console driver to report mouse events on SIGUSR2.
- Install signal handler sysmouse() for SIGUSR2.
- Register sysm_process_mouse() as sysm_handler.

terms.c: sysmouse():
- Fetch the mouse state and store it in static variables.

terms.c: do_getch():
- Call sysm_getch().

terms.c: sysm_getch():
- select() on tty.
- If interrupted, we were sent a signal
  => fetch mouse state from variables and call sysm_handler.
- Otherwise return character read from tty.

main.c: sysm_process_mouse(),
menu.c: sysm_process_menu_mouse():
- Glue code between sysmouse semantics and process_mouse(),
  process_mMouse().

menu.c: popup_menu(),
menu.c: action_menu():
- Swap sysm_process_menu() and sysm_process_menu_mouse() as
  sysm_handler, and generally duplicate GPM handling.

terms.c: mouse_end():
- Doesn't do anything at all for sysmouse, because mouse handling is
  automatically reset by the console driver on program exit.

Patch:

--- config.h.orig Fri Jan 21 21:48:43 2000
+++ config.h Fri Jan 21 21:49:49 2000
@@ -76,6 +76,7 @@
 #define COLOR
 #define MOUSE
 #define USE_GPM
+#undef USE_SYSMOUSE
 #define MENU
 #define USE_COOKIE
 #define USE_SSL
--- configure.orig Fri Jan 21 21:43:15 2000
+++ configure Fri Jan 21 21:47:35 2000
@@ -631,6 +631,15 @@
   done
 fi
 
+case $sysname in
+ freebsd|FreeBSD)
+ use_sysmouse="#define USE_SYSMOUSE"
+ ;;
+ *)
+ use_sysmouse="#undef USE_SYSMOUSE"
+ ;;
+esac
+
 extlib=''
 
 case $sysname in
@@ -1237,6 +1246,7 @@
 $def_color
 $def_mouse
 $use_gpm
+$use_sysmouse
 $def_menu
 $def_cookie
 $def_ssl
--- buffer.c.orig Fri Jan 21 21:56:04 2000
+++ buffer.c Fri Jan 21 21:58:12 2000
@@ -2,6 +2,8 @@
 
 #ifdef USE_GPM
 #include <gpm.h>
+#endif
+#if defined(USE_GPM) || defined(USE_SYSMOUSE)
 extern int do_getch();
 #define getch() do_getch()
 #endif
--- linein.c.orig Fri Jan 21 21:59:00 2000
+++ linein.c Fri Jan 21 21:59:53 2000
@@ -5,6 +5,8 @@
 
 #ifdef USE_GPM
 #include <gpm.h>
+#endif
+#if defined(USE_GPM) || defined(USE_SYSMOUSE)
 extern int do_getch();
 #define getch() do_getch()
 #endif
--- main.c.orig Fri Jan 21 22:00:37 2000
+++ main.c Sat Jan 22 02:28:30 2000
@@ -9,9 +9,11 @@
 #include "myctype.h"
 #ifdef USE_GPM
 #include <gpm.h>
+#endif
+#if defined(USE_GPM) || defined(USE_SYSMOUSE)
 extern int do_getch();
 #define getch() do_getch()
-#endif /* USE_GPM */
+#endif
 
 extern void (*GlobalKeymap[])();
 extern void (*EscKeymap[])();
@@ -3095,12 +3097,30 @@
     }
   }
   else {
- GPM_DRAWPOINTER(event);
     return 0;
   }
   x = event->x;
   y = event->y;
   process_mouse(btn, x-1, y-1);
+ return 0;
+}
+#endif
+
+#ifdef USE_SYSMOUSE
+int sysm_process_mouse(int x, int y, int nbs, int obs)
+{
+ int btn;
+ int bits;
+
+ if (obs & ~nbs)
+ btn = MOUSE_BTN_UP;
+ else if (bits = nbs & ~obs)
+ btn = bits & 0x1 ? MOUSE_BTN1_DOWN :
+ (bits & 0x2 ? MOUSE_BTN2_DOWN :
+ (bits & 0x4 ? MOUSE_BTN3_DOWN : 0));
+ else /* nbs == obs */
+ return 0;
+ process_mouse(btn, x, y);
   return 0;
 }
 #endif
--- menu.c.orig Fri Jan 21 22:06:59 2000
+++ menu.c Sat Jan 22 02:30:16 2000
@@ -12,8 +12,15 @@
 #include <gpm.h>
 static int gpm_process_menu_mouse(Gpm_Event *event, void *data);
 extern int gpm_process_mouse(Gpm_Event*,void*);
-#define X_GPM_SELECTED (char)0xff
-static int X_Gpm_Selection;
+#endif
+#ifdef USE_SYSMOUSE
+extern int (*sysm_handler)(int x, int y, int nbs, int obs);
+static int sysm_process_menu_mouse(int, int, int, int);
+extern int sysm_process_mouse(int, int, int, int);
+#endif
+#if defined(USE_GPM) || defined(USE_SYSMOUSE)
+#define X_MOUSE_SELECTED (char)0xff
+static int X_Mouse_Selection;
 extern int do_getch();
 #define getch() do_getch()
 #endif
@@ -517,9 +524,9 @@
 #ifdef MOUSE
     if (use_mouse) mouse_inactive();
 #endif
-#ifdef USE_GPM
- if (c == X_GPM_SELECTED) {
- select = X_Gpm_Selection;
+#if defined(USE_GPM) || defined(USE_SYSMOUSE)
+ if (c == X_MOUSE_SELECTED) {
+ select = X_Mouse_Selection;
       break;
     }
 #endif
@@ -561,6 +568,9 @@
 #ifdef USE_GPM
   gpm_handler = gpm_process_menu_mouse;
 #endif
+#ifdef USE_SYSMOUSE
+ sysm_handler = sysm_process_menu_mouse;
+#endif
   menu->parent = parent;
   menu->select = menu->initial;
   menu->offset = 0;
@@ -583,6 +593,10 @@
   if (CurrentMenu == NULL)
     gpm_handler = gpm_process_mouse;
 #endif
+#ifdef USE_SYSMOUSE
+ if (CurrentMenu == NULL)
+ sysm_handler = sysm_process_mouse;
+#endif
 }
 
 void
@@ -858,9 +872,31 @@
   }
   x = event->x;
   y = event->y;
- X_Gpm_Selection = process_mMouse(btn, x-1, y-1);
- if (X_Gpm_Selection >= 0)
- return X_GPM_SELECTED;
+ X_Mouse_Selection = process_mMouse(btn, x-1, y-1);
+ if (X_Mouse_Selection >= 0)
+ return X_MOUSE_SELECTED;
+ return 0;
+}
+#endif
+
+#ifdef USE_SYSMOUSE
+static int
+sysm_process_menu_mouse(int x, int y, int nbs, int obs)
+{
+ int btn;
+ int bits;
+
+ if (obs & ~nbs)
+ btn = MOUSE_BTN_UP;
+ else if (bits = nbs & ~obs)
+ btn = bits & 0x1 ? MOUSE_BTN1_DOWN :
+ (bits & 0x2 ? MOUSE_BTN2_DOWN :
+ (bits & 0x4 ? MOUSE_BTN3_DOWN : 0));
+ else /* nbs == obs */
+ return 0;
+ X_Mouse_Selection = process_mMouse(btn, x, y);
+ if (X_Mouse_Selection >= 0)
+ return X_MOUSE_SELECTED;
   return 0;
 }
 #endif
--- terms.c.orig Fri Jan 21 22:14:34 2000
+++ terms.c Sat Jan 22 01:36:39 2000
@@ -15,6 +15,16 @@
 #ifdef USE_GPM
 #include <gpm.h>
 #endif
+#ifdef USE_SYSMOUSE
+#include <machine/console.h>
+#ifndef FBIO_GETMODE /* FreeBSD 3.x */
+#define FBIO_GETMODE CONS_GET
+#define FBIO_MODEINFO CONS_MODEINFO
+#endif
+int (*sysm_handler)(int x, int y, int nbs, int obs);
+static int cwidth = 8, cheight = 16;
+static int xpos, ypos, buttons;
+#endif
 #ifdef MOUSE
 static int is_xterm = 0;
 #endif
@@ -1423,6 +1433,59 @@
 }
 #endif
 
+#ifdef USE_SYSMOUSE
+int
+sysm_getch()
+{
+ fd_set rfd;
+ int key;
+ int nbs, x, y;
+ static int obs = 0;
+
+ FD_ZERO(&rfd);
+ FD_SET(tty, &rfd);
+ while (select(tty+1, &rfd, NULL, NULL, NULL) <= 0) {
+ if (errno == EINTR) {
+ x = xpos / cwidth;
+ y = ypos / cheight;
+ nbs = buttons;
+ key = (*sysm_handler)(x, y, nbs, obs);
+ obs = nbs;
+ if (key != 0)
+ return key;
+ }
+ }
+ return getch();
+}
+
+int
+do_getch()
+{
+ if (is_xterm)
+ return getch();
+ else
+ return sysm_getch();
+}
+
+MySignalHandler
+sysmouse(SIGNAL_ARG)
+{
+ struct mouse_info mi;
+
+ mi.operation = MOUSE_GETINFO;
+ if (ioctl(tty, CONS_MOUSECTL, &mi) == -1)
+ return;
+ xpos = mi.u.data.x;
+ ypos = mi.u.data.y;
+ buttons = mi.u.data.buttons & 0x7;
+ /* for cosmetic bug in syscons.c on FreeBSD 3.[34] */
+ mi.operation = MOUSE_HIDE;
+ ioctl(tty, CONS_MOUSECTL, &mi);
+ mi.operation = MOUSE_SHOW;
+ ioctl(tty, CONS_MOUSECTL, &mi);
+}
+#endif
+
 void
 bell(void)
 {
@@ -1465,12 +1528,22 @@
 #ifdef USE_GPM
   Gpm_Connect conn;
   extern int gpm_process_mouse(Gpm_Event*,void*);
+#endif USE_GPM
+#ifdef USE_SYSMOUSE
+ mouse_info_t mi;
+ video_info_t vi;
+ extern int sysm_process_mouse();
+#endif
 
- if (mouseActive) return;
+#if defined(USE_GPM) || defined(USE_SYSMOUSE)
+ if (mouseActive)
+ return;
+#endif
   term = getenv("TERM");
   if (!strncmp(term,"kterm",5) || !strncmp(term,"xterm",5)) {
     is_xterm = 1;
   }
+#ifdef USE_GPM
   else {
     conn.eventMask = ~0;
     conn.defaultMask = GPM_MOVE|GPM_HARD;
@@ -1479,10 +1552,24 @@
     Gpm_Open(&conn,0); /* don't care even if it fails */
     gpm_handler = gpm_process_mouse;
   }
-#else
- term = getenv("TERM");
- if (!strncmp(term,"kterm",5) || !strncmp(term,"xterm",5)) {
- is_xterm = 1;
+#endif
+#ifdef USE_SYSMOUSE
+ else {
+ if (ioctl(tty, FBIO_GETMODE, &vi.vi_mode) != -1 &&
+ ioctl(tty, FBIO_MODEINFO, &vi) != -1) {
+ cwidth = vi.vi_cwidth;
+ cheight = vi.vi_cheight;
+ }
+ signal(SIGUSR2, SIG_IGN);
+ mi.operation = MOUSE_MODE;
+ mi.u.mode.mode = 0;
+ mi.u.mode.signal = SIGUSR2;
+ if (ioctl(tty, CONS_MOUSECTL, &mi) != -1) {
+ signal(SIGUSR2, sysmouse);
+ mi.operation = MOUSE_SHOW;
+ ioctl(tty, CONS_MOUSECTL, &mi);
+ sysm_handler = sysm_process_mouse;
+ }
   }
 #endif
   mouseActive = 1;

-- 
Christian "naddy" Weisgerber                  naddy@mips.rhein-neckar.de



This archive was generated by hypermail 2b29 : Wed Jul 19 2000 - 10:30:43 CDT