1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997-2012 Sam Lantinga
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19    Sam Lantinga
20    slouken@libsdl.org
21*/
22#include "SDL_config.h"
23
24#include <sys/types.h>
25#include <dev/wscons/wsdisplay_usl_io.h>
26#include <sys/ioctl.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <termios.h>
30#include <errno.h>
31#include <string.h>
32
33#include "SDL.h"
34#include "../../events/SDL_sysevents.h"
35#include "../../events/SDL_events_c.h"
36#include "SDL_wsconsvideo.h"
37#include "SDL_wsconsevents_c.h"
38
39static int posted = 0;
40
41int WSCONS_InitKeyboard(_THIS)
42{
43  struct termios tty;
44
45  if (ioctl(private->fd, WSKBDIO_GTYPE, &private->kbdType) == -1) {
46    WSCONS_ReportError("cannot get keyboard type: %s", strerror(errno));
47    return -1;
48  }
49
50  if (tcgetattr(private->fd, &private->saved_tty) == -1) {
51    WSCONS_ReportError("cannot get terminal attributes: %s", strerror(errno));
52    return -1;
53  }
54  private->did_save_tty = 1;
55  tty = private->saved_tty;
56  tty.c_iflag = IGNPAR | IGNBRK;
57  tty.c_oflag = 0;
58  tty.c_cflag = CREAD | CS8;
59  tty.c_lflag = 0;
60  tty.c_cc[VTIME] = 0;
61  tty.c_cc[VMIN] = 1;
62  cfsetispeed(&tty, 9600);
63  cfsetospeed(&tty, 9600);
64  if (tcsetattr(private->fd, TCSANOW, &tty) < 0) {
65    WSCONS_ReportError("cannot set terminal attributes: %s", strerror(errno));
66    return -1;
67  }
68  if (ioctl(private->fd, KDSKBMODE, K_RAW) == -1) {
69    WSCONS_ReportError("cannot set raw keyboard mode: %s", strerror(errno));
70    return -1;
71  }
72
73  return 0;
74}
75
76void WSCONS_ReleaseKeyboard(_THIS)
77{
78  if (private->fd != -1) {
79    if (ioctl(private->fd, KDSKBMODE, K_XLATE) == -1) {
80      WSCONS_ReportError("cannot restore keyboard to translated mode: %s",
81			 strerror(errno));
82    }
83    if (private->did_save_tty) {
84      if (tcsetattr(private->fd, TCSANOW, &private->saved_tty) < 0) {
85	WSCONS_ReportError("cannot restore keynoard attributes: %s",
86			   strerror(errno));
87      }
88    }
89  }
90}
91
92static void updateMouse()
93{
94}
95
96static SDLKey keymap[128];
97
98static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
99{
100  keysym->scancode = scancode;
101  keysym->sym = SDLK_UNKNOWN;
102  keysym->mod = KMOD_NONE;
103
104  if (scancode < SDL_arraysize(keymap))
105    keysym->sym = keymap[scancode];
106
107  if (keysym->sym == SDLK_UNKNOWN)
108    printf("Unknown mapping for scancode %d\n", scancode);
109
110  return keysym;
111}
112
113static void updateKeyboard(_THIS)
114{
115  unsigned char buf[100];
116  SDL_keysym keysym;
117  int n, i;
118
119  if ((n = read(private->fd, buf, sizeof(buf))) > 0) {
120    for (i = 0; i < n; i++) {
121      unsigned char c = buf[i] & 0x7f;
122      if (c == 224) // special key prefix -- what should we do with it?
123	continue;
124      posted += SDL_PrivateKeyboard((buf[i] & 0x80) ? SDL_RELEASED : SDL_PRESSED,
125				    TranslateKey(c, &keysym));
126    }
127  }
128}
129
130void WSCONS_PumpEvents(_THIS)
131{
132  do {
133    posted = 0;
134    updateMouse();
135    updateKeyboard(this);
136  } while (posted);
137}
138
139void WSCONS_InitOSKeymap(_THIS)
140{
141  int i;
142
143  /* Make sure unknown keys are mapped correctly */
144  for (i=0; i < SDL_arraysize(keymap); i++) {
145    keymap[i] = SDLK_UNKNOWN;
146  }
147
148  switch (private->kbdType) {
149#ifdef WSKBD_TYPE_ZAURUS
150  case WSKBD_TYPE_ZAURUS:
151    /* top row */
152    keymap[2] = SDLK_1;
153    keymap[3] = SDLK_2;
154    keymap[4] = SDLK_3;
155    keymap[5] = SDLK_4;
156    keymap[6] = SDLK_5;
157    keymap[7] = SDLK_6;
158    keymap[8] = SDLK_7;
159    keymap[9] = SDLK_8;
160    keymap[10] = SDLK_9;
161    keymap[11] = SDLK_0;
162    keymap[14] = SDLK_BACKSPACE;
163
164    /* second row */
165    keymap[16] = SDLK_q;
166    keymap[17] = SDLK_w;
167    keymap[18] = SDLK_e;
168    keymap[19] = SDLK_r;
169    keymap[20] = SDLK_t;
170    keymap[21] = SDLK_y;
171    keymap[22] = SDLK_u;
172    keymap[23] = SDLK_i;
173    keymap[24] = SDLK_o;
174    keymap[25] = SDLK_p;
175
176    /* third row */
177    keymap[15] = SDLK_TAB;
178    keymap[30] = SDLK_a;
179    keymap[31] = SDLK_s;
180    keymap[32] = SDLK_d;
181    keymap[33] = SDLK_f;
182    keymap[34] = SDLK_g;
183    keymap[35] = SDLK_h;
184    keymap[36] = SDLK_j;
185    keymap[37] = SDLK_k;
186    keymap[38] = SDLK_l;
187
188    /* fourth row */
189    keymap[42] = SDLK_LSHIFT;
190    keymap[44] = SDLK_z;
191    keymap[45] = SDLK_x;
192    keymap[46] = SDLK_c;
193    keymap[47] = SDLK_v;
194    keymap[48] = SDLK_b;
195    keymap[49] = SDLK_n;
196    keymap[50] = SDLK_m;
197    keymap[54] = SDLK_RSHIFT;
198    keymap[28] = SDLK_RETURN;
199
200    /* fifth row */
201    keymap[56] = SDLK_LALT;
202    keymap[29] = SDLK_LCTRL;
203    /* keymap[56] = ; */
204    keymap[0] = SDLK_LSUPER;
205    keymap[12] = SDLK_MINUS;
206    keymap[57] = SDLK_SPACE;
207    keymap[51] = SDLK_COMMA;
208    keymap[52] = SDLK_PERIOD;
209
210    /* misc */
211    keymap[59] = SDLK_F1;
212    keymap[60] = SDLK_F2;
213    keymap[61] = SDLK_F3;
214    keymap[62] = SDLK_F4;
215    keymap[63] = SDLK_F5;
216    keymap[1] = SDLK_ESCAPE;
217    /* keymap[28] = SDLK_KP_ENTER; */
218    keymap[72] = SDLK_UP;
219    keymap[75] = SDLK_LEFT;
220    keymap[77] = SDLK_RIGHT;
221    keymap[80] = SDLK_DOWN;
222    break;
223#endif /* WSKBD_TYPE_ZAURUS */
224
225  default:
226    WSCONS_ReportError("Unable to map keys for keyboard type %u",
227		       private->kbdType);
228    break;
229  }
230}
231
232/* end of SDL_wsconsevents.c ... */
233
234