source: mainline/kbd/generic/kbd.c@ 5bd03eb

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5bd03eb was 80649a91, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Merged libadt into libc.
Made lot of psthread and thread stuff thread-safe.
Added new driver framework for easy C connection programming.
Changed FB code to use new API.

  • Property mode set to 100644
File size: 4.7 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#include <ipc/ipc.h>
30#include <ipc/services.h>
31#include <stdio.h>
32#include <unistd.h>
33#include <stdlib.h>
34#include <ipc/ns.h>
35#include <errno.h>
36#include <arch/kbd.h>
37#include <kbd.h>
38#include <key_buffer.h>
39#include <libadt/fifo.h>
40
41#define NAME "KBD"
42
43#define KBD_REQUEST_MAX 32 /**< Maximum requests buffered until keypress */
44
45int main(int argc, char **argv)
46{
47 ipc_call_t call;
48 ipc_callid_t callid;
49 char connected = 0;
50 int res;
51 int c;
52 ipcarg_t phonead;
53
54 ipcarg_t retval, arg1, arg2;
55
56 /* Counter of unsatisfied calls */
57 fifo_count_t callers_counter = 0;
58 /* Fifo with callid's of unsatisfied calls requred for answer */
59 FIFO_INITIALIZE_STATIC(callers_buffer, ipc_callid_t, KBD_REQUEST_MAX);
60
61 printf("Uspace kbd service started.\n");
62
63 /* Initialize arch dependent parts */
64 if (!(res = kbd_arch_init())) {
65 printf("Kbd registration failed with retval %d.\n", res);
66 return -1;
67 };
68
69 /* Initialize key buffer */
70 key_buffer_init();
71
72 /* Register service at nameserver */
73 printf("%s: Registering at naming service.\n", NAME);
74
75 if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, &phonead)) != 0) {
76 printf("%s: Error: Registering at naming service failed.\n", NAME);
77 return -1;
78 };
79
80 while (1) {
81 callid = ipc_wait_for_call(&call);
82 // printf("%s:Call phone=%lX..", NAME, call.in_phone_hash);
83 switch (IPC_GET_METHOD(call)) {
84 case IPC_M_PHONE_HUNGUP:
85 if (connected) {
86 /* If nobody's connected, clear keybuffer and dont store new keys */
87 if (--connected == 0) {
88 callers_counter = 0;
89 callers_buffer.head = callers_buffer.tail = 0;
90 key_buffer_free();
91 }
92
93 printf("%s: Phone hung up.\n", NAME);
94 } else {
95 printf("%s: Oops, got phone hung up, but nobody connected.\n", NAME);
96 }
97
98 retval = 0;
99 break;
100 case IPC_M_CONNECT_ME_TO:
101 // printf("%s: Connect me (%P) to: %zd\n",NAME, IPC_GET_ARG3(call), IPC_GET_ARG1(call));
102 /* Only one connected client allowed */
103 if (connected) {
104 retval = ELIMIT;
105 } else {
106 retval = 0;
107 connected = 1;
108 }
109 break;
110 case IPC_M_INTERRUPT:
111 if (connected) {
112 /* recode scancode and store it into key buffer */
113 kbd_arch_process(IPC_GET_ARG2(call));
114 //printf("%s: GOT INTERRUPT: %c\n", NAME, IPC_GET_ARG2(call));
115
116 /* Some callers could awaiting keypress - if its true, we have to send keys to them.
117 * One interrupt can store more than one key into buffer. */
118 retval = 0;
119 arg2 = 0xbeef;
120 while ((callers_counter) && (!key_buffer_empty())) {
121 callers_counter--;
122 if (!key_buffer_pop((char *)&arg1)) {
123 printf("%s: KeyBuffer empty but it should not be.\n");
124 break;
125 }
126 ipc_answer_fast(fifo_pop(callers_buffer), retval, arg1, arg2);
127 }
128 }
129 break;
130 case KBD_GETCHAR:
131 // printf("%s: Getchar: ", NAME);
132 retval = 0;
133 arg1 = 0;
134 if (!key_buffer_pop((char *)&arg1)) {
135 if (callers_counter < KBD_REQUEST_MAX) {
136 callers_counter++;
137 fifo_push(callers_buffer, callid);
138 } else {
139 retval = ELIMIT;
140 }
141 continue;
142 };
143 arg2 = 0xbeef;
144 // printf("GetChar return %c\n", arg1);
145
146 break;
147 default:
148 printf("%s: Unknown method: %zd\n", NAME, IPC_GET_METHOD(call));
149 retval = ENOENT;
150 break;
151 }
152
153 if (! (callid & IPC_CALLID_NOTIFICATION)) {
154 ipc_answer_fast(callid, retval, arg1, arg2);
155 }
156 }
157}
158
Note: See TracBrowser for help on using the repository browser.