From 82eece415e015cb3f8ef79052f4ae0de9474a204 Mon Sep 17 00:00:00 2001 From: Nick Chan Date: Sat, 4 Feb 2023 19:40:57 +0800 Subject: [PATCH] fixes --- .github/workflows/build.yml | 6 +- patches/gpm/010_ps2_rework.patch | 501 ------------------------------- 2 files changed, 4 insertions(+), 503 deletions(-) delete mode 100644 patches/gpm/010_ps2_rework.patch diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 875db3b..af915f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -228,7 +228,8 @@ jobs: ${{ env.CONFIGURE_ARGS }} \ --with-readline=gnu \ --without-python \ - --without-tcl + --without-tcl \ + --disable-nls gmake -j$(sysctl -n hw.ncpu) gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }} cd .. @@ -600,7 +601,8 @@ jobs: --with-gpm-support \ --with-readline=gnu \ --without-python \ - --without-tcl + --without-tcl \ + --disable-nls gmake -j$(sysctl -n hw.ncpu) gmake -j$(sysctl -n hw.ncpu) install DESTDIR=${{ env.DESTDIR }} cd .. diff --git a/patches/gpm/010_ps2_rework.patch b/patches/gpm/010_ps2_rework.patch deleted file mode 100644 index a11e714..0000000 --- a/patches/gpm/010_ps2_rework.patch +++ /dev/null @@ -1,501 +0,0 @@ -Description: PS/2 rework -Author: Zephaniah E. Hull - ---- a/src/headers/gpmInt.h -+++ b/src/headers/gpmInt.h -@@ -54,6 +54,7 @@ - #define GPM_AUX_ID_ERROR -1 - #define GPM_AUX_ID_PS2 0 - #define GPM_AUX_ID_IMPS2 3 -+#define GPM_AUX_ID_EXPS2 4 - - /* these are shameless stolen from /usr/src/linux/include/linux/pc_keyb.h */ - -@@ -65,6 +66,7 @@ - #define GPM_AUX_SET_SAMPLE 0xF3 /* Set sample rate */ - #define GPM_AUX_ENABLE_DEV 0xF4 /* Enable aux device */ - #define GPM_AUX_DISABLE_DEV 0xF5 /* Disable aux device */ -+#define GPM_AUX_DEFAULTS 0xF6 /* Reset to defaults */ - #define GPM_AUX_RESET 0xFF /* Reset aux device */ - #define GPM_AUX_ACK 0xFA /* Command byte ACK. */ - ---- a/src/daemon/startup.c -+++ b/src/daemon/startup.c -@@ -35,21 +35,9 @@ - - void startup(int argc, char **argv) - { -- int i, opt; -+ int i, j, opt; -+ char *p; - -- 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} -- }; -- - /* log to debug, who we are */ - gpm_report(GPM_PR_DEBUG, GPM_MESS_VERSION); - -@@ -92,16 +80,23 @@ - which_mouse=mouse_table+i; /* used to access options */ - if ((which_mouse->opt_accel) < 1) exit(usage("acceleration")); - if ((which_mouse->opt_delta) < 2) exit(usage("delta")); -- if (strlen((which_mouse->opt_sequence)) != 3 || atoi((which_mouse->opt_sequence))<100) -+ if (strlen(which_mouse->opt_sequence) <= 0) - exit(usage("sequence")); -- if ((which_mouse->opt_glidepoint_tap) > 3) exit(usage("glidepoint tap button")); -- if ((which_mouse->opt_glidepoint_tap)) -- (which_mouse->opt_glidepoint_tap)=GPM_B_LEFT >> ((which_mouse->opt_glidepoint_tap)-1); - - /* choose the sequence */ -- for (opt=0; seq[opt].in && strcmp(seq[opt].in,(which_mouse->opt_sequence)); opt++) ; -- if(!seq[opt].in) exit(usage("button sequence")); -- (which_mouse->opt_sequence)=strdup(seq[opt].out); /* I can rewrite on it */ -+ for (j = 0; j < 9; j++) -+ which_mouse->opt_buts[j] = 1 << j; -+ -+ for (p = which_mouse->opt_sequence, j = 0; *p != '\0'; p++, j++) { -+ if ((*p < '0') || (*p > '9')) -+ exit(usage("button sequence")); -+ which_mouse->opt_buts[j] = (1 << (*p - '1')); -+ } -+ -+ if (which_mouse->opt_glidepoint_tap > 9) -+ exit(usage("glidepoint tap button")); -+ if (which_mouse->opt_glidepoint_tap) -+ which_mouse->opt_glidepoint_tap = which_mouse->opt_buts[which_mouse->opt_glidepoint_tap - 1]; - - /* look for the mouse type */ - (which_mouse->m_type) = find_mouse_by_name((which_mouse->opt_type)); ---- a/src/mice.c -+++ b/src/mice.c -@@ -5,6 +5,7 @@ - * Copyright (C) 1994-2000 Alessandro Rubini - * Copyright (C) 1998,1999 Ian Zimmerman - * Copyright (C) 2001-2008 Nico Schottelius -+ * Copyright (C) 2002 Zephaniah E. Hull - * - * 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 -@@ -55,6 +56,7 @@ - #include - #include /* stat() */ - #include /* select() */ -+#include /* poll() */ - - #include /* MAJOR */ - #include -@@ -603,14 +605,21 @@ - return 0; - } - -+/* -+ * PS/2 mouse parser. -+ * Also called by the 'children' of the PS/2 mouse, for insanity sake. -+ * -- Zephaniah E. Hull. -+ */ - static int M_ps2(Gpm_Event *state, unsigned char *data) - { - static int tap_active=0; /* there exist glidepoint ps2 mice */ - -- state->buttons= -- !!(data[0]&1) * GPM_B_LEFT + -- !!(data[0]&2) * GPM_B_RIGHT + -- !!(data[0]&4) * GPM_B_MIDDLE; -+ state->wdx = state->wdy = 0; -+ -+ state->buttons = -+ ((data[0] & 0x02) ? (1 << 0) : 0) | // Right. -+ ((data[0] & 0x04) ? (1 << 1) : 0) | // Middle. -+ ((data[0] & 0x01) ? (1 << 2) : 0); // Left. - - if (data[0]==0 && (which_mouse->opt_glidepoint_tap)) /* by default this is false */ - state->buttons = tap_active = (which_mouse->opt_glidepoint_tap); -@@ -639,27 +648,28 @@ - return 0; - } - -+/* -+ * I cheat, because the two protocols are almost identical except for -+ * the 4th and 5th buttons, I just handle both. -+ * -+ * Note, the only thing that I've seen describe the 4th and 5th buttons -+ * for the IMPS/2 protocol is the X4 source, someone let me know if they -+ * actually see this used? -+ * -- Zephaniah E. Hull. -+ */ - static int M_imps2(Gpm_Event *state, unsigned char *data) - { -- -- static int tap_active=0; /* there exist glidepoint ps2 mice */ -- state->wdx = state->wdy = 0; /* Clear them.. */ -- state->dx = state->dy = state->wdx = state->wdy = 0; -- -- state->buttons= ((data[0] & 1) << 2) /* left */ -- | ((data[0] & 6) >> 1); /* middle and right */ -- -- if (data[0]==0 && (which_mouse->opt_glidepoint_tap)) // by default this is false -- state->buttons = tap_active = (which_mouse->opt_glidepoint_tap); -- else if (tap_active) { -- if (data[0]==8) -- state->buttons = tap_active = 0; -- else state->buttons = tap_active; -- } -+ M_ps2(state, data); - - /* Standard movement.. */ - state->dx = (data[0] & 0x10) ? data[1] - 256 : data[1]; - state->dy = (data[0] & 0x20) ? -(data[2] - 256) : -data[2]; -+ -+ state->buttons += -+ ((data[0] & 0x40) ? (1 << 3) : 0) | // IMPS/2 Button 4 -+ ((data[0] & 0x80) ? (1 << 4) : 0) | // IMPS/2 Button 5 -+ ((data[3] & 0x10) ? (1 << 3) : 0) | // EXPS/2 Button 4 -+ ((data[3] & 0x20) ? (1 << 4) : 0); // EXPS/2 Button 5 - - /* The wheels.. */ - unsigned char wheel = data[3] & 0x0f; -@@ -723,17 +733,6 @@ - return 0; - } - --/* standard ps2 */ --static Gpm_Type *I_ps2(int fd, unsigned short flags, -- struct Gpm_Type *type, int argc, char **argv) --{ -- static unsigned char s[] = { 246, 230, 244, 243, 100, 232, 3, }; -- write (fd, s, sizeof (s)); -- usleep (30000); -- tcflush (fd, TCIFLUSH); -- return type; --} -- - static Gpm_Type *I_netmouse(int fd, unsigned short flags, - struct Gpm_Type *type, int argc, char **argv) - { -@@ -1930,92 +1929,168 @@ - * - * Returns 0 if OK, or >0 if 1 or more errors occurred. - */ --static int write_to_mouse(int fd, unsigned char *data, size_t len) -+static int write_ps2(int fd, unsigned char cmd0, unsigned char cmd1, -+ size_t num, size_t rnum, unsigned long int sleep) - { -- int i; -- int error = 0; -- for (i = 0; i < len; i++) { -- unsigned char c; -- write(fd, &data[i], 1); -- read(fd, &c, 1); -- if (c != GPM_AUX_ACK) error++; -+ int i, error = 0, rcnt; -+ unsigned char cmd[2], ret[512]; -+ -+ cmd[0] = cmd0; -+ cmd[1] = cmd1; -+ -+ if (sleep == -1) -+ sleep = 50000; -+ -+ alarm(5); -+ rcnt = write(fd, cmd, num); -+ alarm(0); -+ if (rcnt != num) -+ return 1; -+ -+ usleep(sleep); -+ -+ alarm(5); -+ rcnt = read(fd, ret, rnum); -+ alarm(0); -+ -+ usleep(sleep); -+ -+ if (rcnt <= 0) -+ error++; -+ -+ for (i = 0; i < rcnt; i++) { -+ if (ret[i] != GPM_AUX_ACK) { -+ gpm_report(GPM_PR_ERR, "write_ps2: %d %d, %x", rcnt, i, ret[i]); -+ error++; -+ } - } - -- /* flush any left-over input */ -- usleep (30000); -- tcflush (fd, TCIFLUSH); - return(error); - } - -+static Gpm_Type *get_mouse_type(char *name) -+{ -+ Gpm_Type *type; - -+ for (type = mice; type->fun; type++) { -+ if (strcmp(type->name, name) == 0) -+ return(type); -+ } -+ return NULL; -+} -+ - /* 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 Gpm_Type *I_ps2(int fd, unsigned short flags_unused, -+ struct Gpm_Type *type, int argc, char **argv) - { -- int id; -- static unsigned char basic_init[] = { GPM_AUX_ENABLE_DEV, GPM_AUX_SET_SAMPLE, 100 }; -- static unsigned char imps2_init[] = { GPM_AUX_SET_SAMPLE, 200, GPM_AUX_SET_SAMPLE, 100, GPM_AUX_SET_SAMPLE, 80, }; -- 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)); -- -- /* Now try again and make sure we have a PS/2 mouse */ -- if (write_to_mouse(fd, basic_init, sizeof (basic_init)) != 0) { -- gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_INIT); -- return(NULL); -- } -+ int id, error = 0, rate; -+ -+ /* Flush any existing input. */ -+ tcflush(fd, TCIOFLUSH); - -- /* Try to switch to 3 button mode */ -- if (write_to_mouse(fd, imps2_init, sizeof (imps2_init)) != 0) { -- gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_FAILED); -+ if (write_ps2(fd, GPM_AUX_DEFAULTS, '\0', 1, 1, -1)) { -+ gpm_report(GPM_PR_ERR, "PS/2 mouse failed init"); - return(NULL); - } - -- /* Read the mouse id */ -- id = read_mouse_id(fd); -- if (id == GPM_AUX_ID_ERROR) { -- gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_MID_FAIL); -- id = GPM_AUX_ID_PS2; -+ // Magic to enable the IMPS/2 protocol. -+ if ((!strcmp(type->name, "imps2")) || (!strcmp(type->name, "autops2"))) { -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 200, 2, 2, -1); -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 100, 2, 2, -1); -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 80, 2, 2, -1); -+ if (error) { -+ gpm_report(GPM_PR_ERR, "imps2: PS/2 mouse failed (3 button) init"); -+ return(NULL); -+ } - } -- -- /* And do the real initialisation */ -- if (write_to_mouse(fd, ps2_init, sizeof (ps2_init)) != 0) { -- gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_SETUP_FAIL); -+ if ((!strcmp(type->name, "exps2")) || (!strcmp(type->name, "autops2"))) { -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 200, 2, 2, -1); -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 200, 2, 2, -1); -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 80, 2, 2, -1); -+ if (error) { -+ gpm_report(GPM_PR_ERR, "exps2: PS/2 mouse failed (3 button) init"); -+ return (NULL); -+ } - } - -- 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; -- } -- if (id != GPM_AUX_ID_PS2) { -- gpm_report(GPM_PR_ERR,GPM_MESS_IMPS2_BAD_ID, id); -+ if (write_ps2(fd, GPM_AUX_SET_SCALE11, '\0', 1, 1, -1)) { -+ gpm_report(GPM_PR_ERR, "PS/2 mouse failed init: Unable to set 1:1 scale."); -+ return (NULL); -+ } -+ -+ if (which_mouse->opt_sample > 0) { -+ if (which_mouse->opt_sample >= 200) rate = 200; -+ else if (which_mouse->opt_sample >= 100) rate = 100; -+ else if (which_mouse->opt_sample >= 80) rate = 80; -+ else if (which_mouse->opt_sample >= 60) rate = 60; -+ else if (which_mouse->opt_sample >= 40) rate = 40; -+ else if (which_mouse->opt_sample >= 20) rate = 20; -+ else if (which_mouse->opt_sample >= 10) rate = 10; -+ else rate = 100; -+ } else { -+ rate = 100; -+ } -+ -+ if (write_ps2(fd, GPM_AUX_SET_SAMPLE, rate, 2, 1, -1)) { -+ gpm_report(GPM_PR_ERR, "PS/2 mouse failed init: Unable to set rate."); -+ return (NULL); -+ } -+ -+ if (!strcmp(type->name, "autops2")) { -+ /* Read the mouse id */ -+ id = read_mouse_id(fd); -+ -+ switch (id) { -+ case GPM_AUX_ID_ERROR: -+ gpm_report(GPM_PR_ERR, "Unable to read PS/2 mouse ID: Using base PS/2 protocol.\n"); -+ write_ps2(fd, GPM_AUX_SET_STREAM, '\0', 1, 1, 1); -+ write_ps2(fd, GPM_AUX_ENABLE_DEV, '\0', 1, 1, 1); -+ return get_mouse_type("ps2"); -+ case GPM_AUX_ID_PS2: -+ gpm_report(GPM_PR_INFO, "Detected base PS/2 protocol mouse."); -+ write_ps2(fd, GPM_AUX_SET_STREAM, '\0', 1, 1, 1); -+ write_ps2(fd, GPM_AUX_ENABLE_DEV, '\0', 1, 1, 1); -+ return get_mouse_type("ps2"); -+ case GPM_AUX_ID_IMPS2: -+ gpm_report(GPM_PR_INFO, "Detected IMPS/2 protocol mouse."); -+ write_ps2(fd, GPM_AUX_SET_STREAM, '\0', 1, 1, 1); -+ write_ps2(fd, GPM_AUX_ENABLE_DEV, '\0', 1, 1, 1); -+ return get_mouse_type("imps2"); -+ case GPM_AUX_ID_EXPS2: -+ gpm_report(GPM_PR_INFO, "Detected EXPS/2 protocol mouse."); -+ write_ps2(fd, GPM_AUX_SET_STREAM, '\0', 1, 1, 1); -+ write_ps2(fd, GPM_AUX_ENABLE_DEV, '\0', 1, 1, 1); -+ return get_mouse_type("exps2"); -+ default: -+ gpm_report(GPM_PR_ERR, "Unknown mouse ID, using base PS/2 protocol."); -+ write_ps2(fd, GPM_AUX_SET_STREAM, '\0', 1, 1, 1); -+ write_ps2(fd, GPM_AUX_ENABLE_DEV, '\0', 1, 1, 1); -+ return get_mouse_type("ps2"); -+ } - } -- else gpm_report(GPM_PR_INFO,GPM_MESS_IMPS2_PS2); - -- for (type=mice; type->fun; type++) -- if (strcmp(type->name, "ps2") == 0) return(type); -+ write_ps2(fd, GPM_AUX_SET_STREAM, '\0', 1, 1, 1); -+ write_ps2(fd, GPM_AUX_ENABLE_DEV, '\0', 1, 1, 1); - -- /* ps2 was not found!!! */ -- return(NULL); -+ return type; - } - --/* -- * 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) -+/* PS/2 Init */ -+static Gpm_Type *I_fuimps2(int fd, unsigned short flags, -+ struct Gpm_Type *type, int argc, char **argv) - { -- static unsigned char s1[] = { 243, 200, 243, 200, 243, 80, }; -+ int error = 0; - - if (check_no_argv(argc, argv)) return NULL; - -- write (fd, s1, sizeof (s1)); -- usleep (30000); -- tcflush (fd, TCIFLUSH); -+ // Magic to enable the IMPS/2 protocol. -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 200, 2, 2, -1); -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 100, 2, 2, -1); -+ error += write_ps2(fd, GPM_AUX_SET_SAMPLE, 80, 2, 2, -1); -+ if (error) -+ gpm_report(GPM_PR_ERR, "fuimps2: %d errors in init, ignoring.", error); -+ - return type; - } - -@@ -2409,9 +2484,12 @@ - "", M_evdev, I_empty, STD_FLG, - {0x00, 0x00, 0x00, 0x00} , 16, 16, 0, 0, NULL}, - #endif /* HAVE_LINUX_INPUT_H */ -- {"exps2", "IntelliMouse Explorer (ps2) - 3 buttons, wheel unused", -- "ExplorerPS/2", M_imps2, I_exps2, STD_FLG, -- {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0}, -+ {"exps2", "IntelliMouse Explorer (ps2) - 3 buttons (wheel is repeated).", -+ "ExplorerPS/2", M_imps2, I_ps2, STD_FLG, -+ {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0}, -+ {"autops2","For PS/2 type mouse, specific protocol will be auto detected", -+ "", M_ps2, I_ps2, STD_FLG, -+ {0xc0, 0x00, 0x00, 0x00}, 3, 1, 0, 0, 0}, - #ifdef HAVE_LINUX_JOYSTICK_H - {"js", "For joystick mouse emulation", - "Joystick", M_js, NULL, 0, -@@ -2423,10 +2501,14 @@ - {"gunze", "Gunze touch-screens (only button-1 events, by now)", - "", M_gunze, I_gunze, STD_FLG, - {0xF9, 0x50, 0xF0, 0x30}, 11, 1, 0, 1, NULL}, -- {"imps2","For the Microsoft IntelliMouse on a PS/2 port (round\n" -- " connector with 6 pins), 3 buttons (wheel is repeated).", -- "", M_imps2, I_imps2, STD_FLG, -+ {"imps2","For the Microsoft IntelliMouse on a PS/2 port\n" -+ "(round connector with 6 pins), 3 buttons (wheel is repeated).", -+ "", M_imps2, I_ps2, STD_FLG, - {0xC0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, R_imps2}, -+ {"fuimps2","For BROKEN wheel mice on a PS/2 port\n" -+ "(round connector with 6 pins), 3 buttons (wheel is repeated).", -+ "", M_imps2, I_fuimps2, STD_FLG, -+ {0xc0, 0x00, 0x00, 0x00}, 4, 1, 0, 0, 0}, - {"logi", "For old serial Logitech mice.", - "Logitech", M_logi, I_logi, CS8 | CSTOPB | STD_FLG, - {0xe0, 0x80, 0x80, 0x00}, 3, 3, 0, 0, 0}, -@@ -2463,10 +2545,12 @@ - " Try it if '-t ms' does not work.", - "", M_bare, I_pnp, CS7 | STD_FLG, - {0x40, 0x40, 0x40, 0x00}, 3, 1, 0, 0, 0}, -- {"ps2", "For most busmice connected to a PS/2 port (round with 6 metal\n" -- " pins).", -+ {"ps2", "For PS/2 mice (round with 6 metal pins).\n", - "PS/2", M_ps2, I_ps2, STD_FLG, - {0xc0, 0x00, 0x00, 0x00}, 3, 1, 0, 0, R_ps2}, -+ {"fups2", "For /BROKEN/ PS/2 mice (round with 6 metal pins).\n", -+ "PS/2", M_ps2, I_empty, STD_FLG, -+ {0xc0, 0x00, 0x00, 0x00}, 3, 1, 0, 0, 0}, - {"sun", "For Sun (Sparc) mice.", - "", M_sun, I_serial, CS8 | CSTOPB | STD_FLG, - {0xf8, 0x80, 0x00, 0x00}, 3, 1, 0, 0, R_sun}, ---- a/src/daemon/processmouse.c -+++ b/src/daemon/processmouse.c -@@ -46,6 +46,7 @@ - static int fine_dx, - fine_dy, - i, j, m, -+ obuttons, - newB=0, /* old buttons and Type to chain events */ - oldB=0, - oldT=0; -@@ -91,8 +92,18 @@ - event->modifiers = nEvent.modifiers; /* propagate modifiers */ - - /* propagate buttons */ -+ /* Change the button order */ -+ obuttons = nEvent.buttons; -+ nEvent.buttons = 0; -+ for (j = 0; j < 8; j++) { -+ if (obuttons & (1 << j)) { -+ nEvent.buttons |= which_mouse->opt_buts[j]; -+ } -+ } -+#if 0 - nEvent.buttons = ((which_mouse->opt_sequence)[nEvent.buttons&7]&7) | - (nEvent.buttons & ~7); /* change the order */ -+#endif - oldB=newB; newB=nEvent.buttons; - if (!i) event->buttons=nEvent.buttons; - ---- a/src/headers/daemon.h -+++ b/src/headers/daemon.h -@@ -97,6 +97,7 @@ - char *opt_options; /* extra textual configuration */ - Gpm_Type *m_type; - int fd; -+ int opt_buts[9]; - }; - - /*************************************************************************