Contiki 2.5
ctk-console.c
1 /*
2  * Copyright (c) 2006, Swedish Institute of Computer Science.
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  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * Author: Oliver Schmidt <ol.sc@web.de>
32  *
33  * $Id: ctk-console.c,v 1.10 2007/12/15 20:12:28 oliverschmidt Exp $
34  */
35 
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #include <stdlib.h>
39 
40 #include "contiki.h"
41 #include "ctk/ctk.h"
42 
43 #include "ctk-console.h"
44 
45 static HANDLE stdinhandle;
46 static HANDLE stdouthandle;
47 
48 static unsigned char width;
49 static unsigned char height;
50 
51 static DWORD saved_inputmode;
52 static DWORD saved_outputmode;
53 static unsigned char saved_color;
54 static char saved_title[1024];
55 static CONSOLE_CURSOR_INFO saved_cursorinfo;
56 
57 static unsigned char color;
58 static unsigned char reversed;
59 
60 static unsigned char blank[1024];
61 static unsigned char hline[1024];
62 
63 static ctk_arch_key_t keys[256];
64 static unsigned char available;
65 
66 static unsigned short xpos;
67 static unsigned short ypos;
68 static unsigned char button;
69 
70 /*-----------------------------------------------------------------------------------*/
71 static BOOL WINAPI
72 ctrlhandler(DWORD ctrltype)
73 {
74  if(ctrltype == CTRL_C_EVENT) {
75  exit(EXIT_SUCCESS);
76  return TRUE;
77  }
78  return FALSE;
79 }
80 /*-----------------------------------------------------------------------------------*/
81 void
82 console_init(void)
83 {
84  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
85  CONSOLE_CURSOR_INFO cursorinfo = {1, FALSE};
86  static unsigned char done;
87 
88  if(done) {
89  return;
90  }
91  done = 1;
92 
93  stdinhandle = GetStdHandle(STD_INPUT_HANDLE);
94  stdouthandle = GetStdHandle(STD_OUTPUT_HANDLE);
95 
96  GetConsoleMode(stdinhandle, &saved_inputmode);
97  SetConsoleMode(stdinhandle, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
98 
99  GetConsoleMode(stdouthandle, &saved_outputmode);
100  SetConsoleMode(stdouthandle, ENABLE_PROCESSED_OUTPUT);
101 
102  screensize(&width, &height);
103 
104  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
105  saved_color = (unsigned char)consoleinfo.wAttributes;
106 
107  GetConsoleTitle(saved_title, sizeof(saved_title));
108  SetConsoleTitle("Contiki");
109 
110  GetConsoleCursorInfo(stdouthandle, &saved_cursorinfo);
111  SetConsoleCursorInfo(stdouthandle, &cursorinfo);
112 
113  SetConsoleCtrlHandler(ctrlhandler, TRUE);
114  atexit(console_exit);
115 
116  memset(blank, ' ', sizeof(blank));
117  memset(hline, 0xC4, sizeof(hline));
118 }
119 /*-----------------------------------------------------------------------------------*/
120 void
121 console_exit(void)
122 {
123  static unsigned char done;
124 
125  if(done) {
126  return;
127  }
128  done = 1;
129 
130  textcolor(saved_color);
131  revers(0);
132  clrscr();
133  gotoxy(0, 0);
134 
135  SetConsoleMode(stdinhandle, saved_inputmode);
136  SetConsoleMode(stdouthandle, saved_outputmode);
137  SetConsoleTitle(saved_title);
138  SetConsoleCursorInfo(stdouthandle, &saved_cursorinfo);
139 }
140 /*-----------------------------------------------------------------------------------*/
141 unsigned char
142 console_resize(void)
143 {
144  unsigned char new_width;
145  unsigned char new_height;
146 
147  screensize(&new_width, &new_height);
148 
149  if(new_width != width ||
150  new_height != height) {
151  width = new_width;
152  height = new_height;
153  return 1;
154  }
155 
156  return 0;
157 }
158 /*-----------------------------------------------------------------------------------*/
159 static void
160 setcolor(void)
161 {
162  SetConsoleTextAttribute(stdouthandle, (WORD)(reversed? (color & 0x0F) << 4 |
163  (color & 0xF0) >> 4
164  : color));
165 }
166 /*-----------------------------------------------------------------------------------*/
167 unsigned char
168 wherex(void)
169 {
170  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
171 
172  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
173  return (unsigned char)consoleinfo.dwCursorPosition.X;
174 }
175 /*-----------------------------------------------------------------------------------*/
176 unsigned char
177 wherey(void)
178 {
179  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
180 
181  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
182  return (unsigned char)consoleinfo.dwCursorPosition.Y;
183 }
184 /*-----------------------------------------------------------------------------------*/
185 void
186 clrscr(void)
187 {
188  unsigned char i, width, height;
189 
190  screensize(&width, &height);
191  for(i = 0; i < height; ++i) {
192  cclearxy(0, i, width);
193  }
194 }
195 /*-----------------------------------------------------------------------------------*/
196 void
197 bgcolor(unsigned char c)
198 {
199  /* Presume this to be one of the first calls. */
200  console_init();
201 }
202 /*-----------------------------------------------------------------------------------*/
203 void
204 bordercolor(unsigned char c)
205 {
206  /* Presume this to be one of the first calls. */
207  console_init();
208 }
209 /*-----------------------------------------------------------------------------------*/
210 void
211 screensize(unsigned char *x, unsigned char *y)
212 {
213  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
214 
215  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
216  *x = consoleinfo.srWindow.Right - consoleinfo.srWindow.Left + 1;
217  *y = consoleinfo.srWindow.Bottom - consoleinfo.srWindow.Top + 1;
218 }
219 /*-----------------------------------------------------------------------------------*/
220 void
221 revers(unsigned char c)
222 {
223  reversed = c;
224  setcolor();
225 }
226 /*-----------------------------------------------------------------------------------*/
227 void
228 console_cputc(char c)
229 {
230  DWORD dummy;
231 
232  WriteConsole(stdouthandle, &c, 1, &dummy, NULL);
233 }
234 /*-----------------------------------------------------------------------------------*/
235 void
236 console_cputs(char *str)
237 {
238  DWORD dummy;
239 
240  WriteConsole(stdouthandle, str, (DWORD)strlen(str), &dummy, NULL);
241 }
242 /*-----------------------------------------------------------------------------------*/
243 void
244 cclear(unsigned char length)
245 {
246  DWORD dummy;
247 
248  WriteConsole(stdouthandle, blank, length, &dummy, NULL);
249 }
250 /*-----------------------------------------------------------------------------------*/
251 void
252 chline(unsigned char length)
253 {
254  DWORD dummy;
255 
256  WriteConsole(stdouthandle, hline, length, &dummy, NULL);
257 }
258 /*-----------------------------------------------------------------------------------*/
259 void
260 cvline(unsigned char length)
261 {
262  unsigned char i, x, y;
263 
264  x = wherex();
265  y = wherey();
266 
267  for(i = 0; i < length; ++i) {
268  cputcxy(x, (unsigned char)(y + i), (char)0xB3);
269  }
270 }
271 /*-----------------------------------------------------------------------------------*/
272 void
273 gotoxy(unsigned char x, unsigned char y)
274 {
275  COORD coord = {x, y};
276 
277  SetConsoleCursorPosition(stdouthandle, coord);
278 }
279 /*-----------------------------------------------------------------------------------*/
280 void
281 cclearxy(unsigned char x, unsigned char y, unsigned char length)
282 {
283  gotoxy(x, y);
284  cclear(length);
285 }
286 /*-----------------------------------------------------------------------------------*/
287 void
288 chlinexy(unsigned char x, unsigned char y, unsigned char length)
289 {
290  gotoxy(x, y);
291  chline(length);
292 }
293 /*-----------------------------------------------------------------------------------*/
294 void
295 cvlinexy(unsigned char x, unsigned char y, unsigned char length)
296 {
297  gotoxy(x, y);
298  cvline(length);
299 }
300 /*-----------------------------------------------------------------------------------*/
301 void
302 cputsxy(unsigned char x, unsigned char y, char *str)
303 {
304  gotoxy(x, y);
305  console_cputs(str);
306 }
307 /*-----------------------------------------------------------------------------------*/
308 void
309 cputcxy(unsigned char x, unsigned char y, char c)
310 {
311  gotoxy(x, y);
312  console_cputc(c);
313 }
314 /*-----------------------------------------------------------------------------------*/
315 void
316 textcolor(unsigned char c)
317 {
318  color = c;
319  setcolor();
320 }
321 /*-----------------------------------------------------------------------------------*/
322 static void
323 console_readkey(KEY_EVENT_RECORD keyrecord)
324 {
325  ctk_arch_key_t key;
326 
327  if(!keyrecord.bKeyDown) {
328  return;
329  }
330 
331  if(keyrecord.wRepeatCount > (WORD)255 - available) {
332  keyrecord.wRepeatCount = (WORD)255 - available;
333  }
334 
335  key = keyrecord.uChar.AsciiChar;
336  if(key == CTK_CONF_WIDGETDOWN_KEY && keyrecord.dwControlKeyState & SHIFT_PRESSED) {
337  key = CTK_CONF_WIDGETUP_KEY;
338  }
339  if(key == 0) {
340  switch(keyrecord.wVirtualKeyCode) {
341  case VK_TAB:
342  if(keyrecord.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
343  key = CTK_CONF_WINDOWSWITCH_KEY;
344  }
345  break;
346  case VK_LEFT:
347  key = CH_CURS_LEFT;
348  break;
349  case VK_UP:
350  key = CH_CURS_UP;
351  break;
352  case VK_RIGHT:
353  key = CH_CURS_RIGHT;
354  break;
355  case VK_DOWN:
356  key = CH_CURS_DOWN;
357  break;
358  case VK_F10:
359  key = CTK_CONF_MENU_KEY;
360  break;
361  }
362  }
363 
364  if(key == 0) {
365  return;
366  }
367 
368  memset(keys + available, key, keyrecord.wRepeatCount);
369  available += (unsigned char)keyrecord.wRepeatCount;
370 }
371 /*-----------------------------------------------------------------------------------*/
372 static void
373 console_readmouse(MOUSE_EVENT_RECORD mouserecord)
374 {
375  xpos = mouserecord.dwMousePosition.X;
376  ypos = mouserecord.dwMousePosition.Y;
377 
378  button = (unsigned char)mouserecord.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED;
379 }
380 /*-----------------------------------------------------------------------------------*/
381 static void
382 console_read(void)
383 {
384  INPUT_RECORD inputrecord;
385  DWORD count;
386 
387  if(!GetNumberOfConsoleInputEvents(stdinhandle, &count) || count == 0) {
388  return;
389  }
390  if(!ReadConsoleInput(stdinhandle, &inputrecord, 1, &count) || count == 0) {
391  return;
392  }
393 
394  switch(inputrecord.EventType) {
395  case KEY_EVENT:
396  console_readkey(inputrecord.Event.KeyEvent);
397  break;
398  case MOUSE_EVENT:
399  console_readmouse(inputrecord.Event.MouseEvent);
400  break;
401  }
402 }
403 /*-----------------------------------------------------------------------------------*/
404 char
406 {
407  console_read();
408  return keys[--available];
409 }
410 /*-----------------------------------------------------------------------------------*/
411 unsigned char
413 {
414  console_read();
415  return available;
416 }
417 /*-----------------------------------------------------------------------------------*/
418 void
419 ctk_mouse_init(void)
420 {
421 }
422 /*-----------------------------------------------------------------------------------*/
423 unsigned short
424 ctk_mouse_x(void)
425 {
426  console_read();
427  return xpos;
428 }
429 /*-----------------------------------------------------------------------------------*/
430 unsigned short
431 ctk_mouse_y(void)
432 {
433  console_read();
434  return ypos;
435 }
436 /*-----------------------------------------------------------------------------------*/
437 unsigned short
438 ctk_mouse_xtoc(unsigned short x)
439 {
440  return x;
441 }
442 /*-----------------------------------------------------------------------------------*/
443 unsigned short
444 ctk_mouse_ytoc(unsigned short y)
445 {
446  return y;
447 }
448 /*-----------------------------------------------------------------------------------*/
449 unsigned char
450 ctk_mouse_button(void)
451 {
452  console_read();
453  return button;
454 }
455 /*-----------------------------------------------------------------------------------*/
456 void
457 ctk_mouse_hide(void)
458 {
459 }
460 /*-----------------------------------------------------------------------------------*/
461 void
462 ctk_mouse_show(void)
463 {
464 }
465 /*-----------------------------------------------------------------------------------*/