00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <string.h>
00052
00053 #include "contiki.h"
00054
00055 #include "ctk/ctk.h"
00056 #include "ctk/ctk-draw.h"
00057 #include "ctk/ctk-mouse.h"
00058
00059 static unsigned char height, width;
00060
00061 static unsigned char mode;
00062
00063 #if CTK_CONF_WINDOWS
00064 static struct ctk_window desktop_window;
00065 static struct ctk_window *windows;
00066 static struct ctk_window *dialog;
00067 #else
00068 static struct ctk_window *window;
00069 #endif
00070
00071 #if CTK_CONF_MENUS
00072 static struct ctk_menus menus;
00073 static struct ctk_menu *lastmenu;
00074 static struct ctk_menu desktopmenu;
00075 static unsigned char maxnitems;
00076 #endif
00077
00078 #ifndef NULL
00079 #define NULL (void *)0
00080 #endif
00081
00082 #define REDRAW_NONE 0
00083 #define REDRAW_ALL 1
00084 #define REDRAW_FOCUS 2
00085 #define REDRAW_WIDGETS 4
00086 #define REDRAW_MENUS 8
00087 #define REDRAW_MENUPART 16
00088
00089 #define MAX_REDRAWWIDGETS 4
00090 static unsigned char redraw;
00091 static struct ctk_widget *redraw_widgets[MAX_REDRAWWIDGETS];
00092 static unsigned char redraw_widgetptr;
00093
00094 #if CTK_CONF_ICONS
00095 static unsigned char iconx, icony;
00096 #define ICONX_START (width - 6)
00097 #define ICONY_START (height - 6 - CTK_CONF_MENUS)
00098 #define ICONX_DELTA -16
00099 #define ICONY_DELTA -5
00100 #define ICONY_MAX height
00101 #endif
00102
00103 #ifndef ctk_arch_keyavail
00104 unsigned char ctk_arch_keyavail(void);
00105 #endif
00106
00107 #ifndef ctk_arch_getkey
00108 ctk_arch_key_t ctk_arch_getkey(void);
00109 #endif
00110
00111 #ifndef ctk_arch_isprint
00112 unsigned char ctk_arch_isprint(ctk_arch_key_t key);
00113 #endif
00114
00115 PROCESS(ctk_process, "CTK Contiki GUI");
00116
00117
00118
00119
00120
00121 process_event_t
00122
00123
00124
00125
00126
00127 ctk_signal_keypress,
00128
00129
00130
00131 ctk_signal_widget_activate,
00132
00133
00134 ctk_signal_button_activate,
00135
00136
00137
00138 ctk_signal_widget_select,
00139
00140
00141 ctk_signal_button_hover,
00142
00143
00144
00145 ctk_signal_hyperlink_activate,
00146
00147
00148 ctk_signal_hyperlink_hover;
00149
00150
00151
00152 process_event_t ctk_signal_menu_activate;
00153
00154
00155
00156 process_event_t ctk_signal_window_close;
00157
00158 #if CTK_CONF_MOUSE_SUPPORT
00159
00160
00161
00162 process_event_t ctk_signal_pointer_move,
00163
00164
00165 ctk_signal_pointer_button;
00166 #endif
00167
00168 #if CTK_CONF_SCREENSAVER
00169
00170
00171 process_event_t ctk_signal_screensaver_stop,
00172
00173
00174 ctk_signal_screensaver_start;
00175 #endif
00176
00177
00178
00179 #if CTK_CONF_MOUSE_SUPPORT
00180 unsigned short mouse_x, mouse_y, mouse_button;
00181 #endif
00182
00183 #if CTK_CONF_SCREENSAVER
00184 static unsigned short screensaver_timer = 0;
00185 unsigned short ctk_screensaver_timeout = (5*60);
00186 static struct timer timer;
00187 #endif
00188
00189 static void CC_FASTCALL
00190 textentry_input(ctk_arch_key_t c,
00191 CC_REGISTER_ARG struct ctk_textentry *t);
00192
00193 #if CTK_CONF_MENUS
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 static void
00204 make_desktopmenu(void)
00205 {
00206 struct ctk_window *w;
00207
00208 desktopmenu.nitems = 0;
00209
00210 if(windows == NULL) {
00211 ctk_menuitem_add(&desktopmenu, "(No windows)");
00212 } else {
00213 for(w = windows; w != NULL; w = w->next) {
00214 ctk_menuitem_add(&desktopmenu, w->title);
00215 }
00216 }
00217 }
00218 #endif
00219
00220 #if CTK_CONF_ICONS
00221 static void
00222 arrange_icons(void)
00223 {
00224 struct ctk_widget *icon;
00225
00226 iconx = ICONX_START;
00227 icony = ICONY_START;
00228
00229 for(icon = desktop_window.active; icon != NULL; icon = icon->next) {
00230
00231 icon->x = iconx;
00232 icon->y = icony;
00233
00234 icony += ICONY_DELTA;
00235 if(icony >= ICONY_MAX) {
00236 icony = ICONY_START;
00237 iconx += ICONX_DELTA;
00238 }
00239 }
00240 }
00241 #endif
00242
00243 void
00244 ctk_restore(void)
00245 {
00246 ctk_draw_init();
00247
00248 height = ctk_draw_height();
00249 width = ctk_draw_width();
00250
00251 #if CTK_CONF_ICONS
00252 arrange_icons();
00253 #endif
00254
00255 redraw = REDRAW_ALL;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 void
00281 ctk_mode_set(unsigned char m) {
00282 mode = m;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 unsigned char
00292 ctk_mode_get(void) {
00293 return mode;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 void
00305 ctk_icon_add(CC_REGISTER_ARG struct ctk_widget *icon, struct process *p)
00306 {
00307 #if CTK_CONF_ICONS
00308 icon->widget.icon.owner = p;
00309 ctk_widget_add(&desktop_window, icon);
00310 arrange_icons();
00311 #endif
00312 }
00313 #if CTK_CONF_WINDOWS
00314
00315
00316
00317
00318
00319
00320
00321 void
00322 ctk_dialog_open(struct ctk_window *d)
00323 {
00324 dialog = d;
00325 redraw |= REDRAW_FOCUS;
00326 }
00327
00328
00329
00330
00331
00332
00333 void
00334 ctk_dialog_close(void)
00335 {
00336 dialog = NULL;
00337 redraw |= REDRAW_ALL;
00338 }
00339 #endif
00340
00341
00342
00343
00344
00345
00346
00347 void
00348 ctk_window_open(CC_REGISTER_ARG struct ctk_window *w)
00349 {
00350 #if CTK_CONF_WINDOWS
00351 struct ctk_window *w2;
00352
00353
00354 for(w2 = windows; w2 != w && w2 != NULL; w2 = w2->next);
00355 if(w2 == NULL) {
00356
00357
00358 w->next = windows;
00359 if(windows != NULL) {
00360 windows->prev = w;
00361 }
00362 windows = w;
00363 w->prev = NULL;
00364 } else {
00365
00366
00367 if(w != windows) {
00368 if(w->next != NULL) {
00369 w->next->prev = w->prev;
00370 }
00371 if(w->prev != NULL) {
00372 w->prev->next = w->next;
00373 }
00374 w->next = windows;
00375 windows->prev = w;
00376 windows = w;
00377 w->prev = NULL;
00378 }
00379 }
00380 #else
00381 window = w;
00382 #endif
00383
00384 #if CTK_CONF_MENUS
00385
00386 make_desktopmenu();
00387 #endif
00388
00389 redraw |= REDRAW_ALL;
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 void
00401 ctk_window_close(struct ctk_window *w)
00402 {
00403 #if CTK_CONF_WINDOWCLOSE
00404 static struct ctk_window *w2;
00405
00406 if(w == NULL) {
00407 return;
00408 }
00409
00410
00411 if(w == windows) {
00412 windows = w->next;
00413 if(windows != NULL) {
00414 windows->prev = NULL;
00415 }
00416 w->next = w->prev = NULL;
00417 } else {
00418
00419
00420
00421 for(w2 = windows; w2 != NULL && w2->next != w; w2 = w2->next);
00422
00423 if(w2 == NULL) {
00424
00425 return;
00426 }
00427
00428 if(w->next != NULL) {
00429 w->next->prev = w->prev;
00430 }
00431 w2->next = w->next;
00432
00433 w->next = w->prev = NULL;
00434 }
00435
00436 #if CTK_CONF_MENUS
00437
00438 make_desktopmenu();
00439 #endif
00440 redraw |= REDRAW_ALL;
00441 #endif
00442 }
00443 #if CTK_CONF_WINDOWS
00444
00445
00446
00447
00448
00449 static void
00450 make_windowbuttons(CC_REGISTER_ARG struct ctk_window *window)
00451 {
00452 unsigned char placement;
00453
00454 if(ctk_draw_windowtitle_height >= 2) {
00455 placement = -1 - ctk_draw_windowtitle_height/2;
00456 } else {
00457 placement = -1;
00458 }
00459 #if CTK_CONF_WINDOWMOVE
00460 CTK_BUTTON_NEW(&window->titlebutton, 0, placement,
00461 window->titlelen, window->title);
00462 #else
00463 CTK_LABEL_NEW(&window->titlebutton, 0, placement,
00464 window->titlelen, 1, window->title);
00465 #endif
00466 CTK_WIDGET_ADD(window, &window->titlebutton);
00467
00468 #if CTK_CONF_WINDOWCLOSE
00469 CTK_BUTTON_NEW(&window->closebutton, window->w - 3, placement,
00470 1, "x");
00471 #else
00472 CTK_LABEL_NEW(&window->closebutton, window->w - 4, placement,
00473 3, 1, " ");
00474 #endif
00475 CTK_WIDGET_ADD(window, &window->closebutton);
00476 }
00477 #endif
00478
00479
00480
00481
00482
00483
00484
00485 void
00486 ctk_window_clear(struct ctk_window *w)
00487 {
00488 w->active = w->inactive = w->focused = NULL;
00489
00490 #if CTK_CONF_WINDOWS
00491 make_windowbuttons(w);
00492 #endif
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void
00505 ctk_menu_add(struct ctk_menu *menu)
00506 {
00507 #if CTK_CONF_MENUS
00508 struct ctk_menu *m;
00509
00510 if(lastmenu == NULL) {
00511 lastmenu = menu;
00512 }
00513
00514 for(m = menus.menus; m->next != NULL; m = m->next) {
00515 if(m == menu) {
00516 return;
00517 }
00518 }
00519 m->next = menu;
00520 menu->next = NULL;
00521
00522 redraw |= REDRAW_MENUPART;
00523 #endif
00524 }
00525
00526
00527
00528
00529
00530
00531
00532 void
00533 ctk_menu_remove(struct ctk_menu *menu)
00534 {
00535 #if CTK_CONF_MENUS
00536 struct ctk_menu *m;
00537
00538 for(m = menus.menus; m->next != NULL; m = m->next) {
00539 if(m->next == menu) {
00540 m->next = menu->next;
00541 if(menu == lastmenu) {
00542 lastmenu = NULL;
00543 }
00544 redraw |= REDRAW_MENUPART;
00545 return;
00546 }
00547 }
00548 #endif
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 static void CC_FASTCALL
00560 do_redraw_all(unsigned char clipy1, unsigned char clipy2)
00561 {
00562 #if CTK_CONF_WINDOWS
00563 static struct ctk_widget *widget;
00564 struct ctk_window *w;
00565 unsigned char focus;
00566 #endif
00567
00568 if(mode != CTK_MODE_NORMAL && mode != CTK_MODE_WINDOWMOVE) {
00569 return;
00570 }
00571
00572 ctk_draw_clear(clipy1, clipy2);
00573
00574 #if CTK_CONF_WINDOWS
00575
00576 for(widget = desktop_window.active;
00577 widget != NULL; widget = widget->next) {
00578 ctk_draw_widget(widget, windows != NULL? 0: CTK_FOCUS_WINDOW, clipy1, clipy2);
00579 }
00580
00581
00582 if(windows != NULL) {
00583
00584 for(w = windows; w->next != NULL; w = w->next);
00585
00586
00587 for(; w != windows; w = w->prev) {
00588 ctk_draw_clear_window(w, 0, clipy1, clipy2);
00589 ctk_draw_window(w, 0, clipy1, clipy2, 1);
00590 }
00591
00592
00593 focus = mode == CTK_MODE_WINDOWMOVE?
00594 CTK_FOCUS_WIDGET|CTK_FOCUS_WINDOW:
00595 CTK_FOCUS_WINDOW;
00596 ctk_draw_clear_window(windows, focus, clipy1, clipy2);
00597 ctk_draw_window(windows, focus, clipy1, clipy2, 1);
00598 }
00599
00600
00601 if(dialog != NULL) {
00602 ctk_draw_dialog(dialog);
00603 }
00604 #else
00605 if(window != NULL) {
00606 ctk_draw_clear_window(window, CTK_FOCUS_WINDOW, clipy1, clipy2);
00607 ctk_draw_window(window, CTK_FOCUS_WINDOW, clipy1, clipy2, 0);
00608 }
00609 #endif
00610
00611 #if CTK_CONF_MENUS
00612 ctk_draw_menus(&menus);
00613 #endif
00614 }
00615 #if CTK_CONF_WINDOWS
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 void
00628 ctk_desktop_redraw(struct ctk_desktop *d)
00629 {
00630 if(PROCESS_CURRENT() == &ctk_process) {
00631 if(mode == CTK_MODE_NORMAL || mode == CTK_MODE_WINDOWMOVE) {
00632 do_redraw_all(CTK_CONF_MENUS, height);
00633 }
00634 } else {
00635 height = ctk_draw_height();
00636 width = ctk_draw_width();
00637
00638 redraw |= REDRAW_ALL;
00639 }
00640 }
00641 #endif
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 void
00653 ctk_window_redraw(struct ctk_window *w)
00654 {
00655
00656
00657 if(mode != CTK_MODE_NORMAL) {
00658 return;
00659 }
00660
00661 #if CTK_CONF_WINDOWS
00662 if(w == dialog) {
00663 ctk_draw_dialog(w);
00664 } else if(dialog == NULL &&
00665 #if CTK_CONF_MENUS
00666 menus.open == NULL &&
00667 #endif
00668 windows == w)
00669 #endif
00670 {
00671 ctk_draw_window(w, CTK_FOCUS_WINDOW, 0, height, 0);
00672 }
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 static void
00685 window_new(CC_REGISTER_ARG struct ctk_window *window,
00686 unsigned char w, unsigned char h, char *title)
00687 {
00688 #if CTK_CONF_WINDOWS
00689 if(w >= width - 2) {
00690 window->x = 0;
00691 } else {
00692 window->x = (width - w - 2) / 2;
00693 }
00694 if(h >= height - 2 - ctk_draw_windowtitle_height) {
00695 window->y = 0;
00696 } else {
00697 window->y = (height - h - 2 - ctk_draw_windowtitle_height) / 2;
00698 }
00699 #endif
00700
00701 window->w = w;
00702 window->h = h;
00703 window->title = title;
00704 if(title != NULL) {
00705 window->titlelen = (unsigned char)strlen(title);
00706 } else {
00707 window->titlelen = 0;
00708 }
00709 window->next = window->prev = NULL;
00710 window->owner = PROCESS_CURRENT();
00711 window->active = window->inactive = window->focused = NULL;
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 void
00733 ctk_window_new(struct ctk_window *window,
00734 unsigned char w, unsigned char h, char *title)
00735 {
00736 window_new(window, w, h, title);
00737
00738 #if CTK_CONF_WINDOWS
00739 make_windowbuttons(window);
00740 #endif
00741 }
00742 #if CTK_CONF_WINDOWS
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 void
00757 ctk_dialog_new(CC_REGISTER_ARG struct ctk_window *dialog,
00758 unsigned char w, unsigned char h)
00759 {
00760 window_new(dialog, w, h, NULL);
00761 }
00762 #endif
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 void
00776 ctk_menu_new(CC_REGISTER_ARG struct ctk_menu *menu, char *title)
00777 {
00778 #if CTK_CONF_MENUS
00779 menu->next = NULL;
00780 menu->title = title;
00781 menu->titlelen = (unsigned char)strlen(title);
00782 menu->active = 0;
00783 menu->nitems = 0;
00784 #endif
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 unsigned char
00801 ctk_menuitem_add(CC_REGISTER_ARG struct ctk_menu *menu, char *name)
00802 {
00803 #if CTK_CONF_MENUS
00804 if(menu->nitems == CTK_MAXMENUITEMS) {
00805 return 0;
00806 }
00807 menu->items[menu->nitems].title = name;
00808 menu->items[menu->nitems].titlelen = (unsigned char)strlen(name);
00809 return menu->nitems++;
00810 #else
00811 return 0;
00812 #endif
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822 static void CC_FASTCALL
00823 add_redrawwidget(struct ctk_widget *w)
00824 {
00825 static unsigned char i;
00826
00827 if(redraw_widgetptr == MAX_REDRAWWIDGETS) {
00828 redraw |= REDRAW_FOCUS;
00829 } else {
00830 redraw |= REDRAW_WIDGETS;
00831
00832
00833 for(i = 0; i < redraw_widgetptr; ++i) {
00834 if(redraw_widgets[i] == w) {
00835 return;
00836 }
00837 }
00838 redraw_widgets[redraw_widgetptr++] = w;
00839 }
00840 }
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 static void
00854 widget_redraw(struct ctk_widget *widget)
00855 {
00856 struct ctk_window *window;
00857
00858 if(mode != CTK_MODE_NORMAL || widget == NULL) {
00859 return;
00860 }
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 #if CTK_CONF_MENUS
00871 if(menus.open == NULL)
00872 #endif
00873 {
00874 window = widget->window;
00875 #if CTK_CONF_WINDOWS
00876 if(window == dialog) {
00877 ctk_draw_widget(widget, CTK_FOCUS_DIALOG, 0, height);
00878 } else if(dialog == NULL &&
00879 (window == windows ||
00880 window == &desktop_window))
00881 #endif
00882 {
00883 ctk_draw_widget(widget, CTK_FOCUS_WINDOW, 0, height);
00884 }
00885 }
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 void
00903 ctk_widget_redraw(struct ctk_widget *widget)
00904 {
00905 if(mode != CTK_MODE_NORMAL || widget == NULL) {
00906 return;
00907 }
00908
00909
00910
00911 add_redrawwidget(widget);
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 void CC_FASTCALL
00926 ctk_widget_add(CC_REGISTER_ARG struct ctk_window *window,
00927 CC_REGISTER_ARG struct ctk_widget *widget)
00928 {
00929 if(widget->type == CTK_WIDGET_LABEL ||
00930 widget->type == CTK_WIDGET_SEPARATOR) {
00931 widget->next = window->inactive;
00932 window->inactive = widget;
00933 widget->window = window;
00934 } else {
00935 widget->next = window->active;
00936 window->active = widget;
00937 widget->window = window;
00938 }
00939 }
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 unsigned char
00951 ctk_desktop_width(struct ctk_desktop *d)
00952 {
00953 return ctk_draw_width();
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 unsigned char
00966 ctk_desktop_height(struct ctk_desktop *d)
00967 {
00968 return ctk_draw_height();
00969 }
00970
00971
00972
00973
00974
00975
00976
00977 static void CC_FASTCALL
00978 select_widget(struct ctk_widget *focus)
00979 {
00980 struct ctk_window *window;
00981
00982 window = focus->window;
00983
00984 if(focus != window->focused) {
00985 window->focused = focus;
00986
00987
00988
00989 if(window->focused->type == CTK_WIDGET_HYPERLINK) {
00990 process_post(window->owner, ctk_signal_hyperlink_hover, window->focused);
00991 } else if(window->focused->type == CTK_WIDGET_BUTTON) {
00992 process_post(window->owner, ctk_signal_button_hover, window->focused);
00993 }
00994
00995 add_redrawwidget(window->focused);
00996
00997 process_post(focus->window->owner, ctk_signal_widget_select, focus);
00998 }
00999 }
01000
01001 #define UP 0
01002 #define DOWN 1
01003 #define LEFT 2
01004 #define RIGHT 3
01005 static void CC_FASTCALL
01006 switch_focus_widget(unsigned char direction)
01007 {
01008 #if CTK_CONF_WINDOWS
01009 register struct ctk_window *window;
01010 #endif
01011 register struct ctk_widget *focus;
01012 struct ctk_widget *widget;
01013
01014 #if CTK_CONF_WINDOWS
01015 if(dialog != NULL) {
01016 window = dialog;
01017 } else {
01018 window = windows;
01019 }
01020
01021
01022
01023 if(window == NULL) {
01024 window = &desktop_window;
01025 }
01026 #else
01027 if(window == NULL) {
01028 return;
01029 }
01030 #endif
01031
01032 focus = window->focused;
01033 if(focus == NULL) {
01034 focus = window->active;
01035 if(focus == NULL) {
01036 return;
01037 }
01038 }
01039 add_redrawwidget(focus);
01040
01041 if((direction & 1) == 0) {
01042
01043 focus = focus->next;
01044 } else {
01045
01046 for(widget = window->active;
01047 widget != NULL; widget = widget->next) {
01048 if(widget->next == focus) {
01049 break;
01050 }
01051 }
01052 focus = widget;
01053 if(focus == NULL) {
01054 if(window->active != NULL) {
01055 for(focus = window->active;
01056 focus->next != NULL; focus = focus->next);
01057 }
01058 }
01059 }
01060 if(focus == NULL) {
01061 focus = window->active;
01062 }
01063
01064 select_widget(focus);
01065 }
01066
01067 #if CTK_CONF_MENUS
01068 static void
01069 switch_open_menu(unsigned char rightleft)
01070 {
01071 struct ctk_menu *menu;
01072
01073 if(rightleft == 0) {
01074
01075 for(menu = menus.menus; menu != NULL; menu = menu->next) {
01076 if(menu->next == menus.open) {
01077 break;
01078 }
01079 }
01080 lastmenu = menus.open;
01081 menus.open = menu;
01082 if(menus.open == NULL) {
01083 for(menu = menus.menus;
01084 menu->next != NULL; menu = menu->next);
01085 menus.open = menu;
01086 }
01087 } else {
01088
01089 lastmenu = menus.open;
01090 menus.open = menus.open->next;
01091 if(menus.open == NULL) {
01092 menus.open = menus.menus;
01093 }
01094 }
01095
01096 menus.open->active = 0;
01097 }
01098
01099 static void
01100 switch_menu_item(unsigned char updown)
01101 {
01102 register struct ctk_menu *m;
01103
01104 m = menus.open;
01105
01106 if(updown == 0) {
01107
01108 if(m->active == 0) {
01109 m->active = m->nitems - 1;
01110 } else {
01111 --m->active;
01112 if(m->items[m->active].title[0] == '-') {
01113 --m->active;
01114 }
01115 }
01116 } else {
01117
01118 if(m->active >= m->nitems - 1) {
01119 m->active = 0;
01120 } else {
01121 ++m->active;
01122 if(m->items[m->active].title[0] == '-') {
01123 ++m->active;
01124 }
01125 }
01126 }
01127 }
01128 #endif
01129
01130 static unsigned char CC_FASTCALL
01131 activate(CC_REGISTER_ARG struct ctk_widget *w)
01132 {
01133 if(w->type == CTK_WIDGET_BUTTON) {
01134 #if CTK_CONF_WINDOWCLOSE
01135 if(w == (struct ctk_widget *)&windows->closebutton) {
01136 process_post(w->window->owner, ctk_signal_window_close, windows);
01137 ctk_window_close(windows);
01138 return REDRAW_ALL;
01139 } else
01140 #endif
01141 #if CTK_CONF_WINDOWMOVE
01142 if(w == (struct ctk_widget *)&windows->titlebutton) {
01143 mode = CTK_MODE_WINDOWMOVE;
01144 return REDRAW_ALL;
01145 } else
01146 #endif
01147 {
01148 process_post(w->window->owner, ctk_signal_widget_activate, w);
01149 }
01150 #if CTK_CONF_ICONS
01151 } else if(w->type == CTK_WIDGET_ICON) {
01152 if(w->widget.icon.owner != PROCESS_NONE) {
01153 process_post(w->widget.icon.owner, ctk_signal_widget_activate, w);
01154 } else {
01155 process_post(w->window->owner, ctk_signal_widget_activate, w);
01156 }
01157 #endif
01158 } else if(w->type == CTK_WIDGET_HYPERLINK) {
01159 process_post(PROCESS_BROADCAST, ctk_signal_hyperlink_activate, w);
01160 } else if(w->type == CTK_WIDGET_TEXTENTRY) {
01161 if(w->widget.textentry.state == CTK_TEXTENTRY_NORMAL) {
01162 w->widget.textentry.state = CTK_TEXTENTRY_EDIT;
01163 textentry_input(0, (struct ctk_textentry *)w);
01164 } else {
01165 w->widget.textentry.state = CTK_TEXTENTRY_NORMAL;
01166 process_post(w->window->owner, ctk_signal_widget_activate, w);
01167 }
01168 add_redrawwidget(w);
01169 return REDRAW_WIDGETS;
01170 } else {
01171 process_post(w->window->owner, ctk_signal_widget_activate, w);
01172 }
01173 return REDRAW_NONE;
01174 }
01175
01176 #ifdef SDCC
01177
01178
01179
01180 unsigned char
01181 ctk_textentry_input_null(ctk_arch_key_t c, struct ctk_textentry *t)
01182 {
01183 return 0;
01184 }
01185 #endif
01186
01187 static void CC_FASTCALL
01188 textentry_input(ctk_arch_key_t c, CC_REGISTER_ARG struct ctk_textentry *t)
01189 {
01190 register char *cptr, *cptr2;
01191 static unsigned char len, txpos, typos, tlen;
01192
01193 if(t->input != NULL && t->input(c, t)) {
01194 return;
01195 }
01196
01197 txpos = t->xpos;
01198 typos = t->ypos;
01199 tlen = t->len;
01200
01201 cptr = &t->text[txpos + typos * (tlen + 1)];
01202
01203 switch(c) {
01204 case CH_CURS_LEFT:
01205 if(txpos > 0) {
01206 --txpos;
01207 }
01208 break;
01209
01210 case CH_CURS_RIGHT:
01211 if(txpos < tlen - 1 && *cptr != 0) {
01212 ++txpos;
01213 }
01214 break;
01215
01216 case CH_CURS_UP:
01217 txpos = 0;
01218 break;
01219
01220 case 0:
01221 case CH_CURS_DOWN:
01222 txpos = (unsigned char)strlen(t->text);
01223 if(txpos == tlen) {
01224 --txpos;
01225 }
01226 break;
01227
01228 case CH_ENTER:
01229 activate((struct ctk_widget *)t);
01230 switch_focus_widget(DOWN);
01231 break;
01232
01233 case CTK_CONF_WIDGETDOWN_KEY:
01234 t->state = CTK_TEXTENTRY_NORMAL;
01235 switch_focus_widget(DOWN);
01236 break;
01237 case CTK_CONF_WIDGETUP_KEY:
01238 t->state = CTK_TEXTENTRY_NORMAL;
01239 switch_focus_widget(UP);
01240 break;
01241
01242 default:
01243 len = tlen - txpos;
01244 if(c == CH_DEL) {
01245 if(len == 1 && *cptr != 0) {
01246 *cptr = 0;
01247 } else {
01248 if(txpos > 0) {
01249 --txpos;
01250 strcpy(cptr - 1, cptr);
01251 }
01252 }
01253 } else {
01254 if(ctk_arch_isprint(c)) {
01255 if(len > 1) {
01256 cptr2 = cptr + len - 1;
01257 while(cptr2 > cptr) {
01258 *cptr2 = *(cptr2 - 1);
01259 --cptr2;
01260 }
01261 ++txpos;
01262 }
01263 *cptr = c;
01264 }
01265 }
01266 break;
01267 }
01268
01269 t->xpos = txpos;
01270 t->ypos = typos;
01271 }
01272
01273 #if CTK_CONF_MENUS
01274 static unsigned char
01275 activate_menu(void)
01276 {
01277 struct ctk_window *w;
01278
01279 lastmenu = menus.open;
01280 if(menus.open == &desktopmenu) {
01281 for(w = windows; w != NULL; w = w->next) {
01282 if(w->title == desktopmenu.items[desktopmenu.active].title) {
01283 ctk_window_open(w);
01284 menus.open = NULL;
01285 return REDRAW_ALL;
01286 }
01287 }
01288 } else {
01289 process_post(PROCESS_BROADCAST, ctk_signal_menu_activate, menus.open);
01290 }
01291 menus.open = NULL;
01292 return REDRAW_MENUPART;
01293 }
01294
01295 static unsigned char
01296 menus_input(ctk_arch_key_t c)
01297 {
01298 if(menus.open->nitems > maxnitems) {
01299 maxnitems = menus.open->nitems;
01300 }
01301
01302 switch(c) {
01303 case CH_CURS_RIGHT:
01304 switch_open_menu(1);
01305 return REDRAW_MENUPART;
01306
01307 case CH_CURS_DOWN:
01308 switch_menu_item(1);
01309 return REDRAW_MENUS;
01310
01311 case CH_CURS_LEFT:
01312 switch_open_menu(0);
01313 return REDRAW_MENUPART;
01314
01315 case CH_CURS_UP:
01316 switch_menu_item(0);
01317 return REDRAW_MENUS;
01318
01319 case CH_ENTER:
01320 return activate_menu();
01321
01322 case CTK_CONF_MENU_KEY:
01323 lastmenu = menus.open;
01324 menus.open = NULL;
01325 return REDRAW_MENUPART;
01326 }
01327
01328 return REDRAW_NONE;
01329 }
01330 #endif
01331
01332 #if CTK_CONF_SCREENSAVER
01333 static void
01334 handle_timer(void)
01335 {
01336 if(mode == CTK_MODE_NORMAL) {
01337 ++screensaver_timer;
01338 if(screensaver_timer >= ctk_screensaver_timeout) {
01339 process_post(PROCESS_BROADCAST, ctk_signal_screensaver_start, NULL);
01340 #ifdef CTK_SCREENSAVER_INIT
01341 CTK_SCREENSAVER_INIT();
01342 #endif
01343
01344 screensaver_timer = 0;
01345 }
01346 }
01347 }
01348 #endif
01349
01350 static void
01351 unfocus_widget(CC_REGISTER_ARG struct ctk_widget *w)
01352 {
01353 if(w != NULL) {
01354 redraw |= REDRAW_WIDGETS;
01355 add_redrawwidget(w);
01356 if(CTK_WIDGET_TYPE(w) == CTK_WIDGET_TEXTENTRY) {
01357 ((struct ctk_textentry *)w)->state =
01358 CTK_TEXTENTRY_NORMAL;
01359 }
01360 w->window->focused = NULL;
01361 }
01362 }
01363
01364 PROCESS_THREAD(ctk_process, ev, data)
01365 {
01366 static ctk_arch_key_t c;
01367 static unsigned char i;
01368 #if CTK_CONF_WINDOWS
01369 register struct ctk_window *window;
01370 #endif
01371 register struct ctk_widget *widget;
01372 register struct ctk_widget **widgetptr;
01373 #if CTK_CONF_MOUSE_SUPPORT
01374 static unsigned char mxc, myc, mouse_button_changed, mouse_moved,
01375 mouse_clicked;
01376 #if CTK_CONF_MENUS
01377 static unsigned char menux;
01378 register struct ctk_menu *menu;
01379 #endif
01380 #endif
01381
01382 PROCESS_BEGIN();
01383
01384 #if CTK_CONF_MENUS
01385 ctk_menu_new(&desktopmenu, "Desktop");
01386 make_desktopmenu();
01387 menus.menus = menus.desktopmenu = &desktopmenu;
01388 #endif
01389
01390 #if CTK_CONF_MOUSE_SUPPORT
01391 ctk_mouse_init();
01392 ctk_mouse_show();
01393 #endif
01394
01395 ctk_restore();
01396
01397 #if CTK_CONF_WINDOWS
01398 desktop_window.owner = &ctk_process;
01399 #endif
01400
01401 ctk_signal_keypress = process_alloc_event();
01402
01403 ctk_signal_button_activate =
01404 ctk_signal_widget_activate = process_alloc_event();
01405
01406 ctk_signal_button_hover =
01407 ctk_signal_hyperlink_hover =
01408 ctk_signal_widget_select = process_alloc_event();
01409
01410 ctk_signal_hyperlink_activate = process_alloc_event();
01411
01412 ctk_signal_menu_activate = process_alloc_event();
01413
01414 ctk_signal_window_close = process_alloc_event();
01415
01416 #if CTK_CONF_MOUSE_SUPPORT
01417 ctk_signal_pointer_move = process_alloc_event();
01418 ctk_signal_pointer_button = process_alloc_event();
01419 #endif
01420
01421 #if CTK_CONF_SCREENSAVER
01422 ctk_signal_screensaver_start = process_alloc_event();
01423 ctk_signal_screensaver_stop = process_alloc_event();
01424 #endif
01425
01426 mode = CTK_MODE_NORMAL;
01427
01428 #if CTK_CONF_ICONS
01429 iconx = ICONX_START;
01430 icony = ICONY_START;
01431 #endif
01432
01433 #if CTK_CONF_SCREENSAVER
01434 timer_set(&timer, CLOCK_SECOND);
01435 #endif
01436
01437 while(1) {
01438 process_poll(&ctk_process);
01439 PROCESS_WAIT_EVENT();
01440
01441 #if CTK_CONF_SCREENSAVER
01442 if(timer_expired(&timer)) {
01443 timer_reset(&timer);
01444 handle_timer();
01445 }
01446 #endif
01447
01448 #if CTK_CONF_MENUS
01449 if(menus.open != NULL) {
01450 maxnitems = menus.open->nitems;
01451 } else {
01452 maxnitems = 0;
01453 }
01454 #endif
01455
01456 #if CTK_CONF_MOUSE_SUPPORT
01457 mouse_button_changed = mouse_moved = mouse_clicked = 0;
01458
01459
01460 if(ctk_mouse_button() != mouse_button) {
01461 mouse_button = ctk_mouse_button();
01462 mouse_button_changed = 1;
01463 if(mouse_button == 0) {
01464 mouse_clicked = 1;
01465 }
01466 }
01467
01468
01469 if(ctk_mouse_x() != mouse_x ||
01470 ctk_mouse_y() != mouse_y) {
01471 mouse_x = ctk_mouse_x();
01472 mouse_y = ctk_mouse_y();
01473 mouse_moved = 1;
01474 }
01475
01476 mxc = ctk_mouse_xtoc(mouse_x);
01477 myc = ctk_mouse_ytoc(mouse_y);
01478 #endif
01479
01480 #if CTK_CONF_SCREENSAVER
01481 if(mode == CTK_MODE_SCREENSAVER) {
01482 if(ctk_arch_keyavail()
01483 #if CTK_CONF_MOUSE_SUPPORT
01484 || mouse_moved || mouse_button_changed
01485 #endif
01486 ) {
01487 process_post(PROCESS_BROADCAST, ctk_signal_screensaver_stop, NULL);
01488 mode = CTK_MODE_NORMAL;
01489 }
01490 } else
01491 #endif
01492 if(mode == CTK_MODE_NORMAL) {
01493 #if CTK_CONF_MOUSE_SUPPORT
01494
01495
01496
01497 if(mouse_moved || mouse_button_changed) {
01498 ctk_mouse_show();
01499 #if CTK_CONF_SCREENSAVER
01500 screensaver_timer = 0;
01501 #endif
01502
01503 #if CTK_CONF_MENUS
01504 if(myc == 0) {
01505
01506
01507 if(mouse_clicked) {
01508 static unsigned char titlelen;
01509
01510
01511
01512
01513
01514
01515 menux = 1;
01516 for(menu = menus.menus->next;
01517 menu != NULL; menu = menu->next) {
01518 titlelen = menu->titlelen;
01519 if(mxc >= menux && mxc <= menux + titlelen) {
01520 break;
01521 }
01522 menux += titlelen;
01523 }
01524
01525
01526 if(mxc >= width - 7 &&
01527 mxc <= width - 1) {
01528 menu = &desktopmenu;
01529 }
01530
01531 menus.open = menu;
01532 redraw |= REDRAW_MENUPART;
01533 }
01534 } else {
01535 --myc;
01536
01537 if(menus.open != NULL) {
01538 static unsigned char nitems;
01539
01540
01541
01542
01543
01544 if(menus.open == &desktopmenu) {
01545 menux = width - CTK_CONF_MENUWIDTH;
01546 } else {
01547 menux = 1;
01548 for(menu = menus.menus->next; menu != menus.open;
01549 menu = menu->next) {
01550 menux += menu->titlelen;
01551 }
01552 }
01553
01554 nitems = menus.open->nitems;
01555
01556
01557 if(mxc >= menux && mxc <= menux + CTK_CONF_MENUWIDTH) {
01558 if(myc <= nitems) {
01559 menus.open->active = myc;
01560 } else {
01561 menus.open->active = nitems - 1;
01562 }
01563 }
01564
01565 if(mouse_clicked) {
01566 if(mxc >= menux && mxc <= menux + CTK_CONF_MENUWIDTH &&
01567 myc <= nitems) {
01568 redraw |= activate_menu();
01569 } else {
01570 lastmenu = menus.open;
01571 menus.open = NULL;
01572 redraw |= REDRAW_MENUPART;
01573 }
01574 } else {
01575 redraw |= REDRAW_MENUS;
01576 }
01577 } else {
01578 #endif
01579
01580 #if CTK_CONF_WINDOWS
01581
01582
01583 if(dialog != NULL) {
01584 window = dialog;
01585 } else {
01586 for(window = windows; window != NULL;
01587 window = window->next) {
01588
01589
01590 if(mxc >= window->x &&
01591 mxc <= window->x + window->w +
01592 2 * ctk_draw_windowborder_width &&
01593 myc >= window->y &&
01594 myc <= window->y + window->h +
01595 ctk_draw_windowtitle_height +
01596 ctk_draw_windowborder_height) {
01597 break;
01598 }
01599 }
01600 }
01601
01602
01603
01604
01605 if(window == NULL) {
01606 window = &desktop_window;
01607 }
01608
01609
01610
01611
01612
01613 if(windows != NULL &&
01614 window != windows &&
01615 windows->focused != NULL){
01616 unfocus_widget(windows->focused);
01617 }
01618 #endif
01619
01620 if(window != NULL) {
01621 #if CTK_CONF_WINDOWS
01622
01623
01624 if(dialog == NULL &&
01625 window != &desktop_window &&
01626 window != windows &&
01627 mouse_clicked) {
01628
01629 ctk_window_open(window);
01630 redraw |= REDRAW_ALL;
01631 } else {
01632
01633
01634
01635
01636 mxc = mxc - window->x - ctk_draw_windowborder_width;
01637 myc = myc - window->y - ctk_draw_windowtitle_height;
01638 #endif
01639
01640
01641
01642
01643 for(widget = window->active; widget != NULL;
01644 widget = widget->next) {
01645
01646 if(mxc >= widget->x &&
01647 mxc <= widget->x + widget->w + 1 &&
01648 myc >= widget->y &&
01649 myc <= widget->y + widget->h - 1) {
01650 break;
01651 }
01652 }
01653
01654
01655
01656
01657 if(mouse_moved
01658 #if CTK_CONF_WINDOWS
01659 && (window != &desktop_window || windows == NULL)
01660 #endif
01661 ) {
01662
01663 process_post(window->owner, ctk_signal_pointer_move, NULL);
01664
01665
01666
01667
01668 if(window->focused != NULL &&
01669 widget != window->focused) {
01670 unfocus_widget(window->focused);
01671 }
01672 redraw |= REDRAW_WIDGETS;
01673 if(widget != NULL) {
01674 select_widget(widget);
01675 }
01676 }
01677
01678 if(mouse_button_changed) {
01679 process_post(window->owner, ctk_signal_pointer_button,
01680 (process_data_t)(size_t)mouse_button);
01681 if(mouse_clicked && widget != NULL) {
01682 select_widget(widget);
01683 redraw |= activate(widget);
01684 }
01685 }
01686 #if CTK_CONF_WINDOWS
01687 }
01688 #endif
01689 }
01690 #if CTK_CONF_MENUS
01691 }
01692 }
01693 #endif
01694 }
01695 #endif
01696
01697 while(ctk_arch_keyavail()) {
01698
01699 ctk_mouse_hide();
01700
01701 #if CTK_CONF_SCREENSAVER
01702 screensaver_timer = 0;
01703 #endif
01704
01705 c = ctk_arch_getkey();
01706
01707 #if CTK_CONF_WINDOWS
01708 if(dialog != NULL) {
01709 window = dialog;
01710 } else if(windows != NULL) {
01711 window = windows;
01712 } else {
01713 window = &desktop_window;
01714 }
01715 #else
01716 if(window == NULL) {
01717 continue;
01718 }
01719 #endif
01720
01721
01722
01723
01724
01725 if(c == 3) {
01726 process_post(window->owner, PROCESS_EVENT_EXIT, NULL);
01727 }
01728
01729 widget = window->focused;
01730
01731 if(widget != NULL &&
01732 widget->type == CTK_WIDGET_TEXTENTRY &&
01733 widget->widget.textentry.state == CTK_TEXTENTRY_EDIT) {
01734 textentry_input(c, (struct ctk_textentry *)widget);
01735 add_redrawwidget(widget);
01736 #if CTK_CONF_MENUS
01737 } else if(menus.open != NULL) {
01738 redraw |= menus_input(c);
01739 #endif
01740 } else {
01741 switch(c) {
01742 case CTK_CONF_WIDGETDOWN_KEY:
01743 switch_focus_widget(DOWN);
01744 break;
01745 case CTK_CONF_WIDGETUP_KEY:
01746 switch_focus_widget(UP);
01747 break;
01748 #if CTK_CONF_MENUS
01749 case CTK_CONF_MENU_KEY:
01750 if(dialog == NULL) {
01751 if(lastmenu == NULL) {
01752 menus.open = menus.menus;
01753 } else {
01754 menus.open = lastmenu;
01755 }
01756 menus.open->active = 0;
01757 redraw |= REDRAW_MENUS;
01758 }
01759 break;
01760 #endif
01761 #if CTK_CONF_WINDOWS
01762 case CTK_CONF_WINDOWSWITCH_KEY:
01763 if(windows != NULL) {
01764 for(window = windows; window->next != NULL;
01765 window = window->next);
01766 ctk_window_open(window);
01767 }
01768 break;
01769 #endif
01770 default:
01771
01772 if(c == CH_ENTER &&
01773 widget != NULL) {
01774 redraw |= activate(widget);
01775 } else {
01776 if(widget != NULL &&
01777 widget->type == CTK_WIDGET_TEXTENTRY) {
01778 if(widget->widget.textentry.state == CTK_TEXTENTRY_NORMAL) {
01779 widget->widget.textentry.state = CTK_TEXTENTRY_EDIT;
01780 textentry_input(0, (struct ctk_textentry *)widget);
01781 }
01782 textentry_input(c, (struct ctk_textentry *)widget);
01783 add_redrawwidget(widget);
01784 } else {
01785 unfocus_widget(window->focused);
01786 process_post_synch(window->owner, ctk_signal_keypress,
01787 (process_data_t)(size_t)c);
01788 }
01789 }
01790 break;
01791 }
01792 }
01793
01794 #if 0
01795 if(redraw & REDRAW_WIDGETS) {
01796 widgetptr = redraw_widgets;
01797 for(i = 0; i < MAX_REDRAWWIDGETS; ++i) {
01798 widget_redraw(*widgetptr);
01799 *widgetptr = NULL;
01800 ++widgetptr;
01801 }
01802 redraw &= ~REDRAW_WIDGETS;
01803 redraw_widgetptr = 0;
01804 }
01805 #endif
01806 }
01807 #if CTK_CONF_WINDOWMOVE
01808 } else if(mode == CTK_MODE_WINDOWMOVE) {
01809
01810 redraw = 0;
01811
01812 window = windows;
01813
01814 #if CTK_CONF_MOUSE_SUPPORT
01815
01816
01817 if(mouse_moved) {
01818
01819 if(window->w + mxc + 2 >= width) {
01820 window->x = width - 2 - window->w;
01821 } else {
01822 window->x = mxc;
01823 }
01824
01825 if(window->h + myc + ctk_draw_windowtitle_height +
01826 ctk_draw_windowborder_height >= height) {
01827 window->y = height - window->h -
01828 ctk_draw_windowtitle_height - ctk_draw_windowborder_height;
01829 } else {
01830 window->y = myc;
01831 }
01832 #if CTK_CONF_MENUS
01833 if(window->y > 0) {
01834 --window->y;
01835 }
01836 #endif
01837
01838 redraw = REDRAW_ALL;
01839 }
01840
01841
01842
01843 if(mouse_button_changed &&
01844 mouse_button == 0) {
01845 mode = CTK_MODE_NORMAL;
01846 redraw = REDRAW_ALL;
01847 }
01848 #endif
01849
01850 while(mode == CTK_MODE_WINDOWMOVE && ctk_arch_keyavail()) {
01851
01852 #if CTK_CONF_SCREENSAVER
01853 screensaver_timer = 0;
01854 #endif
01855
01856 c = ctk_arch_getkey();
01857
01858 switch(c) {
01859 case CH_CURS_RIGHT:
01860 ++window->x;
01861 if(window->x + window->w + 1 >= width) {
01862 --window->x;
01863 }
01864 redraw = REDRAW_ALL;
01865 break;
01866 case CH_CURS_LEFT:
01867 if(window->x > 0) {
01868 --window->x;
01869 }
01870 redraw = REDRAW_ALL;
01871 break;
01872 case CH_CURS_DOWN:
01873 ++window->y;
01874 if(window->y + window->h + 1 + CTK_CONF_MENUS >= height) {
01875 --window->y;
01876 }
01877 redraw = REDRAW_ALL;
01878 break;
01879 case CH_CURS_UP:
01880 if(window->y > 0) {
01881 --window->y;
01882 }
01883 redraw = REDRAW_ALL;
01884 break;
01885 default:
01886 mode = CTK_MODE_NORMAL;
01887 redraw = REDRAW_ALL;
01888 break;
01889 }
01890 }
01891 #endif
01892 }
01893
01894 if(redraw & REDRAW_ALL) {
01895 do_redraw_all(CTK_CONF_MENUS, height);
01896 #if CTK_CONF_MENUS
01897 } else if(redraw & REDRAW_MENUPART) {
01898 do_redraw_all(CTK_CONF_MENUS, maxnitems + 1);
01899 } else if(redraw & REDRAW_MENUS) {
01900 ctk_draw_menus(&menus);
01901 #endif
01902 } else if(redraw & REDRAW_FOCUS) {
01903 #if CTK_CONF_WINDOWS
01904 if(dialog != NULL) {
01905 ctk_window_redraw(dialog);
01906 } else if(windows != NULL) {
01907 ctk_window_redraw(windows);
01908 } else {
01909 ctk_window_redraw(&desktop_window);
01910 }
01911 #else
01912 if(window != NULL) {
01913 ctk_window_redraw(window);
01914 }
01915 #endif
01916 } else if(redraw & REDRAW_WIDGETS) {
01917 widgetptr = redraw_widgets;
01918 for(i = 0; i < MAX_REDRAWWIDGETS; ++i) {
01919 widget_redraw(*widgetptr);
01920 *widgetptr = NULL;
01921 ++widgetptr;
01922 }
01923 }
01924 redraw = 0;
01925 redraw_widgetptr = 0;
01926 }
01927
01928 PROCESS_END();
01929 }
01930
01931
01932