Messages in this thread Patch in this message | | | Date | Sun, 30 Jul 2000 22:05:12 +0200 | From | Pavel Machek <> | Subject | Re: pc_keyb.c 3 button mouse emulation |
| |
Hi!
> I would like to use the "Windows" key on my PC compatible notebook as the > middle mouse button. I would prefer to do this at the driver level as is > done on the Macintosh port rather than at the application level.
BAD idea.
Such emulation belongs to gpm -R, then X can see already "emulated" features. Notice that what you want is very similar to me wanting mouse-on-keyboard emulation [and you definitely don't want *that* in kernelspace, do you].
I actually did mouse-on-keyboard emulation with trivial patch called keylink some time ago. [It basically created /dev/keylink and whenever you pressed interesting key it send char through that device].
> Anyway, I am hoping that one of the current maintainers of this code might > see the use in such a feature and help. Since the ps/2 mouse and keyboard > drivers are now part of the same file, this hack may not even be so ugly. > If there is an existing way to do what I am wanting, then I apologize for > this message, but would then like very much to know what that way is.
I hope this hack does not get through. Doing it right (userspace) would be much better.
Pavel [here it is, for reference; I do even have mouse emulation daemon, and it was really trivial with gpm's "mix two mice into one" feature] Hi!
I've created simple way for keyboard to talk to userland. I used to use kerneld, but there is no such thing any more. It allows for example pasting from keyboard (really usefull - mouse is usefull for text selection, but why touch it for pasting of text?), I also use it for mouse emulation on keyboard.
It also includes my previous blank-from-keyboard patch, and it does mirror cleaning up of peaces it touches.
Pavel PS: relative to 2.1.90.
--- /dev/null Sun Jun 2 15:30:20 1996 +++ linux/drivers/char/keylink.c Sun Mar 22 16:26:16 1998 @@ -0,0 +1,128 @@ +/* + * Keylink - for making keyboard combinations call userland + * + * Copyright 1998 Pavel Machek <pavel@ucw.cz>, distribute + * under terms of GPL + * + * Loosely based on msbusmouse.c. + */ + +#include <linux/module.h> + +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/errno.h> +#include <linux/miscdevice.h> +#include <linux/random.h> +#include <linux/poll.h> +#include <linux/init.h> + +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/irq.h> + +static struct wait_queue *wait; +static int active = 0; + +#define RING 0x100 +static char ringbuf[ RING ]; +static int head = 0, tail = 0; + +#define INC( a ) a = (a+1) & (RING-1) + +void keylink_pushkey( char c ) +{ + INC( head ); + if (head == tail) + printk( "keylink: ring buffer overrun, keys lost\n" ); + ringbuf[ head ] = c; + wake_up_interruptible(&wait); +} + +static int release_keylink(struct inode * inode, struct file * file) +{ + if (--active) + return 0; + MOD_DEC_USE_COUNT; + return 0; +} + +static int open_keylink(struct inode * inode, struct file * file) +{ + if (active++) + return 0; + MOD_INC_USE_COUNT; + return 0; +} + +static ssize_t write_keylink(struct file * file, + const char * buffer, size_t count, loff_t *ppos) +{ + return -EINVAL; +} + +static ssize_t read_keylink(struct file * file, + char * buffer, size_t count, loff_t *ppos) +{ + int i; + + if (head==tail) + interruptible_sleep_on( &wait ); + for (i = 0; i < count; i++) { + if (head==tail) + break; + INC( tail ); + put_user(ringbuf[tail], buffer + i); + } + return i; +} + +static unsigned int keylink_poll(struct file *file, poll_table * local_wait) +{ + poll_wait(file, &wait, local_wait); + return 0; +} + +struct file_operations keylink_fops = { + NULL, /* keylink_seek */ + read_keylink, + write_keylink, + NULL, /* keylink_readdir */ + keylink_poll, /* keylink_poll */ + NULL, /* keylink_ioctl */ + NULL, /* keylink_mmap */ + open_keylink, + release_keylink, + NULL, +}; + +static struct miscdevice misc_keylink = { + KEYLINK_MINOR, "keylink", &keylink_fops +}; + +__initfunc(int keylink_init(void)) +{ + head = tail = 0; + wait = NULL; + + + printk(KERN_INFO "Keylink installed.\n"); + misc_register(&misc_keylink); + return 0; +} + +#ifdef MODULE +int init_module(void) +{ + return keylink_init(); +} + +void cleanup_module(void) +{ + misc_deregister(&misc_keylink); +} +#endif + --- clean/drivers/char/Config.in Wed Mar 18 12:56:09 1998 +++ linux/drivers/char/Config.in Sun Mar 22 19:18:46 1998 @@ -7,6 +7,7 @@ bool 'Virtual terminal' CONFIG_VT if [ "$CONFIG_VT" = "y" ]; then bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE + bool 'Keylink support' CONFIG_KEYLINK fi tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL if [ "$CONFIG_SERIAL" = "y" ]; then diff -u clean/drivers/char/Makefile linux/drivers/char/Makefile --- clean/drivers/char/Makefile Wed Jan 14 21:45:43 1998 +++ linux/drivers/char/Makefile Sun Mar 22 19:20:49 1998 @@ -39,6 +39,10 @@ ifndef CONFIG_SUN_KEYBOARD ifdef CONFIG_VT +ifdef CONFIG_KEYLINK +L_OBJS += keylink.o +M = y +endif L_OBJS += keyboard.o endif ifneq ($(ARCH),m68k) diff -u clean/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- clean/drivers/char/keyboard.c Thu Feb 12 12:32:35 1998 +++ linux/drivers/char/keyboard.c Sun Mar 22 21:24:31 1998 @@ -19,6 +19,8 @@ * parts by Geert Uytterhoeven, May 1997 * * 27-05-97: Added support for the Magic SysRq Key (Martin Mares) + * + * 29-07-97: Added blank console key and possiblity to call userland (Pavel Machek) */ #include <linux/config.h> @@ -104,31 +107,33 @@ static k_handfn do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, - do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_ignore; + do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_keylink, do_ignore; static k_hand key_handler[16] = { do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift, do_meta, do_ascii, do_lock, do_lowercase, do_slock, - do_ignore, do_ignore, do_ignore + do_keylink, do_ignore, do_ignore }; /* Key types processed even in raw modes */ -#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT)) +#define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT) | (1 << 13)) typedef void (*void_fnp)(void); typedef void (void_fn)(void); static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, - SAK, decr_console, incr_console, spawn_console, bare_num; + SAK, decr_console, incr_console, spawn_console, bare_num, + blank_now; static void_fnp spec_fn_table[] = { do_null, enter, show_ptregs, show_mem, show_state, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, SAK, - decr_console, incr_console, spawn_console, bare_num + decr_console, incr_console, spawn_console, bare_num, + blank_now }; #define SPECIALS_ALLOWED_IN_RAW_MODE (1 << KVAL(K_SAK)) @@ -138,7 +143,7 @@ 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1, NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, 255, - NR_LOCK - 1 + NR_LOCK - 1, 255 }; const int NR_TYPES = SIZE(max_vals); @@ -195,8 +200,11 @@ char up_flag; /* 0 or 0200 */ char raw_mode; - do_poke_blanked_console = 1; - mark_bh(CONSOLE_BH); + if (scancode < 0x80) + { + do_poke_blanked_console = 1; + mark_bh(CONSOLE_BH); + } add_keyboard_randomness(scancode); tty = ttytab[fg_console]; @@ -406,6 +414,11 @@ if (!rep) chg_vc_kbd_led(kbd,VC_NUMLOCK); } +static void blank_now(void) +{ + do_poke_blanked_console = 0; + do_blank_screen(0); +} static void lastcons(void) { @@ -490,6 +503,14 @@ #endif } +static void do_keylink(unsigned char value, char up_flag) +{ +#ifdef CONFIG_KEYLINK + if (!up_flag) + keylink_pushkey( value ); +#endif +} + static void do_ignore(unsigned char value, char up_flag) { } @@ -511,6 +532,10 @@ spec_fn_table[value](); } +/* + * You do not want to clear this procedure and reuse its place... + * this is where normal characters reside + */ static void do_lowercase(unsigned char value, char up_flag) { printk(KERN_ERR "keyboard.c: do_lowercase was called - impossible\n"); diff -u clean/drivers/char/mem.c linux/drivers/char/mem.c --- clean/drivers/char/mem.c Sun Mar 8 12:49:55 1998 +++ linux/drivers/char/mem.c Sun Mar 22 21:18:02 1998 @@ -32,9 +32,6 @@ #ifdef CONFIG_ISDN int isdn_init(void); #endif -#ifdef CONFIG_PCWATCHDOG -int pcwatchdog_init(void); -#endif #ifdef CONFIG_VIDEO_DEV extern int videodev_init(void); #endif @@ -532,7 +529,8 @@ defined (CONFIG_AMIGAMOUSE) || defined (CONFIG_ATARIMOUSE) || \ defined (CONFIG_PCWATCHDOG) || \ defined (CONFIG_APM) || defined (CONFIG_RTC) || \ - defined (CONFIG_SUN_MOUSE) || defined (CONFIG_NVRAM) + defined (CONFIG_SUN_MOUSE) || defined (CONFIG_NVRAM) || \ + defined (CONFIG_KEYLINK) misc_init(); #endif #ifdef CONFIG_SOUND diff -u clean/drivers/char/misc.c linux/drivers/char/misc.c --- clean/drivers/char/misc.c Wed Mar 18 12:56:09 1998 +++ linux/drivers/char/misc.c Sun Mar 22 21:16:05 1998 @@ -81,9 +85,7 @@ extern int nvram_init(void); extern int radio_init(void); extern void hfmodem_init(void); -#ifdef CONFIG_PC110_PAD extern int pc110pad_init(void); -#endif #ifdef CONFIG_PROC_FS static int misc_read_proc(char *buf, char **start, off_t offset, @@ -269,6 +271,9 @@ #endif #ifdef CONFIG_HFMODEM hfmodem_init(); +#endif +#ifdef CONFIG_KEYLINK + keylink_init(); #endif #endif /* !MODULE */ if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { --- clean/include/linux/miscdevice.h Wed Jan 14 21:46:06 1998 +++ linux/include/linux/miscdevice.h Sun Mar 22 00:05:47 1998 @@ -9,6 +9,7 @@ #define ATARIMOUSE_MINOR 5 #define SUN_MOUSE_MINOR 6 #define PC110PAD_MINOR 9 +#define KEYLINK_MINOR 127 #define WATCHDOG_MINOR 130 /* Watchdog timer */ #define TEMP_MINOR 131 /* Temperature Sensor */ #define RTC_MINOR 135 --- kbd-0.93/src/ksyms.c.ofic Fri Apr 4 22:14:02 1997 +++ kbd-0.93/src/ksyms.c Sun Mar 22 13:44:49 1998 @@ -714,7 +714,7 @@ }; static char *spec_syms[] = { - "VoidSymbol", + "VoidSymbol", /* 0 */ "Return", "Show_Registers", "Show_Memory", @@ -724,7 +724,7 @@ "Caps_Lock", "Num_Lock", "Scroll_Lock", - "Scroll_Forward", + "Scroll_Forward", /* 10 */ "Scroll_Backward", "Boot", "Caps_On", @@ -733,7 +733,17 @@ "Decr_Console", "Incr_Console", "Spawn_Console", - "Bare_Num_Lock" + "Bare_Num_Lock", + "Blank_Now", /* 20 */ + "__Spec_21", + "__Spec_22", + "__Spec_23", + "__Spec_24", + "__Spec_25", + "__Spec_26", + "__Spec_27", + "__Spec_28", + "__Spec_29" }; static char *pad_syms[] = { @@ -1033,6 +1043,265 @@ "SCtrlR" }; +static char *keylink_syms[] = { + "Keylink_Paste", /* 0 */ + "Keylink_LeftDown", + "Keylink_Down", + "Keylink_RightDown", + "Keylink_Left", + "Keylink_5", /* 5 */ + "Keylink_Right", + "Keylink_LeftUp", + "Keylink_Up", + "Keylink_RightUp", + "Keylink_Fast_LeftDown",/* 10 */ + "Keylink_Fast_Down", + "Keylink_Fast_RightDown", + "Keylink_Fast_Left", + "Keylink_14", + "Keylink_Fast_Right", /* 15 */ + "Keylink_Fast_LeftUp", + "Keylink_Fast_Up", + "Keylink_Fast_RightUp", + "Keylink_19", + "Keylink_Click_1", /* 20 */ + "Keylink_Click_2", + "Keylink_Click_3", + "Keylink_Toggle_1", + "Keylink_Toggle_2", + "Keylink_Toggle_3", + "Keylink_DoubleClick_1", + "Keylink_DoubleClick_2", + "Keylink_DoubleClick_3", + "Keylink_29", + "Keylink_30", + "Keylink_31", + "Keylink_32", + "Keylink_33", + "Keylink_34", + "Keylink_35", + "Keylink_36", + "Keylink_37", + "Keylink_38", + "Keylink_39", + "Keylink_40", + "Keylink_41", + "Keylink_42", + "Keylink_43", + "Keylink_44", + "Keylink_45", + "Keylink_46", + "Keylink_47", + "Keylink_48", + "Keylink_49", + "Keylink_50", + "Keylink_51", + "Keylink_52", + "Keylink_53", + "Keylink_54", + "Keylink_55", + "Keylink_56", + "Keylink_57", + "Keylink_58", + "Keylink_59", + "Keylink_60", + "Keylink_61", + "Keylink_62", + "Keylink_63", + "Keylink_64", + "Keylink_65", + "Keylink_66", + "Keylink_67", + "Keylink_68", + "Keylink_69", + "Keylink_70", + "Keylink_71", + "Keylink_72", + "Keylink_73", + "Keylink_74", + "Keylink_75", + "Keylink_76", + "Keylink_77", + "Keylink_78", + "Keylink_79", + "Keylink_80", + "Keylink_81", + "Keylink_82", + "Keylink_83", + "Keylink_84", + "Keylink_85", + "Keylink_86", + "Keylink_87", + "Keylink_88", + "Keylink_89", + "Keylink_90", + "Keylink_91", + "Keylink_92", + "Keylink_93", + "Keylink_94", + "Keylink_95", + "Keylink_96", + "Keylink_97", + "Keylink_98", + "Keylink_99", + "Keylink_100", + "Keylink_101", + "Keylink_102", + "Keylink_103", + "Keylink_104", + "Keylink_105", + "Keylink_106", + "Keylink_107", + "Keylink_108", + "Keylink_109", + "Keylink_110", + "Keylink_111", + "Keylink_112", + "Keylink_113", + "Keylink_114", + "Keylink_115", + "Keylink_116", + "Keylink_117", + "Keylink_118", + "Keylink_119", + "Keylink_120", + "Keylink_121", + "Keylink_122", + "Keylink_123", + "Keylink_124", + "Keylink_125", + "Keylink_126", + "Keylink_127", + "Keylink_128", + "Keylink_129", + "Keylink_130", + "Keylink_131", + "Keylink_132", + "Keylink_133", + "Keylink_134", + "Keylink_135", + "Keylink_136", + "Keylink_137", + "Keylink_138", + "Keylink_139", + "Keylink_140", + "Keylink_141", + "Keylink_142", + "Keylink_143", + "Keylink_144", + "Keylink_145", + "Keylink_146", + "Keylink_147", + "Keylink_148", + "Keylink_149", + "Keylink_150", + "Keylink_151", + "Keylink_152", + "Keylink_153", + "Keylink_154", + "Keylink_155", + "Keylink_156", + "Keylink_157", + "Keylink_158", + "Keylink_159", + "Keylink_160", + "Keylink_161", + "Keylink_162", + "Keylink_163", + "Keylink_164", + "Keylink_165", + "Keylink_166", + "Keylink_167", + "Keylink_168", + "Keylink_169", + "Keylink_170", + "Keylink_171", + "Keylink_172", + "Keylink_173", + "Keylink_174", + "Keylink_175", + "Keylink_176", + "Keylink_177", + "Keylink_178", + "Keylink_179", + "Keylink_180", + "Keylink_181", + "Keylink_182", + "Keylink_183", + "Keylink_184", + "Keylink_185", + "Keylink_186", + "Keylink_187", + "Keylink_188", + "Keylink_189", + "Keylink_190", + "Keylink_191", + "Keylink_192", + "Keylink_193", + "Keylink_194", + "Keylink_195", + "Keylink_196", + "Keylink_197", + "Keylink_198", + "Keylink_199", + "Keylink_200", + "Keylink_201", + "Keylink_202", + "Keylink_203", + "Keylink_204", + "Keylink_205", + "Keylink_206", + "Keylink_207", + "Keylink_208", + "Keylink_209", + "Keylink_210", + "Keylink_211", + "Keylink_212", + "Keylink_213", + "Keylink_214", + "Keylink_215", + "Keylink_216", + "Keylink_217", + "Keylink_218", + "Keylink_219", + "Keylink_220", + "Keylink_221", + "Keylink_222", + "Keylink_223", + "Keylink_224", + "Keylink_225", + "Keylink_226", + "Keylink_227", + "Keylink_228", + "Keylink_229", + "Keylink_230", + "Keylink_231", + "Keylink_232", + "Keylink_233", + "Keylink_234", + "Keylink_235", + "Keylink_236", + "Keylink_237", + "Keylink_238", + "Keylink_239", + "Keylink_240", + "Keylink_241", + "Keylink_242", + "Keylink_243", + "Keylink_244", + "Keylink_245", + "Keylink_246", + "Keylink_247", + "Keylink_248", + "Keylink_249", + "Keylink_250", + "Keylink_251", + "Keylink_252", + "Keylink_253", + "Keylink_254", + "Keylink_255" }; + + #define E(x) { x, sizeof(x) / sizeof(char **) } syms_entry syms[] = { @@ -1048,7 +1317,8 @@ E(ascii_syms), E(lock_syms), { 0, 0 }, - E(sticky_syms) + E(sticky_syms), + E(keylink_syms) }; #undef E -- I'm pavel@ucw.cz. "In my country we have almost anarchy and I don't care." Panos Katsaloulis describing me w.r.t. patents at discuss@linmodems.org
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |