blob: e93f5a92b2d0cd9027fd29e2b4c636bbc8d92fbf [file] [log] [blame]
adamdunkels4f45d1f2004-08-09 20:53:08 +00001
adamdunkels4f45d1f2004-08-09 20:53:08 +00002
adamdunkelsa726d4f2004-09-05 07:09:41 +00003#include "ctk.h"
4#include "ctk-draw.h"
5#include "ctk-draw-service.h"
adamdunkels4f45d1f2004-08-09 20:53:08 +00006
adamdunkelsa726d4f2004-09-05 07:09:41 +00007#include "ctk-80col-asm.h"
adamdunkels4f45d1f2004-08-09 20:53:08 +00008
adamdunkelsa726d4f2004-09-05 07:09:41 +00009#include <string.h>
10
11unsigned char ctk_80col_cursx, ctk_80col_cursy;
12unsigned char ctk_80col_reversed;
13unsigned char ctk_80col_color;
14unsigned char *ctk_80col_bitmapptr;
15unsigned char ctk_80col_underline = 0;
adamdunkels4f45d1f2004-08-09 20:53:08 +000016
17#define SCREEN_HEIGHT 25
18#define SCREEN_WIDTH 80
19
20#define SCREENADDR 0xdc00
21#define HIRESADDR 0xe000
22
23unsigned char ctk_80col_lefttab[256];
24unsigned char ctk_80col_righttab[256];
25
adamdunkelsa726d4f2004-09-05 07:09:41 +000026unsigned short ctk_80col_yhiresaddr[25] =
adamdunkels4f45d1f2004-08-09 20:53:08 +000027 {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR,
28 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR,
29 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR,
30 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR,
31 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR,
32 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR,
33 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR,
34 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR,
35 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR,
36 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR,
37 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR,
38 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR,
39 24 * 320 + HIRESADDR};
40
41/*---------------------------------------------------------------------------*/
adamdunkelsa726d4f2004-09-05 07:09:41 +000042/*void
adamdunkels4f45d1f2004-08-09 20:53:08 +000043ctk_arch_draw_char(char c,
44 unsigned char xpos,
45 unsigned char ypos,
46 unsigned char reversedflag,
47 unsigned char color)
48{
adamdunkelsa726d4f2004-09-05 07:09:41 +000049 ctk_80col_cursx = xpos;
50 ctk_80col_cursy = ypos;
51 ctk_80col_reversed = reversedflag;
52 ctk_80col_color = color;
adamdunkels4f45d1f2004-08-09 20:53:08 +000053
adamdunkelsa726d4f2004-09-05 07:09:41 +000054 ctk_80col_cputc(c);
55}*/
adamdunkels4f45d1f2004-08-09 20:53:08 +000056/*---------------------------------------------------------------------------*/
57#pragma optimize(push, off)
58static void
59nmi2(void)
60{
61 asm("pla");
62 asm("sta $01");
63 asm("pla");
64 asm("rti");
65}
66#pragma optimize(pop)
67/*---------------------------------------------------------------------------*/
68#pragma optimize(push, off)
69static void
70nmi(void)
71{
72 asm("sei");
73 asm("pha");
74 asm("inc $d020");
75 asm("lda $01");
76 asm("pha");
77 asm("lda #$36");
78 asm("sta $01");
79 asm("lda #>_nmi2");
80 asm("pha");
81 asm("lda #<_nmi2");
82 asm("pha");
83 asm("php");
84 asm("jmp ($0318)");
85
86 nmi2();
87}
88#pragma optimize(pop)
89/*---------------------------------------------------------------------------*/
90#pragma optimize(push, off)
91static void
92setup_nmi(void)
93{
94 asm("lda #<_nmi");
95 asm("sta $fffa");
96 asm("lda #>_nmi");
97 asm("sta $fffb");
98 return;
99 nmi();
100}
101#pragma optimize(pop)
102/*---------------------------------------------------------------------------*/
103#pragma optimize(push, off)
104void
105ctk_80col_init(void)
106{
107 int i;
108
109
110 setup_nmi();
111
112 /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for
113 hires/colors. */
114 VIC.ctrl1 = 0x3b; /* $D011 */
115 VIC.addr = 0x78; /* $D018 */
116 VIC.ctrl2 = 0xc8; /* $D016 */
117 CIA2.pra = 0x00; /* $DD00 */
118
119 VIC.bordercolor = 0x0f; /* $D020 */
120 VIC.bgcolor0 = 0x0b; /* $D021 */
121
122 /* Fill color memory. */
123 asm("sei");
124 asm("lda $01");
125 asm("pha");
126 asm("lda #$30");
127 asm("sta $01");
128 asm("ldx #0");
129 asm("lda #$bf");
130 asm("fillcolorloop:");
131 asm("sta $dc00,x");
132 asm("sta $dd00,x");
133 asm("sta $de00,x");
134 asm("sta $df00,x");
135 asm("inx");
136 asm("bne fillcolorloop");
137
138 /* Setup sprite pointers */
139 asm("ldx #$fd");
140 asm("stx $dff8");
141 asm("inx");
142 asm("stx $dff9");
143 asm("pla");
144 asm("sta $01");
145 asm("cli");
146
147 /* Fill hires memory with 0. */
148
149 asm("lda $fd");
150 asm("pha");
151 asm("lda $fe");
152 asm("pha");
153 asm("lda #0");
154 asm("sta $fd");
155 asm("lda #$e0");
156 asm("sta $fe");
157 asm("ldy #0");
158 asm("lda #0");
159 asm("clrscrnloop:");
160 asm("lda #$55");
161 asm("sta ($fd),y");
162 asm("iny");
163 asm("lda #$aa");
164 asm("sta ($fd),y");
165 asm("iny");
166 asm("bne clrscrnloop");
167 asm("inc $fe");
168 asm("lda $fe");
169 asm("cmp #$ff");
170 asm("bne clrscrnloop");
171
172 asm("ldy #$00");
173 asm("clrscrnloop2:");
174 asm("lda #$55");
175 asm("sta $ff00,y");
176 asm("iny");
177 asm("lda #$aa");
178 asm("sta $ff00,y");
179 asm("iny");
180 asm("cpy #$40");
181 asm("bne clrscrnloop2");
182
183
184 asm("pla");
185 asm("sta $fe");
186 asm("pla");
187 asm("sta $fd");
188
189
190 /* ctk_draw_clear(0, 24);*/
191
192 for(i = 0; i < 256; ++i) {
193 ctk_80col_lefttab[i] =
194 ((i & 0x40) << 1) |
195 ((i & 0x10) << 2) |
196 ((i & 0x04) << 3) |
197 ((i & 0x01) << 4);
198 ctk_80col_righttab[i] =
199 ((i & 0x40) >> 3) |
200 ((i & 0x10) >> 2) |
201 ((i & 0x04) >> 1) |
202 ((i & 0x01));
203 }
204
205#if 0
206 /* Setup mouse pointer sprite. */
adamdunkelsa726d4f2004-09-05 07:09:41 +0000207 asm("lda %v+%w", ctk_80col_theme,
208 offsetof(struct ctk_80col_theme, pointermaskcolor));
adamdunkels4f45d1f2004-08-09 20:53:08 +0000209 asm("sta $d027");
adamdunkelsa726d4f2004-09-05 07:09:41 +0000210 asm("lda %v+%w", ctk_80col_theme,
211 offsetof(struct ctk_80col_theme, pointercolor));
adamdunkels4f45d1f2004-08-09 20:53:08 +0000212 asm("sta $d028");
213
adamdunkelsa726d4f2004-09-05 07:09:41 +0000214 ptr1 = ctk_80col_theme.pointer;
adamdunkels4f45d1f2004-08-09 20:53:08 +0000215 ptr2 = (unsigned char *)0xff40;
216
217 for(i = 0; i < 0x80; ++i) {
218 *ptr2++ = *ptr1++;
219 }
220#endif
221 return;
222}
223#pragma optimize(pop)
224/*---------------------------------------------------------------------------*/
adamdunkelsa726d4f2004-09-05 07:09:41 +0000225/*static unsigned char cursx, cursy;
226 static unsigned char reversed;*/
227
228/*-----------------------------------------------------------------------------------*/
229static void CC_FASTCALL
230cputc(char c)
231{
232 /* ctk_arch_draw_char(c, cursx, cursy, reversed, 0);*/
233 ctk_80col_cputc(c);
234 /* ++cursx;*/
235}
236/*-----------------------------------------------------------------------------------*/
237unsigned char
238wherex(void)
239{
240 return ctk_80col_cursx;
241}
242/*-----------------------------------------------------------------------------------*/
243unsigned char
244wherey(void)
245{
246 return ctk_80col_cursy;
247}
248/*-----------------------------------------------------------------------------------*/
249/*void
250clrscr(void)
251{
252 unsigned char x, y;
253
254 for(x = 0; x < SCREEN_WIDTH; ++x) {
255 for(y = 0; y < SCREEN_HEIGHT; ++y) {
256 gotoxy(x, y);
257 cputc(' ');
258 }
259 }
260}*/
261/*-----------------------------------------------------------------------------------*/
262#define revers(c) ctk_80col_reversed = c
263/*-----------------------------------------------------------------------------------*/
264static void CC_FASTCALL
265_cputs(char *str)
266{
267 char *ptr = str;
268
269 while(*ptr != 0) {
270 cputc(*ptr++);
271 }
272
273 /* int i;
274 for(i = 0; i < strlen(str); ++i) {
275 cputc(str[i]);
276 }*/
277}
278/*-----------------------------------------------------------------------------------*/
279static void CC_FASTCALL
280cclear(unsigned char length)
281{
282 int i;
283 for(i = 0; i < length; ++i) {
284 cputc(' ');
285 }
286}
287/*-----------------------------------------------------------------------------------*/
288void CC_FASTCALL
289chline(unsigned char length)
290{
291 int i;
292 for(i = 0; i < length; ++i) {
293 cputc('-');
294 }
295}
296/*-----------------------------------------------------------------------------------*/
297void CC_FASTCALL
298cvline(unsigned char length)
299{
300 int i;
301 for(i = 0; i < length; ++i) {
302 cputc('|');
303 --ctk_80col_cursx;
304 ++ctk_80col_cursy;
305 }
306}
307/*-----------------------------------------------------------------------------------*/
308void CC_FASTCALL
309gotoxy(unsigned char x, unsigned char y)
310{
311 ctk_80col_cursx = x;
312 ctk_80col_cursy = y;
313}
314/*-----------------------------------------------------------------------------------*/
315void CC_FASTCALL
316cclearxy(unsigned char x, unsigned char y, unsigned char length)
317{
318 gotoxy(x, y);
319 cclear(length);
320}
321/*-----------------------------------------------------------------------------------*/
322void CC_FASTCALL
323chlinexy(unsigned char x, unsigned char y, unsigned char length)
324{
325 gotoxy(x, y);
326 chline(length);
327}
328/*-----------------------------------------------------------------------------------*/
329void CC_FASTCALL
330cvlinexy(unsigned char x, unsigned char y, unsigned char length)
331{
332 gotoxy(x, y);
333 cvline(length);
334}
335/*-----------------------------------------------------------------------------------*/
336void CC_FASTCALL
337_cputsxy(unsigned char x, unsigned char y, char *str)
338{
339 gotoxy(x, y);
340 _cputs(str);
341}
342/*-----------------------------------------------------------------------------------*/
343void CC_FASTCALL
344cputcxy(unsigned char x, unsigned char y, char c)
345{
346 gotoxy(x, y);
347 cputc(c);
348}
349/*-----------------------------------------------------------------------------------*/
350void CC_FASTCALL
351screensize(unsigned char *x, unsigned char *y)
352{
353 *x = SCREEN_WIDTH;
354 *y = SCREEN_HEIGHT;
355}
356/*-----------------------------------------------------------------------------------*/
357static unsigned char sizex, sizey;
358/*-----------------------------------------------------------------------------------*/
359static void
360_cputsn(char *str, unsigned char len)
361{
362 /* char c;
363
364 while(len > 0) {
365 --len;
366 c = *str;
367 if(c == 0) {
368 break;
369 }
370 cputc(c);
371 ++str;
372 }*/
373 ctk_80col_cputsn(str, len);
374}
375/*-----------------------------------------------------------------------------------*/
376static void
377s_ctk_draw_init(void)
378{
379 screensize(&sizex, &sizey);
380 ctk_draw_clear(0, sizey);
381}
382/*-----------------------------------------------------------------------------------*/
383static void
384draw_widget(struct ctk_widget *w,
385 unsigned char x, unsigned char y,
386 unsigned char clipx,
387 unsigned char clipy,
388 unsigned char clipy1, unsigned char clipy2,
389 unsigned char focus)
390{
391 unsigned char xpos, ypos, xscroll;
392 unsigned char i, j;
393 char c, *text;
394 unsigned char len, wfocus;
395
396 wfocus = 0;
397 if(focus & CTK_FOCUS_WINDOW) {
398 if(focus & CTK_FOCUS_WIDGET) {
399 wfocus = 1;
400 }
401 } else if(focus & CTK_FOCUS_DIALOG) {
402 if(focus & CTK_FOCUS_WIDGET) {
403 wfocus = 1;
404 }
405 } else {
406 }
407
408 xpos = x + w->x;
409 ypos = y + w->y;
410
411 switch(w->type) {
412 case CTK_WIDGET_SEPARATOR:
413 if(ypos >= clipy1 && ypos < clipy2) {
414 chlinexy(xpos, ypos, w->w);
415 }
416 break;
417 case CTK_WIDGET_LABEL:
418 text = w->widget.label.text;
419 for(i = 0; i < w->h; ++i) {
420 if(ypos >= clipy1 && ypos < clipy2) {
421 gotoxy(xpos, ypos);
422 _cputsn(text, w->w);
423 if(w->w - (wherex() - xpos) > 0) {
424 cclear(w->w - (wherex() - xpos));
425 }
426 }
427 ++ypos;
428 text += w->w;
429 }
430 break;
431 case CTK_WIDGET_BUTTON:
432 if(ypos >= clipy1 && ypos < clipy2) {
433 if(wfocus != 0) {
434 revers(1);
435 } else {
436 revers(0);
437 }
438 cputcxy(xpos, ypos, '[');
439 _cputsn(w->widget.button.text, w->w);
440 cputc(']');
441 revers(0);
442 }
443 break;
444 case CTK_WIDGET_HYPERLINK:
445 if(ypos >= clipy1 && ypos < clipy2) {
446 if(wfocus != 0) {
447 revers(0);
448 } else {
449 revers(1);
450 }
451 gotoxy(xpos, ypos);
452 _cputsn(w->widget.button.text, w->w);
453 revers(0);
454 }
455 break;
456 case CTK_WIDGET_TEXTENTRY:
457 text = w->widget.textentry.text;
458 if(wfocus != 0) {
459 revers(1);
460 } else {
461 revers(0);
462 }
463 xscroll = 0;
464 if(w->widget.textentry.xpos >= w->w - 1) {
465 xscroll = w->widget.textentry.xpos - w->w + 1;
466 }
467 for(j = 0; j < w->h; ++j) {
468 if(ypos >= clipy1 && ypos < clipy2) {
469 if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT &&
470 w->widget.textentry.ypos == j) {
471 revers(0);
472 cputcxy(xpos, ypos, '>');
473 for(i = 0; i < w->w; ++i) {
474 c = text[i + xscroll];
475 if(i == w->widget.textentry.xpos - xscroll) {
476 revers(1);
477 } else {
478 revers(0);
479 }
480 if(c == 0) {
481 cputc(' ');
482 } else {
483 cputc(c);
484 }
485 revers(0);
486 }
487 cputc('<');
488 } else {
489 cvlinexy(xpos, ypos, 1);
490 gotoxy(xpos + 1, ypos);
491 _cputsn(text, w->w);
492 i = wherex();
493 if(i - xpos - 1 < w->w) {
494 cclear(w->w - (i - xpos) + 1);
495 }
496 cvline(1);
497 }
498 }
499 ++ypos;
500 text += w->w;
501 }
502 revers(0);
503 break;
504 case CTK_WIDGET_ICON:
505 if(ypos >= clipy1 && ypos < clipy2) {
506 if(focus & 1) {
507 revers(1);
508 } else {
509 revers(0);
510 }
511 gotoxy(xpos, ypos);
512 if(w->widget.icon.textmap != NULL) {
513 ctk_80col_bitmapptr = w->widget.icon.bitmap;
514 for(i = 0; i < 3; ++i) {
515 gotoxy(xpos, ypos);
516 if(ypos >= clipy1 && ypos < clipy2) {
517 /* cputc(w->widget.icon.textmap[0 + 3 * i]);
518 cputc(w->widget.icon.textmap[1 + 3 * i]);
519 cputc(w->widget.icon.textmap[2 + 3 * i]);*/
520 gotoxy(xpos-3, ypos);
521 ctk_80col_draw_bitmapline(3);
522 }
523 ctk_80col_bitmapptr += 3 * 8;
524 ++ypos;
525 }
526 }
527 x = xpos;
528
529 len = strlen(w->widget.icon.title);
530 if(x + len >= sizex) {
531 x = sizex - len;
532 }
533
534 gotoxy(x, ypos);
535 if(ypos >= clipy1 && ypos < clipy2) {
536 _cputs(w->widget.icon.title);
537 }
538 revers(0);
539 }
540 break;
541
542 default:
543 break;
544 }
545}
546/*-----------------------------------------------------------------------------------*/
547static void
548s_ctk_draw_widget(struct ctk_widget *w,
549 unsigned char focus,
550 unsigned char clipy1,
551 unsigned char clipy2)
552{
553 struct ctk_window *win = w->window;
554 unsigned char posx, posy;
555
556 posx = win->x + 1;
557 posy = win->y + 2;
558
559 if(w == win->focused) {
560 focus |= CTK_FOCUS_WIDGET;
561 }
562
563 draw_widget(w, posx, posy,
564 posx + win->w,
565 posy + win->h,
566 clipy1, clipy2,
567 focus);
568
569#ifdef CTK_CONIO_CONF_UPDATE
570 CTK_CONIO_CONF_UPDATE();
571#endif /* CTK_CONIO_CONF_UPDATE */
572}
573/*-----------------------------------------------------------------------------------*/
574static void
575s_ctk_draw_clear_window(struct ctk_window *window,
576 unsigned char focus,
577 unsigned char clipy1,
578 unsigned char clipy2)
579{
580 unsigned char i;
581 unsigned char h;
582
583 if(focus & CTK_FOCUS_WINDOW) {
584 } else {
585 }
586
587 h = window->y + 2 + window->h;
588 /* Clear window contents. */
589 for(i = window->y + 2; i < h; ++i) {
590 if(i >= clipy1 && i < clipy2) {
591 cclearxy(window->x + 1, i, window->w);
592 }
593 }
594}
595/*-----------------------------------------------------------------------------------*/
596static void
597draw_window_contents(struct ctk_window *window, unsigned char focus,
598 unsigned char clipy1, unsigned char clipy2,
599 unsigned char x1, unsigned char x2,
600 unsigned char y1, unsigned char y2)
601{
602 struct ctk_widget *w;
603 unsigned char wfocus;
604
605 /* Draw inactive widgets. */
606 for(w = window->inactive; w != NULL; w = w->next) {
607 draw_widget(w, x1, y1, x2, y2,
608 clipy1, clipy2,
609 focus);
610 }
611
612 /* Draw active widgets. */
613 for(w = window->active; w != NULL; w = w->next) {
614 wfocus = focus;
615 if(w == window->focused) {
616 wfocus |= CTK_FOCUS_WIDGET;
617 }
618
619 draw_widget(w, x1, y1, x2, y2,
620 clipy1, clipy2,
621 wfocus);
622 }
623
624#ifdef CTK_CONIO_CONF_UPDATE
625 CTK_CONIO_CONF_UPDATE();
626#endif /* CTK_CONIO_CONF_UPDATE */
627
628}
629/*-----------------------------------------------------------------------------------*/
630static void
631s_ctk_draw_window(struct ctk_window *window, unsigned char focus,
632 unsigned char clipy1, unsigned char clipy2)
633{
634 unsigned char x, y;
635 unsigned char h;
636 unsigned char x1, y1, x2, y2;
637
638 if(window->y + 1 >= clipy2) {
639 return;
640 }
641
642 x = window->x;
643 y = window->y + 1;
644
645 if(focus & CTK_FOCUS_WINDOW) {
646 } else {
647 }
648
649 x1 = x + 1;
650 y1 = y + 1;
651 x2 = x1 + window->w;
652 y2 = y1 + window->h;
653
654 /* Draw window frame. */
655 if(y >= clipy1) {
656 cputcxy(x, y, CH_ULCORNER);
657 gotoxy(wherex() + window->titlelen + 2, wherey());
658 chline(window->w - (wherex() - x) - 2);
659 cputcxy(x2, y, CH_URCORNER);
660 }
661
662 h = window->h;
663
664 if(clipy1 > y1) {
665 if(clipy1 - y1 < h) {
666 h = clipy1 - y1;
667 y1 = clipy1;
668 } else {
669 h = 0;
670 }
671 }
672
673 if(clipy2 < y1 + h) {
674 if(y1 >= clipy2) {
675 h = 0;
676 } else {
677 h = clipy2 - y1;
678 }
679 }
680
681 cvlinexy(x, y1, h);
682 cvlinexy(x2, y1, h);
683
684 if(y + window->h >= clipy1 &&
685 y + window->h < clipy2) {
686 cputcxy(x, y2, CH_LLCORNER);
687 chlinexy(x1, y2, window->w);
688 cputcxy(x2, y2, CH_LRCORNER);
689 }
690
691 draw_window_contents(window, focus & CTK_FOCUS_WINDOW, clipy1, clipy2,
692 x1, x2, y + 1, y2);
693}
694/*-----------------------------------------------------------------------------------*/
695static void
696s_ctk_draw_dialog(struct ctk_window *dialog)
697{
698 unsigned char x, y;
699 unsigned char i;
700 unsigned char x1, y1, x2, y2;
701
702
703 x = dialog->x;
704 y = dialog->y + 1;
705
706
707 x1 = x + 1;
708 y1 = y + 1;
709 x2 = x1 + dialog->w;
710 y2 = y1 + dialog->h;
711
712
713 /* Draw dialog frame. */
714
715 cvlinexy(x, y1,
716 dialog->h);
717 cvlinexy(x2, y1,
718 dialog->h);
719
720 chlinexy(x1, y,
721 dialog->w);
722 chlinexy(x1, y2,
723 dialog->w);
724
725 cputcxy(x, y, CH_ULCORNER);
726 cputcxy(x, y2, CH_LLCORNER);
727 cputcxy(x2, y, CH_URCORNER);
728 cputcxy(x2, y2, CH_LRCORNER);
729
730
731 /* Clear dialog contents. */
732 for(i = y1; i < y2; ++i) {
733 cclearxy(x1, i, dialog->w);
734 }
735
736 draw_window_contents(dialog, CTK_FOCUS_DIALOG, 0, sizey,
737 x1, x2, y1, y2);
738}
739/*-----------------------------------------------------------------------------------*/
740static void
741s_ctk_draw_clear(unsigned char y1, unsigned char y2)
742{
743 unsigned char i;
744
745 for(i = y1; i < y2; ++i) {
746
747 ctk_80col_clear_line(i);
748 }
749}
750/*-----------------------------------------------------------------------------------*/
751static void
752draw_menu(struct ctk_menu *m)
753{
754 unsigned char x, x2, y;
755 revers(0);
756 x = wherex();
757 _cputs(m->title);
758 cputc(' ');
759 x2 = wherex();
760 if(x + CTK_CONF_MENUWIDTH > sizex) {
761 x = sizex - CTK_CONF_MENUWIDTH;
762 }
763
764
765 for(y = 0; y < m->nitems; ++y) {
766 if(y == m->active) {
767 revers(0);
768 } else {
769 revers(1);
770 }
771 gotoxy(x, y + 1);
772 if(m->items[y].title[0] == '-') {
773 chline(CTK_CONF_MENUWIDTH);
774 } else {
775 _cputs(m->items[y].title);
776 }
777 if(x + CTK_CONF_MENUWIDTH > wherex()) {
778 cclear(x + CTK_CONF_MENUWIDTH - wherex());
779 }
780
781 }
782 gotoxy(x2, 0);
783 revers(1);
784}
785/*-----------------------------------------------------------------------------------*/
786static void
787s_ctk_draw_menus(struct ctk_menus *menus)
788{
789 struct ctk_menu *m;
790
791 /* Draw menus */
792 gotoxy(0, 0);
793 revers(1);
794 cputc(' ');
795 for(m = menus->menus->next; m != NULL; m = m->next) {
796 if(m != menus->open) {
797 _cputs(m->title);
798 cputc(' ');
799 } else {
800 draw_menu(m);
801 }
802 }
803
804
805 if(wherex() + strlen(menus->desktopmenu->title) + 1>= sizex) {
806 gotoxy(sizex - strlen(menus->desktopmenu->title) - 1, 0);
807 } else {
808 cclear(sizex - wherex() -
809 strlen(menus->desktopmenu->title) - 1);
810 }
811
812 /* Draw desktopmenu */
813 if(menus->desktopmenu != menus->open) {
814 _cputs(menus->desktopmenu->title);
815 cputc(' ');
816 } else {
817 draw_menu(menus->desktopmenu);
818 }
819
820 revers(0);
821}
822/*-----------------------------------------------------------------------------------*/
823static unsigned char
824s_ctk_draw_height(void)
825{
826 return sizey;
827}
828/*-----------------------------------------------------------------------------------*/
829static unsigned char
830s_ctk_draw_width(void)
831{
832 return sizex;
833}
834/*-----------------------------------------------------------------------------------*/
835static unsigned short
836s_ctk_mouse_xtoc(unsigned short x)
837{
838 return x / 4;
839}
840/*-----------------------------------------------------------------------------------*/
841static unsigned short
842s_ctk_mouse_ytoc(unsigned short y)
843{
844 return y / 8;
845}
846/*-----------------------------------------------------------------------------------*/
847static const struct ctk_draw_service_interface interface =
848 {CTK_DRAW_SERVICE_VERSION,
849 1,
850 1,
851 1,
852 s_ctk_draw_init,
853 s_ctk_draw_clear,
854 s_ctk_draw_clear_window,
855 s_ctk_draw_window,
856 s_ctk_draw_dialog,
857 s_ctk_draw_widget,
858 s_ctk_draw_menus,
859 s_ctk_draw_width,
860 s_ctk_draw_height,
861 s_ctk_mouse_xtoc,
862 s_ctk_mouse_ytoc,
863 };
864
865EK_EVENTHANDLER(eventhandler, ev, data);
866EK_PROCESS(proc, CTK_DRAW_SERVICE_NAME ": 80col", EK_PRIO_NORMAL,
867 eventhandler, NULL, (void *)&interface);
868
869/*--------------------------------------------------------------------------*/
870LOADER_INIT_FUNC(ctk_80col_service_init, arg)
871{
872 ek_service_start(CTK_DRAW_SERVICE_NAME, &proc);
873}
874/*--------------------------------------------------------------------------*/
875EK_EVENTHANDLER(eventhandler, ev, data)
876{
877 EK_EVENTHANDLER_ARGS(ev, data);
878
879 switch(ev) {
880 case EK_EVENT_INIT:
881 case EK_EVENT_REPLACE:
882 ctk_80col_init();
883 ctk_restore();
884 break;
885 case EK_EVENT_REQUEST_REPLACE:
886 ek_replace((struct ek_proc *)data, NULL);
887 LOADER_UNLOAD();
888 break;
889 }
890}
891/*--------------------------------------------------------------------------*/