1 |
/* pc-kbd.c - The PC Keyboard input driver. |
/* pc-kbd.c - The PC Keyboard input driver. |
2 |
Copyright (C) 2002, 2004 Free Software Foundation, Inc. |
Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. |
3 |
Written by Marcus Brinkmann. |
Written by Marcus Brinkmann. |
4 |
|
|
5 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
23 |
#include <string.h> |
#include <string.h> |
24 |
#include <iconv.h> |
#include <iconv.h> |
25 |
#include <sys/mman.h> |
#include <sys/mman.h> |
26 |
|
#include <argp.h> |
27 |
|
|
28 |
#include <device/device.h> |
#include <device/device.h> |
29 |
#include <cthreads.h> |
#include <cthreads.h> |
32 |
#include <hurd/cons.h> |
#include <hurd/cons.h> |
33 |
|
|
34 |
#include "driver.h" |
#include "driver.h" |
35 |
|
#include "mach-inputdev.h" |
36 |
|
|
37 |
|
|
38 |
|
/* The default name of the node of the repeater. */ |
39 |
|
#define DEFAULT_REPEATER_NODE "kbd" |
40 |
|
|
41 |
/* The keyboard device in the kernel. */ |
/* The keyboard device in the kernel. */ |
42 |
static device_t kbd_dev; |
static device_t kbd_dev; |
43 |
|
|
57 |
/* Forward declaration. */ |
/* Forward declaration. */ |
58 |
static struct input_ops pc_kbd_ops; |
static struct input_ops pc_kbd_ops; |
59 |
|
|
60 |
|
/* The name of the repeater node. */ |
61 |
|
static char *repeater_node; |
62 |
|
|
63 |
|
/* The repeater node. */ |
64 |
|
static consnode_t cnode; |
65 |
|
|
66 |
/* A list of scan codes generated by the keyboard, in the set 2 encoding. */ |
/* A list of scan codes generated by the keyboard, in the set 2 encoding. */ |
67 |
enum scancode |
enum scancode |
568 |
SC_X1_DEL |
SC_X1_DEL |
569 |
}; |
}; |
570 |
|
|
|
|
|
|
/* This gross stuff is cut & pasted from Mach sources, as Mach doesn't |
|
|
export the interface we are using here. */ |
|
|
|
|
|
/* |
|
|
* Mach Operating System |
|
|
* Copyright (c) 1991,1990,1989 Carnegie Mellon University |
|
|
* All Rights Reserved. |
|
|
* |
|
|
* Permission to use, copy, modify and distribute this software and its |
|
|
* documentation is hereby granted, provided that both the copyright |
|
|
* notice and this permission notice appear in all copies of the |
|
|
* software, derivative works or modified versions, and any portions |
|
|
* thereof, and that both notices appear in supporting documentation. |
|
|
* |
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" |
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR |
|
|
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. |
|
|
* |
|
|
* Carnegie Mellon requests users of this software to return to |
|
|
* |
|
|
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU |
|
|
* School of Computer Science |
|
|
* Carnegie Mellon University |
|
|
* Pittsburgh PA 15213-3890 |
|
|
* |
|
|
* any improvements or extensions that they make and grant Carnegie Mellon |
|
|
* the rights to redistribute these changes. |
|
|
*/ |
|
|
|
|
|
typedef u_short kev_type; /* kd event type */ |
|
|
|
|
|
/* (used for event records) */ |
|
|
struct mouse_motion { |
|
|
short mm_deltaX; /* units? */ |
|
|
short mm_deltaY; |
|
|
}; |
|
|
typedef u_char Scancode; |
|
|
|
|
|
typedef struct { |
|
|
kev_type type; /* see below */ |
|
|
struct timeval time; /* timestamp */ |
|
|
union { /* value associated with event */ |
|
|
boolean_t up; /* MOUSE_LEFT .. MOUSE_RIGHT */ |
|
|
Scancode sc; /* KEYBD_EVENT */ |
|
|
struct mouse_motion mmotion; /* MOUSE_MOTION */ |
|
|
} value; |
|
|
} kd_event; |
|
|
#define m_deltaX mmotion.mm_deltaX |
|
|
#define m_deltaY mmotion.mm_deltaY |
|
|
|
|
|
/* |
|
|
* kd_event ID's. |
|
|
*/ |
|
|
#define MOUSE_LEFT 1 /* mouse left button up/down */ |
|
|
#define MOUSE_MIDDLE 2 |
|
|
#define MOUSE_RIGHT 3 |
|
|
#define MOUSE_MOTION 4 /* mouse motion */ |
|
|
#define KEYBD_EVENT 5 /* key up/down */ |
|
|
|
|
|
|
|
|
#define IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */ |
|
|
#define IOC_OUT 0x40000000 /* copy out parameters */ |
|
|
#define IOC_IN 0x80000000U /* copy in parameters */ |
|
|
#define _IOC(inout,group,num,len) \ |
|
|
(inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num)) |
|
|
#define _IOR(g,n,t) _IOC(IOC_OUT, (g), (n), sizeof(t)) |
|
|
#define _IOW(g,n,t) _IOC(IOC_IN, (g), (n), sizeof(t)) |
|
|
|
|
|
#define KDSKBDMODE _IOW('K', 1, int) /* set keyboard mode */ |
|
|
#define KB_EVENT 1 |
|
|
#define KB_ASCII 2 |
|
|
|
|
|
#define KDGKBDTYPE _IOR('K', 2, int) /* get keyboard type */ |
|
|
#define KB_VANILLAKB 0 |
|
|
|
|
|
#define KDSETLEDS _IOW('K', 5, int) /* set keyboard leds */ |
|
|
|
|
|
|
|
|
/* End of Mach code. */ |
|
|
|
|
571 |
static enum scancode |
static enum scancode |
572 |
gnumach_v1_input_next () |
gnumach_v1_input_next () |
573 |
{ |
{ |
587 |
terminate. */ |
terminate. */ |
588 |
if (err) |
if (err) |
589 |
return 0; |
return 0; |
590 |
|
|
591 |
|
if (kbd_repeater_opened && data_buf.type == KEYBD_EVENT) |
592 |
|
{ |
593 |
|
kbd_repeat_key (&data_buf); |
594 |
|
data_buf.type = 0; |
595 |
|
continue; |
596 |
|
} |
597 |
} |
} |
598 |
while (data_buf.type != KEYBD_EVENT); |
while (data_buf.type != KEYBD_EVENT); |
599 |
|
|
1026 |
|
|
1027 |
|
|
1028 |
|
|
1029 |
|
|
1030 |
|
static const char doc[] = "PC Keyboard Driver"; |
1031 |
|
|
1032 |
|
static const struct argp_option options[] = |
1033 |
|
{ |
1034 |
|
{"repeat", 'r', "NODE", OPTION_ARG_OPTIONAL, |
1035 |
|
"Set a repeater translator on NODE (default: " DEFAULT_REPEATER_NODE ")"}, |
1036 |
|
{ 0 } |
1037 |
|
}; |
1038 |
|
|
1039 |
|
static error_t |
1040 |
|
parse_opt (int key, char *arg, struct argp_state *state) |
1041 |
|
{ |
1042 |
|
int *pos = (int *) state->input; |
1043 |
|
|
1044 |
|
switch (key) |
1045 |
|
{ |
1046 |
|
case 'r': |
1047 |
|
repeater_node = arg ? arg: DEFAULT_REPEATER_NODE; |
1048 |
|
break; |
1049 |
|
|
1050 |
|
case ARGP_KEY_END: |
1051 |
|
break; |
1052 |
|
|
1053 |
|
default: |
1054 |
|
return ARGP_ERR_UNKNOWN; |
1055 |
|
} |
1056 |
|
|
1057 |
|
*pos = state->next; |
1058 |
|
return 0; |
1059 |
|
} |
1060 |
|
|
1061 |
|
static struct argp argp = {options, parse_opt, 0, doc}; |
1062 |
|
|
1063 |
/* Initialize the PC keyboard driver. */ |
/* Initialize the PC keyboard driver. */ |
1064 |
static error_t |
static error_t |
1065 |
pc_kbd_init (void **handle, int no_exit, int argc, char *argv[], int *next) |
pc_kbd_init (void **handle, int no_exit, int argc, char *argv[], int *next) |
1066 |
{ |
{ |
1067 |
|
error_t err; |
1068 |
|
int pos = 1; |
1069 |
|
|
1070 |
|
/* Parse the arguments. */ |
1071 |
|
err = argp_parse (&argp, argc, argv, ARGP_IN_ORDER | ARGP_NO_EXIT |
1072 |
|
| ARGP_SILENT, 0 , &pos); |
1073 |
|
*next += pos - 1; |
1074 |
|
|
1075 |
|
if (err && err != EINVAL) |
1076 |
|
return err; |
1077 |
|
|
1078 |
|
|
1079 |
return 0; |
return 0; |
1080 |
} |
} |
1081 |
|
|
1140 |
iconv_close (cd); |
iconv_close (cd); |
1141 |
return err; |
return err; |
1142 |
} |
} |
1143 |
|
|
1144 |
|
if (repeater_node) |
1145 |
|
kbd_setrepeater (repeater_node, &cnode); |
1146 |
|
|
1147 |
cthread_detach (cthread_fork (input_loop, NULL)); |
cthread_detach (cthread_fork (input_loop, NULL)); |
1148 |
|
|
1149 |
return 0; |
return 0; |
1163 |
mach_port_deallocate (mach_task_self (), kbd_dev); |
mach_port_deallocate (mach_task_self (), kbd_dev); |
1164 |
iconv_close (cd); |
iconv_close (cd); |
1165 |
|
|
1166 |
|
console_unregister_consnode (cnode); |
1167 |
|
console_destroy_consnode (cnode); |
1168 |
|
|
1169 |
return 0; |
return 0; |
1170 |
} |
} |
1171 |
|
|