Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, Takahide Matsutsuka. 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 00011 * copyright notice, this list of conditions and the following 00012 * disclaimer in the documentation and/or other materials provided 00013 * with the distribution. 00014 * 3. The name of the author may not be used to endorse or promote 00015 * products derived from this software without specific prior 00016 * written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00019 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00022 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00024 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * $Id: ctk-conio_arch-source.c,v 1.2 2007/09/29 04:10:00 matsutsuka Exp $ 00031 * 00032 */ 00033 00034 /* 00035 * \file 00036 * This is an original source file for 00037 * ctk-conio_arch.c and ctk-conio_arch-asm.S 00038 * \author 00039 * Takahide Matsutsuka <markn@markn.org> 00040 */ 00041 00042 00043 #include "ctk/ctk.h" 00044 #include "ctk/ctk-draw.h" 00045 #include "contiki-conf.h" 00046 #include "ctk/ctk_arch.h" 00047 #include <string.h> 00048 00049 #ifndef NULL 00050 #define NULL (void *)0 00051 #endif 00052 00053 /*---------------------------------------------------------------------------*/ 00054 static char cursx, cursy; 00055 static unsigned char reversed; 00056 static char cy1, cy2; 00057 00058 unsigned char ctk_draw_windowtitle_height = 1; 00059 00060 /*---------------------------------------------------------------------------*/ 00061 #define revers(c) reversed = c 00062 #define clip(y1, y2) cy1 = y1; cy2 = y2 00063 #define OFFSET(x, y) y * SCREEN_WIDTH + x 00064 00065 /*---------------------------------------------------------------------------*/ 00066 void cputc(char c) { 00067 if (cursy >= cy1 && cursy <= cy2 00068 && cursy >= 0 && cursy <= SCREEN_HEIGHT 00069 && cursx >= 0 && cursx < SCREEN_WIDTH) { 00070 unsigned int offset = OFFSET(cursx, cursy); 00071 *((char *) VRAM_CHAR + offset) = c; 00072 *((char *) VRAM_ATTR + offset) = reversed ? COLOR_REVERSED : COLOR_NORMAL; 00073 } 00074 cursx++; 00075 } 00076 00077 /*---------------------------------------------------------------------------*/ 00078 void cputs(char *str) { 00079 while (*str != 0) { 00080 cputc(*str); 00081 str++; 00082 } 00083 } 00084 /*---------------------------------------------------------------------------*/ 00085 void cputsn(char *str, unsigned char len) { 00086 while ((len > 0) && (*str != 0)) { 00087 cputc(*str); 00088 str++; 00089 len--; 00090 } 00091 } 00092 /*---------------------------------------------------------------------------*/ 00093 void chline(unsigned char length) { 00094 while (length > 0) { 00095 cputc(CH_HOLILINE); 00096 length--; 00097 } 00098 } 00099 /*---------------------------------------------------------------------------*/ 00100 /* #define cvline(l) while (l > 0) { cputc(CH_VERTLINE); */ 00101 /* ++cursy; --cursx; l--; } */ 00102 00103 void cvline(unsigned char length) { 00104 while (length > 0) { 00105 cputc(CH_VERTLINE); 00106 ++cursy; 00107 --cursx; 00108 length--; 00109 } 00110 } 00111 /*---------------------------------------------------------------------------*/ 00112 void gotoxy(unsigned char x, unsigned char y) { 00113 cursx = x; 00114 cursy = y; 00115 } 00116 /*---------------------------------------------------------------------------*/ 00117 void clearTo(char x) { 00118 while (cursx < x) { 00119 cputc(CH_SPACE); 00120 } 00121 cursx = x; 00122 } 00123 00124 /*---------------------------------------------------------------------------*/ 00125 void ctk_draw_clear(unsigned char clipy1, unsigned char clipy2) { 00126 while (clipy1 < clipy2) { 00127 gotoxy(0, clipy1); 00128 clearTo(SCREEN_WIDTH); 00129 clipy1++; 00130 } 00131 } 00132 00133 /*---------------------------------------------------------------------------*/ 00134 void ctk_draw_init(void) { 00135 clip(0, SCREEN_HEIGHT); 00136 ctk_draw_clear(0, SCREEN_HEIGHT); 00137 } 00138 /*---------------------------------------------------------------------------*/ 00139 /* 00140 * w: widget 00141 * x, y: screen position of client drawing area (left, top) 00142 * clipx, clipy: screen position of client drawing area (right, bottom) 00143 * clipy1, clipy2: min/max y position of screen 00144 * focus: boolean 00145 */ 00146 void 00147 draw_widget(struct ctk_widget *w, 00148 unsigned char x, unsigned char y, 00149 unsigned char focus) { 00150 unsigned char xpos, ypos, xscroll; 00151 unsigned char i, j; 00152 char c, *text; 00153 #if CTK_CONF_ICONS 00154 unsigned char len; 00155 #endif /* CTK_CONF_ICONS */ 00156 00157 xpos = x + w->x; 00158 ypos = y + w->y; 00159 00160 revers(focus & CTK_FOCUS_WIDGET); 00161 gotoxy(xpos, ypos); 00162 00163 if (w->type == CTK_WIDGET_SEPARATOR) { 00164 chline(w->w); 00165 } else if (w->type == CTK_WIDGET_LABEL) { 00166 text = w->widget.label.text; 00167 for(i = 0; i < w->h; ++i) { 00168 gotoxy(xpos, ypos); 00169 cputsn(text, w->w); 00170 clearTo(xpos + w->w); 00171 ++ypos; 00172 text += w->w; 00173 } 00174 } else if (w->type == CTK_WIDGET_BUTTON) { 00175 cputc('['); 00176 cputsn(w->widget.button.text, w->w); 00177 cputc(']'); 00178 } else if (w->type == CTK_WIDGET_HYPERLINK) { 00179 cputsn(w->widget.hyperlink.text, w->w); 00180 } else if (w->type == CTK_WIDGET_TEXTENTRY) { 00181 text = w->widget.textentry.text; 00182 xscroll = 0; 00183 if(w->widget.textentry.xpos >= w->w - 1) { 00184 xscroll = w->widget.textentry.xpos - w->w + 1; 00185 } 00186 for(j = 0; j < w->h; ++j) { 00187 gotoxy(xpos, ypos); 00188 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT && 00189 w->widget.textentry.ypos == j) { 00190 revers(0); 00191 cputc('>'); 00192 for(i = 0; i < w->w; ++i) { 00193 c = text[i + xscroll]; 00194 revers(i == w->widget.textentry.xpos - xscroll); 00195 cputc((c == 0) ? CH_SPACE : c); 00196 } 00197 revers(0); 00198 cputc('<'); 00199 } else { 00200 cputc(CH_VERTLINE); 00201 cputsn(text, w->w); 00202 clearTo(xpos + w->w + 1); 00203 cputc(CH_VERTLINE); 00204 } 00205 ++ypos; 00206 text += w->w; 00207 } 00208 #if CTK_CONF_ICONS 00209 } else if (w->type == CTK_WIDGET_ICON) { 00210 if(w->widget.icon.textmap != NULL) { 00211 for(i = 0; i < 3; ++i) { 00212 gotoxy(xpos, ypos); 00213 cputc(w->widget.icon.textmap[0 + 3 * i]); 00214 cputc(w->widget.icon.textmap[1 + 3 * i]); 00215 cputc(w->widget.icon.textmap[2 + 3 * i]); 00216 ++ypos; 00217 } 00218 x = xpos; 00219 00220 len = strlen(w->widget.icon.title); 00221 if(x + len >= SCREEN_WIDTH) { 00222 x = SCREEN_WIDTH - len; 00223 } 00224 gotoxy(x, ypos); 00225 cputs(w->widget.icon.title); 00226 } 00227 #endif /* CTK_CONF_ICONS */ 00228 } 00229 revers(0); 00230 00231 } 00232 /*---------------------------------------------------------------------------*/ 00233 void 00234 ctk_draw_widget(struct ctk_widget *w, 00235 unsigned char focus, 00236 unsigned char clipy1, 00237 unsigned char clipy2) { 00238 00239 struct ctk_window *win = w->window; 00240 unsigned char posx, posy; 00241 clip(clipy1, clipy2); 00242 00243 posx = win->x + 1; 00244 posy = win->y + 2; 00245 00246 if(w == win->focused) { 00247 focus |= CTK_FOCUS_WIDGET; 00248 } 00249 00250 draw_widget(w, posx, posy, focus); 00251 } 00252 /*---------------------------------------------------------------------------*/ 00253 void 00254 ctk_draw_clear_window(struct ctk_window *window, 00255 unsigned char focus, 00256 unsigned char clipy1, 00257 unsigned char clipy2) { 00258 00259 unsigned char i; 00260 unsigned char x1, x2, y1, y2; 00261 x1 = window->x + 1; 00262 x2 = x1 + window->w; 00263 y1 = window->y + 2; 00264 y2 = y1 + window->h; 00265 00266 for(i = y1; i < y2; ++i) { 00267 gotoxy(x1, i); 00268 clearTo(x2); 00269 } 00270 } 00271 /*---------------------------------------------------------------------------*/ 00272 void draw_window_sub(struct ctk_window *window, unsigned char focus) { 00273 00274 unsigned char x, y; 00275 unsigned char x1, y1, x2; 00276 struct ctk_widget *w; 00277 unsigned char wfocus; 00278 00279 x = window->x; 00280 y = window->y + 1; 00281 00282 x1 = x + 1; 00283 y1 = y + 1; 00284 x2 = x1 + window->w; 00285 00286 // |_ 00287 gotoxy(x, y1); 00288 cvline(window->h); 00289 cputc(CH_LLCORNER); 00290 chline(window->w); 00291 cputc(CH_LRCORNER); 00292 00293 // - 00294 gotoxy(x, y); 00295 cputc(CH_ULCORNER); 00296 chline(window->w); 00297 cputc(CH_URCORNER); 00298 // | 00299 gotoxy(x2, y1); 00300 cvline(window->h); 00301 00302 /* Draw inactive widgets. */ 00303 for(w = window->inactive; w != NULL; w = w->next) { 00304 draw_widget(w, x1, y1, focus); 00305 } 00306 00307 /* Draw active widgets. */ 00308 for(w = window->active; w != NULL; w = w->next) { 00309 wfocus = focus; 00310 if(w == window->focused) { 00311 wfocus |= CTK_FOCUS_WIDGET; 00312 } 00313 draw_widget(w, x1, y1, wfocus); 00314 } 00315 } 00316 /*---------------------------------------------------------------------------*/ 00317 void 00318 ctk_draw_window(struct ctk_window *window, unsigned char focus, 00319 unsigned char clipy1, unsigned char clipy2, unsigned char draw_borders) { 00320 clip(clipy1, clipy2); 00321 00322 focus = focus & CTK_FOCUS_WINDOW; 00323 draw_window_sub(window, focus); 00324 } 00325 /*---------------------------------------------------------------------------*/ 00326 void ctk_draw_dialog(struct ctk_window *dialog) { 00327 clip(0, SCREEN_HEIGHT); 00328 00329 ctk_draw_clear_window(dialog, 0, 0, SCREEN_HEIGHT); 00330 draw_window_sub(dialog, CTK_FOCUS_DIALOG); 00331 } 00332 /*---------------------------------------------------------------------------*/ 00333 #if CTK_CONF_MENUS 00334 void draw_menu(struct ctk_menu *m, struct ctk_menu *open) { 00335 #if CC_CONF_UNSIGNED_CHAR_BUGS 00336 unsigned char x2; 00337 unsigned int x, y; 00338 #else 00339 unsigned char x2; 00340 unsigned char x, y; 00341 #endif 00342 x = cursx; 00343 cputs(m->title); 00344 cputc(CH_SPACE); 00345 00346 if (m == open) { 00347 x2 = cursx; 00348 if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) { 00349 x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH; 00350 } 00351 00352 for(y = 0; y < m->nitems; y++) { 00353 if(y == m->active) { 00354 revers(0); 00355 } 00356 gotoxy(x, y + 1); 00357 if(m->items[y].title[0] == '-') { 00358 chline(CTK_CONF_MENUWIDTH); 00359 } else { 00360 cputs(m->items[y].title); 00361 } 00362 clearTo(x + CTK_CONF_MENUWIDTH); 00363 revers(1); 00364 } 00365 gotoxy(x2, 0); 00366 } 00367 } 00368 /*---------------------------------------------------------------------------*/ 00369 void ctk_draw_menus(struct ctk_menus *menus) { 00370 struct ctk_menu *m; 00371 00372 clip(0, SCREEN_HEIGHT); 00373 /* Draw menus */ 00374 gotoxy(0, 0); 00375 revers(1); 00376 for(m = menus->menus->next; m != NULL; m = m->next) { 00377 draw_menu(m, menus->open); 00378 } 00379 00380 clearTo(SCREEN_WIDTH - strlen(menus->desktopmenu->title) - 1); 00381 00382 /* Draw desktopmenu */ 00383 draw_menu(menus->desktopmenu, menus->open); 00384 00385 revers(0); 00386 } 00387 #endif /* CTK_CONF_MENUS */ 00388 /*---------------------------------------------------------------------------*/ 00389 /* Returns width and height of screen. */ 00390 unsigned char ctk_draw_width(void) { 00391 return SCREEN_WIDTH; 00392 } 00393 unsigned char ctk_draw_height(void) { 00394 return SCREEN_HEIGHT; 00395 } 00396