Contiki 2.6

ctk-console.c

00001 /*
00002  * Copyright (c) 2006, Swedish Institute of Computer Science.
00003  * All rights reserved. 
00004  *
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions 
00007  * are met: 
00008  * 1. Redistributions of source code must retain the above copyright 
00009  *    notice, this list of conditions and the following disclaimer. 
00010  * 2. Redistributions in binary form must reproduce the above copyright 
00011  *    notice, this list of conditions and the following disclaimer in the 
00012  *    documentation and/or other materials provided with the distribution. 
00013  * 3. Neither the name of the Institute nor the names of its contributors 
00014  *    may be used to endorse or promote products derived from this software 
00015  *    without specific prior written permission. 
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00027  * SUCH DAMAGE. 
00028  *
00029  * This file is part of the Contiki operating system.
00030  * 
00031  * Author: Oliver Schmidt <ol.sc@web.de>
00032  *
00033  * $Id: ctk-console.c,v 1.10 2007/12/15 20:12:28 oliverschmidt Exp $
00034  */
00035 
00036 #define WIN32_LEAN_AND_MEAN
00037 #include <windows.h>
00038 #include <stdlib.h>
00039 
00040 #include "contiki.h"
00041 #include "ctk/ctk.h"
00042 
00043 #include "ctk-console.h"
00044 
00045 static HANDLE stdinhandle;
00046 static HANDLE stdouthandle;
00047 
00048 static unsigned char width;
00049 static unsigned char height;
00050 
00051 static DWORD               saved_inputmode;
00052 static DWORD               saved_outputmode;
00053 static unsigned char       saved_color;
00054 static char                saved_title[1024];
00055 static CONSOLE_CURSOR_INFO saved_cursorinfo;
00056 
00057 static unsigned char color;
00058 static unsigned char reversed;
00059 
00060 static unsigned char blank[1024];
00061 static unsigned char hline[1024];
00062 
00063 static ctk_arch_key_t keys[256];
00064 static unsigned char  available;
00065 
00066 static unsigned short xpos;
00067 static unsigned short ypos;
00068 static unsigned char  button;
00069 
00070 /*-----------------------------------------------------------------------------------*/
00071 static BOOL WINAPI
00072 ctrlhandler(DWORD ctrltype)
00073 {
00074   if(ctrltype == CTRL_C_EVENT) {
00075     exit(EXIT_SUCCESS);
00076     return TRUE;
00077   }
00078   return FALSE;
00079 }
00080 /*-----------------------------------------------------------------------------------*/
00081 void
00082 console_init(void)
00083 {
00084   CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
00085   CONSOLE_CURSOR_INFO cursorinfo = {1, FALSE};
00086   static unsigned char done;
00087 
00088   if(done) {
00089     return;
00090   }
00091   done = 1;
00092 
00093   stdinhandle  = GetStdHandle(STD_INPUT_HANDLE);
00094   stdouthandle = GetStdHandle(STD_OUTPUT_HANDLE);
00095 
00096   GetConsoleMode(stdinhandle, &saved_inputmode);
00097   SetConsoleMode(stdinhandle, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
00098 
00099   GetConsoleMode(stdouthandle, &saved_outputmode);
00100   SetConsoleMode(stdouthandle, ENABLE_PROCESSED_OUTPUT);
00101 
00102   screensize(&width, &height);
00103 
00104   GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
00105   saved_color = (unsigned char)consoleinfo.wAttributes;
00106 
00107   GetConsoleTitle(saved_title, sizeof(saved_title));
00108   SetConsoleTitle("Contiki");
00109 
00110   GetConsoleCursorInfo(stdouthandle, &saved_cursorinfo);
00111   SetConsoleCursorInfo(stdouthandle, &cursorinfo);
00112 
00113   SetConsoleCtrlHandler(ctrlhandler, TRUE);
00114   atexit(console_exit);
00115 
00116   memset(blank, ' ',  sizeof(blank));
00117   memset(hline, 0xC4, sizeof(hline));
00118 }
00119 /*-----------------------------------------------------------------------------------*/
00120 void
00121 console_exit(void)
00122 {
00123   static unsigned char done;
00124 
00125   if(done) {
00126     return;
00127   }
00128   done = 1;
00129 
00130   textcolor(saved_color);
00131   revers(0);
00132   clrscr();
00133   gotoxy(0, 0);
00134 
00135   SetConsoleMode(stdinhandle,  saved_inputmode);
00136   SetConsoleMode(stdouthandle, saved_outputmode);
00137   SetConsoleTitle(saved_title);
00138   SetConsoleCursorInfo(stdouthandle, &saved_cursorinfo);
00139 }
00140 /*-----------------------------------------------------------------------------------*/
00141 unsigned char
00142 console_resize(void)
00143 {
00144   unsigned char new_width;
00145   unsigned char new_height;
00146 
00147   screensize(&new_width, &new_height);
00148 
00149   if(new_width  != width ||
00150      new_height != height) {
00151     width  = new_width;
00152     height = new_height;
00153     return 1;
00154   }
00155 
00156   return 0;
00157 }
00158 /*-----------------------------------------------------------------------------------*/
00159 static void
00160 setcolor(void)
00161 {
00162   SetConsoleTextAttribute(stdouthandle, (WORD)(reversed? (color & 0x0F) << 4 |
00163                                                          (color & 0xF0) >> 4
00164                                                        : color));
00165 }
00166 /*-----------------------------------------------------------------------------------*/
00167 unsigned char
00168 wherex(void)
00169 {
00170   CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
00171 
00172   GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
00173   return (unsigned char)consoleinfo.dwCursorPosition.X;
00174 }
00175 /*-----------------------------------------------------------------------------------*/
00176 unsigned char
00177 wherey(void)
00178 {
00179   CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
00180 
00181   GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
00182   return (unsigned char)consoleinfo.dwCursorPosition.Y;
00183 }
00184 /*-----------------------------------------------------------------------------------*/
00185 void
00186 clrscr(void)
00187 {
00188   unsigned char i, width, height;
00189 
00190   screensize(&width, &height);
00191   for(i = 0; i < height; ++i) {
00192     cclearxy(0, i, width);
00193   }
00194 }
00195 /*-----------------------------------------------------------------------------------*/
00196 void
00197 bgcolor(unsigned char c)
00198 {
00199   /* Presume this to be one of the first calls. */
00200   console_init();
00201 }
00202 /*-----------------------------------------------------------------------------------*/
00203 void
00204 bordercolor(unsigned char c)
00205 {
00206   /* Presume this to be one of the first calls. */
00207   console_init();
00208 }
00209 /*-----------------------------------------------------------------------------------*/
00210 void
00211 screensize(unsigned char *x, unsigned char *y)
00212 {
00213   CONSOLE_SCREEN_BUFFER_INFO consoleinfo;
00214 
00215   GetConsoleScreenBufferInfo(stdouthandle, &consoleinfo);
00216   *x = consoleinfo.srWindow.Right - consoleinfo.srWindow.Left + 1;
00217   *y = consoleinfo.srWindow.Bottom - consoleinfo.srWindow.Top + 1;
00218 }
00219 /*-----------------------------------------------------------------------------------*/
00220 void
00221 revers(unsigned char c)
00222 {
00223   reversed = c;
00224   setcolor();
00225 }
00226 /*-----------------------------------------------------------------------------------*/
00227 void
00228 console_cputc(char c)
00229 {
00230   DWORD dummy;
00231 
00232   WriteConsole(stdouthandle, &c, 1, &dummy, NULL);
00233 }
00234 /*-----------------------------------------------------------------------------------*/
00235 void
00236 console_cputs(char *str)
00237 {
00238   DWORD dummy;
00239 
00240   WriteConsole(stdouthandle, str, (DWORD)strlen(str), &dummy, NULL);
00241 }
00242 /*-----------------------------------------------------------------------------------*/
00243 void
00244 cclear(unsigned char length)
00245 {
00246   DWORD dummy;
00247 
00248   WriteConsole(stdouthandle, blank, length, &dummy, NULL);
00249 }
00250 /*-----------------------------------------------------------------------------------*/
00251 void
00252 chline(unsigned char length)
00253 {
00254   DWORD dummy;
00255 
00256   WriteConsole(stdouthandle, hline, length, &dummy, NULL);
00257 }
00258 /*-----------------------------------------------------------------------------------*/
00259 void
00260 cvline(unsigned char length)
00261 {
00262   unsigned char i, x, y;
00263 
00264   x = wherex();
00265   y = wherey();
00266 
00267   for(i = 0; i < length; ++i) {
00268     cputcxy(x, (unsigned char)(y + i), (char)0xB3);
00269   }
00270 }
00271 /*-----------------------------------------------------------------------------------*/
00272 void
00273 gotoxy(unsigned char x, unsigned char y)
00274 {
00275   COORD coord = {x, y};
00276 
00277   SetConsoleCursorPosition(stdouthandle, coord);
00278 }
00279 /*-----------------------------------------------------------------------------------*/
00280 void
00281 cclearxy(unsigned char x, unsigned char y, unsigned char length)
00282 {
00283   gotoxy(x, y);
00284   cclear(length);
00285 }
00286 /*-----------------------------------------------------------------------------------*/
00287 void
00288 chlinexy(unsigned char x, unsigned char y, unsigned char length)
00289 {
00290   gotoxy(x, y);
00291   chline(length);
00292 }
00293 /*-----------------------------------------------------------------------------------*/
00294 void
00295 cvlinexy(unsigned char x, unsigned char y, unsigned char length)
00296 {
00297   gotoxy(x, y);
00298   cvline(length);
00299 }
00300 /*-----------------------------------------------------------------------------------*/
00301 void
00302 cputsxy(unsigned char x, unsigned char y, char *str)
00303 {
00304   gotoxy(x, y);
00305   console_cputs(str);
00306 }
00307 /*-----------------------------------------------------------------------------------*/
00308 void
00309 cputcxy(unsigned char x, unsigned char y, char c)
00310 {
00311   gotoxy(x, y);
00312   console_cputc(c);
00313 }
00314 /*-----------------------------------------------------------------------------------*/
00315 void
00316 textcolor(unsigned char c)
00317 {
00318   color = c;
00319   setcolor();
00320 }
00321 /*-----------------------------------------------------------------------------------*/
00322 static void
00323 console_readkey(KEY_EVENT_RECORD keyrecord)
00324 {
00325   ctk_arch_key_t key;
00326 
00327   if(!keyrecord.bKeyDown) {
00328     return;
00329   }
00330 
00331   if(keyrecord.wRepeatCount > (WORD)255 - available) {
00332     keyrecord.wRepeatCount = (WORD)255 - available;
00333   }
00334 
00335   key = keyrecord.uChar.AsciiChar;
00336   if(key == CTK_CONF_WIDGETDOWN_KEY && keyrecord.dwControlKeyState & SHIFT_PRESSED) {
00337     key = CTK_CONF_WIDGETUP_KEY;
00338   }
00339   if(key == 0) {
00340     switch(keyrecord.wVirtualKeyCode) {
00341     case VK_TAB:
00342         if(keyrecord.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) {
00343           key = CTK_CONF_WINDOWSWITCH_KEY;
00344         }
00345         break;
00346     case VK_LEFT:
00347         key = CH_CURS_LEFT;
00348         break;
00349     case VK_UP:
00350         key = CH_CURS_UP;
00351         break;
00352     case VK_RIGHT:
00353         key = CH_CURS_RIGHT;
00354         break;
00355     case VK_DOWN:
00356         key = CH_CURS_DOWN;
00357         break;
00358     case VK_F10:
00359         key = CTK_CONF_MENU_KEY;
00360         break;
00361     }
00362   }
00363 
00364   if(key == 0) {
00365     return;
00366   }
00367 
00368   memset(keys + available, key, keyrecord.wRepeatCount);
00369   available += (unsigned char)keyrecord.wRepeatCount;
00370 }
00371 /*-----------------------------------------------------------------------------------*/
00372 static void
00373 console_readmouse(MOUSE_EVENT_RECORD mouserecord)
00374 {
00375   xpos = mouserecord.dwMousePosition.X;
00376   ypos = mouserecord.dwMousePosition.Y;
00377 
00378   button = (unsigned char)mouserecord.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED;
00379 }
00380 /*-----------------------------------------------------------------------------------*/
00381 static void
00382 console_read(void)
00383 {
00384   INPUT_RECORD inputrecord;
00385   DWORD count;
00386 
00387   if(!GetNumberOfConsoleInputEvents(stdinhandle, &count) || count == 0) {
00388     return;
00389   }
00390   if(!ReadConsoleInput(stdinhandle, &inputrecord, 1, &count) || count == 0) {
00391     return;
00392   }
00393 
00394   switch(inputrecord.EventType) {
00395   case KEY_EVENT:
00396     console_readkey(inputrecord.Event.KeyEvent);
00397     break;
00398   case MOUSE_EVENT:
00399     console_readmouse(inputrecord.Event.MouseEvent);
00400     break;
00401   }
00402 }
00403 /*-----------------------------------------------------------------------------------*/
00404 char
00405 ctk_arch_getkey(void)
00406 {
00407   console_read();
00408   return keys[--available];
00409 }
00410 /*-----------------------------------------------------------------------------------*/
00411 unsigned char
00412 ctk_arch_keyavail(void)
00413 {
00414   console_read();
00415   return available;
00416 }
00417 /*-----------------------------------------------------------------------------------*/
00418 void
00419 ctk_mouse_init(void)
00420 {
00421 }
00422 /*-----------------------------------------------------------------------------------*/
00423 unsigned short
00424 ctk_mouse_x(void)
00425 {
00426   console_read();
00427   return xpos;
00428 }
00429 /*-----------------------------------------------------------------------------------*/
00430 unsigned short
00431 ctk_mouse_y(void)
00432 {
00433   console_read();
00434   return ypos;
00435 }
00436 /*-----------------------------------------------------------------------------------*/
00437 unsigned short
00438 ctk_mouse_xtoc(unsigned short x)
00439 {
00440   return x;
00441 }
00442 /*-----------------------------------------------------------------------------------*/
00443 unsigned short
00444 ctk_mouse_ytoc(unsigned short y)
00445 {
00446   return y;
00447 }
00448 /*-----------------------------------------------------------------------------------*/
00449 unsigned char
00450 ctk_mouse_button(void)
00451 {
00452   console_read();
00453   return button;
00454 }
00455 /*-----------------------------------------------------------------------------------*/
00456 void
00457 ctk_mouse_hide(void)
00458 {
00459 }
00460 /*-----------------------------------------------------------------------------------*/
00461 void
00462 ctk_mouse_show(void)
00463 {
00464 }
00465 /*-----------------------------------------------------------------------------------*/