Contiki 3.x
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  */
34 
35 #define WIN32_LEAN_AND_MEAN
36 #include <windows.h>
37 #include <stdlib.h>
38 
39 #include "contiki.h"
40 #include "ctk/ctk.h"
41 
42 #include "ctk-console.h"
43 
44 static HANDLE stdinhandle;
45 static HANDLE stdouthandle;
46 
47 static unsigned char width;
48 static unsigned char height;
49 
50 static DWORD saved_inputmode;
51 static DWORD saved_outputmode;
52 static unsigned char saved_color;
53 static char saved_title[1024];
54 static CONSOLE_CURSOR_INFO saved_cursorinfo;
55 
56 static unsigned char color;
57 static unsigned char reversed;
58 
59 static unsigned char blank[1024];
60 static unsigned char hline[1024];
61 
62 static ctk_arch_key_t keys[256];
63 static unsigned char available;
64 
65 static unsigned short xpos;
66 static unsigned short ypos;
67 static unsigned char button;
68 
69 /*-----------------------------------------------------------------------------------*/
70 static BOOL WINAPI
71 ctrlhandler(DWORD ctrltype)
72 {
73  if(ctrltype == CTRL_C_EVENT) {
74  exit(EXIT_SUCCESS);
75  return TRUE;
76  }
77  return FALSE;
78 }
79 /*-----------------------------------------------------------------------------------*/
80 void
81 console_init(void)
82 {
83  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
84  CONSOLE_CURSOR_INFO cursorinfo = {1, FALSE};
85  static unsigned char done;
86 
87  if(done) {
88  return;
89  }
90  done = 1;
91 
92  stdinhandle = GetStdHandle(STD_INPUT_HANDLE);
93  stdouthandle = GetStdHandle(STD_OUTPUT_HANDLE);
94 
95  GetConsoleMode(stdinhandle, &saved_inputmode);
96  SetConsoleMode(stdinhandle, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
97 
98  GetConsoleMode(stdouthandle, &saved_outputmode);
99  SetConsoleMode(stdouthandle, ENABLE_PROCESSED_OUTPUT);
100 
101  screensize(&width, &height);
102 
103  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
104  saved_color = (unsigned char)consoleinfo.wAttributes;
105 
106  GetConsoleTitle(saved_title, sizeof(saved_title));
107  SetConsoleTitle("Contiki");
108 
109  GetConsoleCursorInfo(stdouthandle, &saved_cursorinfo);
110  SetConsoleCursorInfo(stdouthandle, &cursorinfo);
111 
112  SetConsoleCtrlHandler(ctrlhandler, TRUE);
113  atexit(console_exit);
114 
115  memset(blank, ' ', sizeof(blank));
116  memset(hline, '-', sizeof(hline));
117 }
118 /*-----------------------------------------------------------------------------------*/
119 void
120 console_exit(void)
121 {
122  static unsigned char done;
123 
124  if(done) {
125  return;
126  }
127  done = 1;
128 
129  textcolor(saved_color);
130  revers(0);
131  clrscr();
132  gotoxy(0, 0);
133 
134  SetConsoleMode(stdinhandle, saved_inputmode);
135  SetConsoleMode(stdouthandle, saved_outputmode);
136  SetConsoleTitle(saved_title);
137  SetConsoleCursorInfo(stdouthandle, &saved_cursorinfo);
138 }
139 /*-----------------------------------------------------------------------------------*/
140 unsigned char
141 console_resize(void)
142 {
143  unsigned char new_width;
144  unsigned char new_height;
145 
146  screensize(&new_width, &new_height);
147 
148  if(new_width != width ||
149  new_height != height) {
150  width = new_width;
151  height = new_height;
152  return 1;
153  }
154 
155  return 0;
156 }
157 /*-----------------------------------------------------------------------------------*/
158 static void
159 setcolor(void)
160 {
161  SetConsoleTextAttribute(stdouthandle, (WORD)(reversed? (color & 0x0F) << 4 |
162  (color & 0xF0) >> 4
163  : color));
164 }
165 /*-----------------------------------------------------------------------------------*/
166 unsigned char
167 wherex(void)
168 {
169  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
170 
171  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
172  return (unsigned char)consoleinfo.dwCursorPosition.X;
173 }
174 /*-----------------------------------------------------------------------------------*/
175 unsigned char
176 wherey(void)
177 {
178  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
179 
180  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
181  return (unsigned char)consoleinfo.dwCursorPosition.Y;
182 }
183 /*-----------------------------------------------------------------------------------*/
184 void
185 clrscr(void)
186 {
187  unsigned char i, width, height;
188 
189  screensize(&width, &height);
190  for(i = 0; i < height; ++i) {
191  cclearxy(0, i, width);
192  }
193 }
194 /*-----------------------------------------------------------------------------------*/
195 void
196 bgcolor(unsigned char c)
197 {
198  /* Presume this to be one of the first calls. */
199  console_init();
200 }
201 /*-----------------------------------------------------------------------------------*/
202 void
203 bordercolor(unsigned char c)
204 {
205  /* Presume this to be one of the first calls. */
206  console_init();
207 }
208 /*-----------------------------------------------------------------------------------*/
209 void
210 screensize(unsigned char *x, unsigned char *y)
211 {
212  CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
213 
214  GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
215  *x = consoleinfo.srWindow.Right - consoleinfo.srWindow.Left + 1;
216  *y = consoleinfo.srWindow.Bottom - consoleinfo.srWindow.Top + 1;
217 }
218 /*-----------------------------------------------------------------------------------*/
219 void
220 revers(unsigned char c)
221 {
222  reversed = c;
223  setcolor();
224 }
225 /*-----------------------------------------------------------------------------------*/
226 void
227 console_cputc(char c)
228 {
229  DWORD dummy;
230 
231  WriteConsole(stdouthandle, &c, 1, &dummy, NULL);
232 }
233 /*-----------------------------------------------------------------------------------*/
234 void
235 console_cputs(char *str)
236 {
237  DWORD dummy;
238 
239  WriteConsole(stdouthandle, str, (DWORD)strlen(str), &dummy, NULL);
240 }
241 /*-----------------------------------------------------------------------------------*/
242 void
243 cclear(unsigned char length)
244 {
245  DWORD dummy;
246 
247  WriteConsole(stdouthandle, blank, length, &dummy, NULL);
248 }
249 /*-----------------------------------------------------------------------------------*/
250 void
251 chline(unsigned char length)
252 {
253  DWORD dummy;
254 
255  WriteConsole(stdouthandle, hline, length, &dummy, NULL);
256 }
257 /*-----------------------------------------------------------------------------------*/
258 void
259 cvline(unsigned char length)
260 {
261  unsigned char i, x, y;
262 
263  x = wherex();
264  y = wherey();
265 
266  for(i = 0; i < length; ++i) {
267  cputcxy(x, (unsigned char)(y + i), '|');
268  }
269 }
270 /*-----------------------------------------------------------------------------------*/
271 void
272 gotoxy(unsigned char x, unsigned char y)
273 {
274  COORD coord = {x, y};
275 
276  SetConsoleCursorPosition(stdouthandle, coord);
277 }
278 /*-----------------------------------------------------------------------------------*/
279 void
280 cclearxy(unsigned char x, unsigned char y, unsigned char length)
281 {
282  gotoxy(x, y);
283  cclear(length);
284 }
285 /*-----------------------------------------------------------------------------------*/
286 void
287 chlinexy(unsigned char x, unsigned char y, unsigned char length)
288 {
289  gotoxy(x, y);
290  chline(length);
291 }
292 /*-----------------------------------------------------------------------------------*/
293 void
294 cvlinexy(unsigned char x, unsigned char y, unsigned char length)
295 {
296  gotoxy(x, y);
297  cvline(length);
298 }
299 /*-----------------------------------------------------------------------------------*/
300 void
301 cputsxy(unsigned char x, unsigned char y, char *str)
302 {
303  gotoxy(x, y);
304  console_cputs(str);
305 }
306 /*-----------------------------------------------------------------------------------*/
307 void
308 cputcxy(unsigned char x, unsigned char y, char c)
309 {
310  gotoxy(x, y);
311  console_cputc(c);
312 }
313 /*-----------------------------------------------------------------------------------*/
314 void
315 textcolor(unsigned char c)
316 {
317  color = c;
318  setcolor();
319 }
320 /*-----------------------------------------------------------------------------------*/
321 static void
322 console_readkey(KEY_EVENT_RECORD keyrecord)
323 {
324  ctk_arch_key_t key;
325 
326  if(!keyrecord.bKeyDown) {
327  return;
328  }
329 
330  if(keyrecord.wRepeatCount > (WORD)255 - available) {
331  keyrecord.wRepeatCount = (WORD)255 - available;
332  }
333 
334  key = keyrecord.uChar.AsciiChar;
335  if(key == CTK_CONF_WIDGETDOWN_KEY && keyrecord.dwControlKeyState & SHIFT_PRESSED) {
336  key = CTK_CONF_WIDGETUP_KEY;
337  }
338  if(key == 0) {
339  switch(keyrecord.wVirtualKeyCode) {
340  case VK_TAB:
341  if(keyrecord.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
342  key = CTK_CONF_WINDOWSWITCH_KEY;
343  }
344  break;
345  case VK_LEFT:
346  key = CH_CURS_LEFT;
347  break;
348  case VK_UP:
349  key = CH_CURS_UP;
350  break;
351  case VK_RIGHT:
352  key = CH_CURS_RIGHT;
353  break;
354  case VK_DOWN:
355  key = CH_CURS_DOWN;
356  break;
357  case VK_F10:
358  key = CTK_CONF_MENU_KEY;
359  break;
360  }
361  }
362 
363  if(key == 0) {
364  return;
365  }
366 
367  memset(keys + available, key, keyrecord.wRepeatCount);
368  available += (unsigned char)keyrecord.wRepeatCount;
369 }
370 /*-----------------------------------------------------------------------------------*/
371 static void
372 console_readmouse(MOUSE_EVENT_RECORD mouserecord)
373 {
374  xpos = mouserecord.dwMousePosition.X;
375  ypos = mouserecord.dwMousePosition.Y;
376 
377  button = (unsigned char)mouserecord.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED;
378 }
379 /*-----------------------------------------------------------------------------------*/
380 static void
381 console_read(void)
382 {
383  INPUT_RECORD inputrecord;
384  DWORD count;
385 
386  if(!GetNumberOfConsoleInputEvents(stdinhandle, &count) || count == 0) {
387  return;
388  }
389  if(!ReadConsoleInput(stdinhandle, &inputrecord, 1, &count) || count == 0) {
390  return;
391  }
392 
393  switch(inputrecord.EventType) {
394  case KEY_EVENT:
395  console_readkey(inputrecord.Event.KeyEvent);
396  break;
397  case MOUSE_EVENT:
398  console_readmouse(inputrecord.Event.MouseEvent);
399  break;
400  }
401 }
402 /*-----------------------------------------------------------------------------------*/
403 char
405 {
406  console_read();
407  return keys[--available];
408 }
409 /*-----------------------------------------------------------------------------------*/
410 unsigned char
412 {
413  console_read();
414  return available;
415 }
416 /*-----------------------------------------------------------------------------------*/
417 void
418 ctk_mouse_init(void)
419 {
420 }
421 /*-----------------------------------------------------------------------------------*/
422 unsigned short
423 ctk_mouse_x(void)
424 {
425  console_read();
426  return xpos;
427 }
428 /*-----------------------------------------------------------------------------------*/
429 unsigned short
430 ctk_mouse_y(void)
431 {
432  console_read();
433  return ypos;
434 }
435 /*-----------------------------------------------------------------------------------*/
436 unsigned short
437 ctk_mouse_xtoc(unsigned short x)
438 {
439  return x;
440 }
441 /*-----------------------------------------------------------------------------------*/
442 unsigned short
443 ctk_mouse_ytoc(unsigned short y)
444 {
445  return y;
446 }
447 /*-----------------------------------------------------------------------------------*/
448 unsigned char
449 ctk_mouse_button(void)
450 {
451  console_read();
452  return button;
453 }
454 /*-----------------------------------------------------------------------------------*/
455 void
456 ctk_mouse_hide(void)
457 {
458 }
459 /*-----------------------------------------------------------------------------------*/
460 void
461 ctk_mouse_show(void)
462 {
463 }
464 /*-----------------------------------------------------------------------------------*/
char ctk_arch_key_t
The keyboard character type of the system.
Definition: ctk-conio.h:40
#define NULL
The null pointer.
unsigned char ctk_arch_keyavail(void)
Check if there is a keypress in the keyboard input queue.
Definition: ctk-curses.c:464
#define TRUE
An alias for one, used for clarity.
ctk_arch_key_t ctk_arch_getkey(void)
Get a keypress from the keyboard input queue.
Definition: ctk-curses.c:452
#define FALSE
An alias for zero, used for clarity.
CTK header file.