source: mainline/uspace/srv/kbd/generic/kbd.c@ 8026731

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8026731 was 8026731, checked in by Martin Decky <martin@…>, 16 years ago

blocking connection to cir_service

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Copyright (c) 2006 Josef Cejka
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @addtogroup kbdgen generic
31 * @brief HelenOS generic uspace keyboard handler.
32 * @ingroup kbd
33 * @{
34 */
35/** @file
36 */
37
38#include <ipc/ipc.h>
39#include <ipc/services.h>
40#include <sysinfo.h>
41#include <stdio.h>
42#include <unistd.h>
43#include <stdlib.h>
44#include <stdio.h>
45#include <ipc/ns.h>
46#include <async.h>
47#include <errno.h>
48#include <libadt/fifo.h>
49#include <kbd/kbd.h>
50#include <kbd/keycode.h>
51
52#include <kbd.h>
53#include <key_buffer.h>
54#include <kbd_port.h>
55#include <kbd_ctl.h>
56#include <layout.h>
57
58#define NAME "kbd"
59
60int cons_connected = 0;
61int phone2cons = -1;
62keybuffer_t keybuffer;
63
64/** Currently active modifiers. */
65static unsigned mods = KM_NUM_LOCK;
66
67/** Currently pressed lock keys. We track these to tackle autorepeat. */
68static unsigned lock_keys;
69
70int cir_service = 0;
71int cir_phone = -1;
72
73void kbd_push_scancode(int scancode)
74{
75/* printf("scancode: 0x%x\n", scancode);*/
76 kbd_ctl_parse_scancode(scancode);
77}
78
79void kbd_push_ev(int type, unsigned int key)
80{
81 kbd_event_t ev;
82 unsigned mod_mask;
83
84 switch (key) {
85 case KC_LCTRL: mod_mask = KM_LCTRL; break;
86 case KC_RCTRL: mod_mask = KM_RCTRL; break;
87 case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
88 case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
89 case KC_LALT: mod_mask = KM_LALT; break;
90 case KC_RALT: mod_mask = KM_RALT; break;
91 default: mod_mask = 0; break;
92 }
93
94 if (mod_mask != 0) {
95 if (type == KE_PRESS)
96 mods = mods | mod_mask;
97 else
98 mods = mods & ~mod_mask;
99 }
100
101 switch (key) {
102 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
103 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
104 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
105 default: mod_mask = 0; break;
106 }
107
108 if (mod_mask != 0) {
109 if (type == KE_PRESS) {
110 /*
111 * Only change lock state on transition from released
112 * to pressed. This prevents autorepeat from messing
113 * up the lock state.
114 */
115 mods = mods ^ (mod_mask & ~lock_keys);
116 lock_keys = lock_keys | mod_mask;
117 } else {
118 lock_keys = lock_keys & ~mod_mask;
119 }
120 }
121/*
122 printf("type: %d\n", type);
123 printf("mods: 0x%x\n", mods);
124 printf("keycode: %u\n", key);
125*/
126 ev.type = type;
127 ev.key = key;
128 ev.mods = mods;
129
130 ev.c = layout_parse_ev(&ev);
131
132 async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
133}
134
135static void console_connection(ipc_callid_t iid, ipc_call_t *icall)
136{
137 ipc_callid_t callid;
138 ipc_call_t call;
139 int retval;
140
141 if (cons_connected) {
142 ipc_answer_0(iid, ELIMIT);
143 return;
144 }
145 cons_connected = 1;
146 ipc_answer_0(iid, EOK);
147
148 while (1) {
149 callid = async_get_call(&call);
150 switch (IPC_GET_METHOD(call)) {
151 case IPC_M_PHONE_HUNGUP:
152 cons_connected = 0;
153 ipc_hangup(phone2cons);
154 phone2cons = -1;
155 ipc_answer_0(callid, EOK);
156 return;
157 case IPC_M_CONNECT_TO_ME:
158 if (phone2cons != -1) {
159 retval = ELIMIT;
160 break;
161 }
162 phone2cons = IPC_GET_ARG5(call);
163 retval = 0;
164 break;
165 default:
166 retval = EINVAL;
167 }
168 ipc_answer_0(callid, retval);
169 }
170}
171
172
173int main(int argc, char **argv)
174{
175 printf(NAME ": HelenOS Keyboard service\n");
176
177 ipcarg_t phonead;
178
179 if (sysinfo_value("kbd.cir.fhc") == 1)
180 cir_service = SERVICE_FHC;
181 else if (sysinfo_value("kbd.cir.obio") == 1)
182 cir_service = SERVICE_OBIO;
183
184 if (cir_service) {
185 while (cir_phone < 0) {
186 cir_phone = ipc_connect_me_to_blocking(PHONE_NS, cir_service,
187 0, 0);
188 }
189 }
190
191 /* Initialize port driver. */
192 if (kbd_port_init())
193 return -1;
194
195 /* Initialize key buffer */
196 keybuffer_init(&keybuffer);
197
198 async_set_client_connection(console_connection);
199
200 /* Register service at nameserver. */
201 if (ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, 0, &phonead) != 0)
202 return -1;
203
204 printf(NAME ": Accepting connections\n");
205 async_manager();
206
207 /* Not reached. */
208 return 0;
209}
210
211/**
212 * @}
213 */
Note: See TracBrowser for help on using the repository browser.