1 #include <stdlib.h>
2 #include "xglk.h"
3 #include "xg_internal.h"
4 #include "xg_win_textbuf.h"
5 #include "xg_win_textgrid.h"
6 #include "xg_win_graphics.h"
7
8 window_t *gli_rootwin = NULL;
9 window_t *gli_focuswin = NULL;
10
11 static window_t *gli_windowlist = NULL;
12
13 /* Window type data structures */
14
15 typedef struct window_blank_struct {
16 window_t *owner;
17 XRectangle bbox;
18 } window_blank_t;
19
20 typedef struct window_pair_struct {
21 window_t *child1, *child2;
22 /* split info... */
23 glui32 dir;
24 int vertical, backward;
25 glui32 division;
26 window_t *key; /* NULL or a leaf-descendant (not a Pair) */
27 int keydamage;
28 glui32 size;
29
30 window_t *owner;
31 XRectangle bbox;
32 int flat; /* true if there's nothing to draw */
33 int splithgt; /* The split center. Will be >= N, < width-N.
34 Unless bbox is too small. */
35
36 } window_pair_t;
37
38 static window_t *gli_new_window(glui32 type, glui32 rock);
39 static void gli_delete_window(window_t *win);
40
41 static window_blank_t *win_blank_create(window_t *win);
42 static void win_blank_destroy(window_blank_t *dwin);
43 static void win_blank_rearrange(window_t *win, XRectangle *box);
44 static void win_blank_redraw(window_t *win);
45
46 static window_pair_t *win_pair_create(window_t *win, glui32 method,
47 window_t *key, glui32 size);
48 static void win_pair_destroy(window_pair_t *dwin);
49 static void win_pair_rearrange(window_t *win, XRectangle *box);
50 static void win_pair_redraw(window_t *win);
51
init_gli_windows()52 int init_gli_windows()
53 {
54 gli_windowlist = NULL;
55
56 gli_focuswin = NULL;
57 gli_rootwin = NULL;
58
59 return TRUE;
60 }
61
gli_delete_window(window_t * win)62 static void gli_delete_window(window_t *win)
63 {
64 window_t *prev, *next;
65
66 if (gli_unregister_obj)
67 (*gli_unregister_obj)(win, gidisp_Class_Window, win->disprock);
68
69 if (win->str) {
70 gli_stream_close(win->str);
71 win->str = NULL;
72 }
73
74 win->type = -1;
75 win->parent = NULL;
76 win->data = NULL;
77
78 prev = win->chain_prev;
79 next = win->chain_next;
80 win->chain_prev = NULL;
81 win->chain_next = NULL;
82
83 if (prev)
84 prev->chain_next = next;
85 else
86 gli_windowlist = next;
87 if (next)
88 next->chain_prev = prev;
89
90 free(win);
91 }
92
gli_new_window(glui32 type,glui32 rock)93 static window_t *gli_new_window(glui32 type, glui32 rock)
94 {
95 window_t *win = (window_t *)malloc(sizeof(window_t));
96
97 if (!win)
98 return NULL;
99
100 win->type = type;
101
102 win->rock = rock;
103 win->parent = NULL; /* for now */
104 win->data = NULL; /* for now */
105 win->mouse_request = FALSE;
106 win->char_request = FALSE;
107 win->line_request = FALSE;
108 win->hyperlink_request = FALSE;
109 win->style = 0;
110 win->linkid = 0;
111
112 win->str = gli_stream_open_window(win);
113 win->echostr = NULL;
114
115 win->chain_prev = NULL;
116 win->chain_next = gli_windowlist;
117 gli_windowlist = win;
118 if (win->chain_next) {
119 win->chain_next->chain_prev = win;
120 }
121
122 if (gli_register_obj)
123 win->disprock = (*gli_register_obj)(win, gidisp_Class_Window);
124 else
125 win->disprock.ptr = NULL;
126
127 return win;
128 }
129
gli_window_fixiterate(window_t * win)130 window_t *gli_window_fixiterate(window_t *win)
131 {
132 if (!win)
133 return gli_rootwin;
134
135 if (win->type == wintype_Pair) {
136 window_pair_t *dwin = win->data;
137 if (!dwin->backward)
138 return dwin->child1;
139 else
140 return dwin->child2;
141 }
142 else {
143 window_t *parwin;
144 window_pair_t *dwin;
145
146 while (win->parent) {
147 parwin = win->parent;
148 dwin = parwin->data;
149 if (!dwin->backward) {
150 if (win == dwin->child1)
151 return dwin->child2;
152 }
153 else {
154 if (win == dwin->child2)
155 return dwin->child1;
156 }
157 win = parwin;
158 }
159
160 return NULL;
161 }
162 }
163
glk_window_iterate(window_t * win,glui32 * rock)164 window_t *glk_window_iterate(window_t *win, glui32 *rock)
165 {
166 if (!win) {
167 win = gli_windowlist;
168 }
169 else {
170 win = win->chain_next;
171 }
172
173 if (win) {
174 if (rock)
175 *rock = win->rock;
176 return win;
177 }
178
179 if (rock)
180 *rock = 0;
181 return NULL;
182 }
183
glk_window_get_root()184 winid_t glk_window_get_root()
185 {
186 if (!gli_rootwin)
187 return 0;
188 return gli_rootwin;
189 }
190
glk_window_get_rock(window_t * win)191 glui32 glk_window_get_rock(window_t *win)
192 {
193 if (!win) {
194 gli_strict_warning("window_get_rock: invalid ref");
195 return 0;
196 }
197 return win->rock;
198 }
199
glk_window_get_type(window_t * win)200 glui32 glk_window_get_type(window_t *win)
201 {
202 if (!win) {
203 gli_strict_warning("window_get_type: invalid ref");
204 return 0;
205 }
206 return win->type;
207 }
208
glk_window_get_parent(window_t * win)209 winid_t glk_window_get_parent(window_t *win)
210 {
211 if (!win) {
212 gli_strict_warning("window_get_parent: invalid ref");
213 return 0;
214 }
215 if (win->parent)
216 return win->parent;
217 else
218 return 0;
219 }
220
glk_window_get_sibling(window_t * win)221 winid_t glk_window_get_sibling(window_t *win)
222 {
223 window_pair_t *dpairwin;
224 if (!win) {
225 gli_strict_warning("window_get_sibling: invalid ref");
226 return NULL;
227 }
228 if (!win->parent)
229 return NULL;
230 dpairwin = win->parent->data;
231 if (dpairwin->child1 == win)
232 return dpairwin->child2;
233 else if (dpairwin->child2 == win)
234 return dpairwin->child1;
235 else {
236 gli_strict_warning("window_get_sibling: damaged window tree");
237 return NULL;
238 }
239 }
240
glk_window_get_size(window_t * win,glui32 * width,glui32 * height)241 void glk_window_get_size(window_t *win, glui32 *width, glui32 *height)
242 {
243 glui32 wid = 0;
244 glui32 hgt = 0;
245
246 if (!win) {
247 gli_strict_warning("window_get_size: invalid ref");
248 return;
249 }
250
251 switch (win->type) {
252 case wintype_Blank:
253 case wintype_Pair:
254 /* always zero */
255 break;
256 case wintype_TextGrid:
257 win_textgrid_get_size(win, &wid, &hgt);
258 break;
259 case wintype_TextBuffer:
260 win_textbuffer_get_size(win, &wid, &hgt);
261 break;
262 case wintype_Graphics:
263 win_graphics_get_size(win, &wid, &hgt);
264 break;
265 }
266
267 if (width)
268 *width = wid;
269 if (height)
270 *height = hgt;
271 }
272
glk_window_open(winid_t splitwin,glui32 method,glui32 size,glui32 wintype,glui32 rock)273 winid_t glk_window_open(winid_t splitwin, glui32 method, glui32 size,
274 glui32 wintype, glui32 rock)
275 {
276 window_t *newwin, *pairwin, *oldparent;
277 window_pair_t *dpairwin;
278 XRectangle box, *boxptr;
279 glui32 val;
280
281 if (!gli_rootwin) {
282 if (splitwin) {
283 gli_strict_warning("window_open: id must be 0");
284 return 0;
285 }
286 /* ignore method and size now */
287 oldparent = NULL;
288
289 box = matte_box;
290
291 box.x += (MATTE_WIDTH-1);
292 box.y += (MATTE_WIDTH-1);
293 box.width -= 2*(MATTE_WIDTH-1);
294 box.height -= 2*(MATTE_WIDTH-1);
295 }
296 else {
297
298 if (!splitwin) {
299 gli_strict_warning("window_open: invalid ref");
300 return 0;
301 }
302
303 val = (method & winmethod_DivisionMask);
304 if (val != winmethod_Fixed && val != winmethod_Proportional) {
305 gli_strict_warning(
306 "window_open: invalid method (not fixed or proportional)");
307 return 0;
308 }
309
310 val = (method & winmethod_DirMask);
311 if (val != winmethod_Above && val != winmethod_Below
312 && val != winmethod_Left && val != winmethod_Right) {
313 gli_strict_warning("window_open: invalid method (bad direction)");
314 return 0;
315 }
316
317 boxptr = gli_window_get_rect(splitwin);
318 if (!boxptr) {
319 gli_strict_warning("window_open: can't get window rect");
320 return 0;
321 }
322 box = *boxptr;
323
324 oldparent = splitwin->parent;
325 if (oldparent && oldparent->type != wintype_Pair) {
326 gli_strict_warning("window_open: parent window is not Pair");
327 return 0;
328 }
329
330 }
331
332 newwin = gli_new_window(wintype, rock);
333 if (!newwin) {
334 gli_strict_warning("window_open: unable to create window");
335 return 0;
336 }
337 switch (wintype) {
338 case wintype_Blank:
339 newwin->data = win_blank_create(newwin);
340 break;
341 case wintype_TextGrid:
342 newwin->data = win_textgrid_create(newwin);
343 break;
344 case wintype_TextBuffer:
345 newwin->data = win_textbuffer_create(newwin);
346 break;
347 case wintype_Graphics:
348 newwin->data = win_graphics_create(newwin);
349 break;
350 case wintype_Pair:
351 gli_strict_warning("window_open: cannot open pair window directly");
352 gli_delete_window(newwin);
353 return 0;
354 default:
355 /* Unknown window type -- do not print a warning, just return 0
356 to indicate that it's not possible. */
357 gli_delete_window(newwin);
358 return 0;
359 }
360
361 if (!newwin->data) {
362 gli_strict_warning("window_open: unable to create window");
363 return 0;
364 }
365
366 if (!splitwin) {
367 gli_rootwin = newwin;
368 gli_window_rearrange(newwin, &box);
369 }
370 else {
371 /* create pairwin, with newwin as the key */
372 pairwin = gli_new_window(wintype_Pair, 0);
373 dpairwin = win_pair_create(pairwin, method, newwin, size);
374 pairwin->data = dpairwin;
375
376 dpairwin->child1 = splitwin;
377 dpairwin->child2 = newwin;
378
379 splitwin->parent = pairwin;
380 newwin->parent = pairwin;
381 pairwin->parent = oldparent;
382
383 if (oldparent) {
384 window_pair_t *dparentwin = oldparent->data;
385 if (dparentwin->child1 == splitwin)
386 dparentwin->child1 = pairwin;
387 else
388 dparentwin->child2 = pairwin;
389 }
390 else {
391 gli_rootwin = pairwin;
392 }
393
394 gli_window_rearrange(pairwin, &box);
395 }
396
397 /* We don't send an event, because we're not in a select(). The user has
398 to know what to redraw. */
399
400 /* Redraw the box area. */
401 box.x -= (MATTE_WIDTH-1);
402 box.y -= (MATTE_WIDTH-1);
403 box.width += 2*(MATTE_WIDTH-1);
404 box.height += 2*(MATTE_WIDTH-1);
405 xglk_invalidate(&box);
406
407 return newwin;
408 }
409
glk_window_get_arrangement(window_t * win,glui32 * method,glui32 * size,winid_t * keywin_id)410 void glk_window_get_arrangement(window_t *win, glui32 *method, glui32 *size,
411 winid_t *keywin_id)
412 {
413 window_pair_t *dwin;
414 glui32 val;
415
416 if (!win) {
417 gli_strict_warning("window_get_arrangement: invalid ref");
418 return;
419 }
420
421 if (win->type != wintype_Pair) {
422 gli_strict_warning("window_get_arrangement: not a Pair window");
423 return;
424 }
425
426 dwin = win->data;
427
428 val = dwin->dir | dwin->division;
429
430 if (size)
431 *size = dwin->size;
432 if (keywin_id) {
433 if (dwin->key)
434 *keywin_id = dwin->key;
435 else
436 *keywin_id = 0;
437 }
438 if (method)
439 *method = val;
440 }
441
glk_window_set_arrangement(window_t * win,glui32 method,glui32 size,winid_t key)442 void glk_window_set_arrangement(window_t *win, glui32 method, glui32 size, winid_t key)
443 {
444 window_pair_t *dwin;
445 glui32 newdir;
446 XRectangle box;
447 int newvertical, newbackward;
448
449 if (!win) {
450 gli_strict_warning("window_set_arrangement: invalid ref");
451 return;
452 }
453
454 if (win->type != wintype_Pair) {
455 gli_strict_warning("window_set_arrangement: not a Pair window");
456 return;
457 }
458
459 if (key) {
460 window_t *wx;
461 if (key->type == wintype_Pair) {
462 gli_strict_warning("window_set_arrangement: keywin cannot be a Pair");
463 return;
464 }
465 for (wx=key; wx; wx=wx->parent) {
466 if (wx == win)
467 break;
468 }
469 if (wx == NULL) {
470 gli_strict_warning("window_set_arrangement: keywin must be a descendant");
471 return;
472 }
473 }
474
475 dwin = win->data;
476 box = dwin->bbox;
477
478 newdir = method & winmethod_DirMask;
479 newvertical = (newdir == winmethod_Left || newdir == winmethod_Right);
480 newbackward = (newdir == winmethod_Left || newdir == winmethod_Above);
481 if (!key)
482 key = dwin->key;
483
484 if ((newvertical && !dwin->vertical) || (!newvertical && dwin->vertical)) {
485 if (!dwin->vertical)
486 gli_strict_warning("window_set_arrangement: split must stay horizontal");
487 else
488 gli_strict_warning("window_set_arrangement: split must stay vertical");
489 return;
490 }
491
492 if (key && key->type == wintype_Blank
493 && (method & winmethod_DivisionMask) == winmethod_Fixed) {
494 gli_strict_warning("window_set_arrangement: a Blank window cannot have a fixed size");
495 return;
496 }
497
498 if ((newbackward && !dwin->backward) || (!newbackward && dwin->backward)) {
499 /* switch the children */
500 window_t *tmpwin = dwin->child1;
501 dwin->child1 = dwin->child2;
502 dwin->child2 = tmpwin;
503 }
504
505 /* set up everything else */
506 dwin->dir = newdir;
507 dwin->division = method & winmethod_DivisionMask;
508 dwin->key = key;
509 dwin->size = size;
510
511 dwin->vertical = (dwin->dir == winmethod_Left || dwin->dir == winmethod_Right);
512 dwin->backward = (dwin->dir == winmethod_Left || dwin->dir == winmethod_Above);
513
514 gli_window_rearrange(win, &box);
515
516 /* We don't send an event, because we're not in a select().
517 The user has to know what to redraw. */
518 box.x -= (MATTE_WIDTH-1);
519 box.y -= (MATTE_WIDTH-1);
520 box.width += 2*(MATTE_WIDTH-1);
521 box.height += 2*(MATTE_WIDTH-1);
522 xglk_invalidate(&box);
523 }
524
gli_window_close(window_t * win,int recurse)525 static void gli_window_close(window_t *win, int recurse)
526 {
527 window_t *wx;
528
529 if (gli_focuswin == win) {
530 /* gli_set_focus(NULL); */ /* We skip this, because it only does drawing,
531 and the whole area will be redrawn anyway. */
532 gli_focuswin = NULL;
533 }
534
535 for (wx=win->parent; wx; wx=wx->parent) {
536 if (wx->type == wintype_Pair) {
537 window_pair_t *dwx = wx->data;
538 if (dwx->key == win) {
539 dwx->key = NULL;
540 dwx->keydamage = TRUE;
541 }
542 }
543 }
544
545 switch (win->type) {
546 case wintype_Blank: {
547 window_blank_t *dwin = win->data;
548 win_blank_destroy(dwin);
549 }
550 break;
551 case wintype_Pair: {
552 window_pair_t *dwin = win->data;
553 if (recurse) {
554 if (dwin->child1)
555 gli_window_close(dwin->child1, TRUE);
556 if (dwin->child2)
557 gli_window_close(dwin->child2, TRUE);
558 }
559 win_pair_destroy(dwin);
560 }
561 break;
562 case wintype_TextBuffer: {
563 window_textbuffer_t *dwin = win->data;
564 win_textbuffer_destroy(dwin);
565 }
566 break;
567 case wintype_TextGrid: {
568 window_textgrid_t *dwin = win->data;
569 win_textgrid_destroy(dwin);
570 }
571 break;
572 case wintype_Graphics: {
573 window_graphics_t *dwin = win->data;
574 win_graphics_destroy(dwin);
575 }
576 break;
577 }
578
579 gli_delete_window(win);
580 }
581
glk_window_close(window_t * win,stream_result_t * result)582 void glk_window_close(window_t *win, stream_result_t *result)
583 {
584 XRectangle box, *boxptr;
585
586 if (!win) {
587 gli_strict_warning("window_close: invalid ref");
588 return;
589 }
590
591 if (win == gli_rootwin || win->parent == NULL) {
592 /* close the root window, which means all windows. */
593
594 gli_rootwin = 0;
595
596 /* begin (simpler) closation */
597
598 boxptr = gli_window_get_rect(win);
599 if (!boxptr) {
600 gli_strict_warning("window_close: can't get window rect");
601 return;
602 }
603 box = *boxptr;
604
605 gli_stream_fill_result(win->str, result);
606 gli_window_close(win, TRUE);
607
608 box.x -= (MATTE_WIDTH-1);
609 box.y -= (MATTE_WIDTH-1);
610 box.width += 2*(MATTE_WIDTH-1);
611 box.height += 2*(MATTE_WIDTH-1);
612 xglk_invalidate(&box);
613 }
614 else {
615 /* have to jigger parent */
616 window_t *pairwin, *sibwin, *grandparwin, *wx;
617 window_pair_t *dpairwin, *dgrandparwin, *dwx;
618 int keydamage_flag;
619
620 pairwin = win->parent;
621 dpairwin = pairwin->data;
622 if (win == dpairwin->child1) {
623 sibwin = dpairwin->child2;
624 }
625 else if (win == dpairwin->child2) {
626 sibwin = dpairwin->child1;
627 }
628 else {
629 gli_strict_warning("window_close: window tree is corrupted");
630 return;
631 }
632
633 boxptr = gli_window_get_rect(pairwin);
634 if (!boxptr) {
635 gli_strict_warning("window_close: can't get window rect");
636 return;
637 }
638 box = *boxptr;
639
640 grandparwin = pairwin->parent;
641 if (!grandparwin) {
642 gli_rootwin = sibwin;
643 sibwin->parent = NULL;
644 }
645 else {
646 dgrandparwin = grandparwin->data;
647 if (dgrandparwin->child1 == pairwin)
648 dgrandparwin->child1 = sibwin;
649 else
650 dgrandparwin->child2 = sibwin;
651 sibwin->parent = grandparwin;
652 }
653
654 /* Begin closation */
655
656 gli_stream_fill_result(win->str, result);
657
658 /* Close the child window (and descendants), so that key-deletion can
659 crawl up the tree to the root window. */
660 gli_window_close(win, TRUE);
661
662 /* This probably isn't necessary, but the child *is* gone, so just in case. */
663 if (win == dpairwin->child1) {
664 dpairwin->child1 = NULL;
665 }
666 else if (win == dpairwin->child2) {
667 dpairwin->child2 = NULL;
668 }
669
670 /* Now we can delete the parent pair. */
671 gli_window_close(pairwin, FALSE);
672
673 keydamage_flag = FALSE;
674 for (wx=sibwin; wx; wx=wx->parent) {
675 if (wx->type == wintype_Pair) {
676 window_pair_t *dwx = wx->data;
677 if (dwx->keydamage) {
678 keydamage_flag = TRUE;
679 dwx->keydamage = FALSE;
680 }
681 }
682 }
683
684 if (keydamage_flag) {
685 box = matte_box;
686
687 box.x += (MATTE_WIDTH-1);
688 box.y += (MATTE_WIDTH-1);
689 box.width -= 2*(MATTE_WIDTH-1);
690 box.height -= 2*(MATTE_WIDTH-1);
691
692 gli_window_rearrange(gli_rootwin, &box);
693
694 xglk_invalidate(&matte_box);
695 }
696 else {
697 gli_window_rearrange(sibwin, &box);
698
699 /* We don't send an event, because we're not in a select(). The user
700 has to know what to redraw. */
701
702 box.x -= (MATTE_WIDTH-1);
703 box.y -= (MATTE_WIDTH-1);
704 box.width += 2*(MATTE_WIDTH-1);
705 box.height += 2*(MATTE_WIDTH-1);
706 xglk_invalidate(&box);
707 }
708 }
709 }
710
711 /* The idea of the flush is that it happens before any entry to
712 glk_select(), which takes care of dirty data in valid regions.
713 It would be really cool if this clipped to the valid region,
714 and the exposure stuff clipped to invalid, but that's hard in X. */
gli_windows_flush()715 void gli_windows_flush()
716 {
717 int ix;
718 window_t *win;
719
720 for (win = gli_windowlist; win; win = win->chain_next) {
721 switch (win->type) {
722 case wintype_TextBuffer:
723 win_textbuffer_flush(win);
724 break;
725 case wintype_TextGrid:
726 win_textgrid_flush(win);
727 break;
728 case wintype_Graphics:
729 win_graphics_flush(win);
730 break;
731 }
732 }
733 }
734
glk_window_clear(window_t * win)735 void glk_window_clear(window_t *win)
736 {
737 if (!win) {
738 gli_strict_warning("window_clear: invalid ref");
739 return;
740 }
741
742 if (win->line_request) {
743 gli_strict_warning("window_clear: window has pending line request");
744 return;
745 }
746
747 switch (win->type) {
748 case wintype_TextBuffer:
749 win_textbuffer_clear_window(win->data);
750 break;
751 case wintype_TextGrid:
752 win_textgrid_clear_window(win->data);
753 break;
754 case wintype_Graphics:
755 win_graphics_erase_rect(win->data, TRUE, 0, 0, 0, 0);
756 break;
757 }
758 }
759
glk_window_move_cursor(window_t * win,glui32 xpos,glui32 ypos)760 void glk_window_move_cursor(window_t *win, glui32 xpos, glui32 ypos)
761 {
762 if (!win) {
763 gli_strict_warning("window_move_cursor: invalid ref");
764 return;
765 }
766
767 switch (win->type) {
768 case wintype_TextGrid:
769 win_textgrid_set_pos(win->data, xpos, ypos);
770 break;
771 default:
772 gli_strict_warning("window_move_cursor: not a TextGrid window");
773 break;
774 }
775 }
776
glk_window_get_stream(window_t * win)777 strid_t glk_window_get_stream(window_t *win)
778 {
779 if (!win) {
780 gli_strict_warning("window_get_stream: invalid ref");
781 return 0;
782 }
783
784 return win->str;
785 }
786
glk_window_get_echo_stream(window_t * win)787 strid_t glk_window_get_echo_stream(window_t *win)
788 {
789 if (!win) {
790 gli_strict_warning("window_get_echo_stream: invalid ref");
791 return 0;
792 }
793
794 if (win->echostr)
795 return win->echostr;
796 else
797 return 0;
798 }
799
glk_window_set_echo_stream(window_t * win,stream_t * str)800 void glk_window_set_echo_stream(window_t *win, stream_t *str)
801 {
802 if (!win) {
803 gli_strict_warning("window_set_echo_stream: invalid window id");
804 return;
805 }
806
807 win->echostr = str;
808 }
809
glk_set_window(window_t * win)810 void glk_set_window(window_t *win)
811 {
812 if (!win) {
813 glk_stream_set_current(NULL);
814 return;
815 }
816
817 glk_stream_set_current(win->str);
818 }
819
gli_window_get_fontset(window_t * win)820 fontset_t *gli_window_get_fontset(window_t *win)
821 {
822 switch (win->type) {
823 case wintype_TextBuffer:
824 return win_textbuffer_get_fontset(win);
825 break;
826 case wintype_TextGrid:
827 return win_textgrid_get_fontset(win);
828 break;
829 default:
830 return NULL;
831 }
832 }
833
gli_window_setfocus(window_t * win,int turnon)834 static void gli_window_setfocus(window_t *win, int turnon)
835 {
836 gli_draw_window_highlight(win, turnon);
837
838 switch (win->type) {
839 case wintype_TextBuffer:
840 win_textbuffer_setfocus(win, turnon);
841 break;
842 case wintype_TextGrid:
843 win_textgrid_setfocus(win, turnon);
844 break;
845 }
846 }
847
gli_set_focus(window_t * win)848 void gli_set_focus(window_t *win)
849 {
850 if (win == gli_focuswin)
851 return;
852
853 if (gli_focuswin) {
854 gli_window_setfocus(gli_focuswin, FALSE);
855 }
856
857 gli_focuswin = win;
858
859 if (gli_focuswin) {
860 gli_window_setfocus(gli_focuswin, TRUE);
861 }
862 }
863
gli_find_window_by_point(window_t * win,XPoint * pt)864 window_t *gli_find_window_by_point(window_t *win, XPoint *pt)
865 {
866 window_t *subwin;
867 window_pair_t *dwin;
868 int res;
869
870 if (!win)
871 return NULL;
872
873 if (win == gli_rootwin) {
874 if (pt->x < matte_box.x + (MATTE_WIDTH-1)
875 || pt->x >= matte_box.x+matte_box.width - (MATTE_WIDTH-1)
876 || pt->y < matte_box.y + (MATTE_WIDTH-1)
877 || pt->y >= matte_box.y+matte_box.height - (MATTE_WIDTH-1)) {
878 return NULL;
879 }
880 }
881
882 if (win->type != wintype_Pair)
883 return win;
884
885 dwin = win->data;
886 if (dwin->vertical) {
887 int val = dwin->bbox.x + dwin->splithgt;
888 if (pt->x >= val - (MATTE_WIDTH/2)
889 && pt->x < val - (MATTE_WIDTH/2) + MATTE_WIDTH) {
890 return win;
891 }
892 res = (pt->x >= val);
893 }
894 else {
895 int val = dwin->bbox.y + dwin->splithgt;
896 if (pt->y >= val - (MATTE_WIDTH/2)
897 && pt->y < val - (MATTE_WIDTH/2) + MATTE_WIDTH) {
898 return win;
899 }
900 res = (pt->y >= val);
901 }
902
903 if (dwin->backward)
904 res = !res;
905 if (res)
906 subwin = dwin->child2;
907 else
908 subwin = dwin->child1;
909 return gli_find_window_by_point(subwin, pt);
910 }
911
gli_window_rearrange(window_t * win,XRectangle * box)912 void gli_window_rearrange(window_t *win, XRectangle *box)
913 {
914 switch (win->type) {
915 case wintype_Blank:
916 win_blank_rearrange(win, box);
917 break;
918 case wintype_Pair:
919 win_pair_rearrange(win, box);
920 break;
921 case wintype_TextGrid:
922 win_textgrid_rearrange(win, box);
923 break;
924 case wintype_TextBuffer:
925 win_textbuffer_rearrange(win, box);
926 break;
927 case wintype_Graphics:
928 win_graphics_rearrange(win, box);
929 break;
930 }
931 }
932
gli_window_redraw(window_t * win)933 void gli_window_redraw(window_t *win)
934 {
935 switch (win->type) {
936 case wintype_Blank:
937 win_blank_redraw(win);
938 break;
939 case wintype_Pair:
940 win_pair_redraw(win);
941 break;
942 case wintype_TextGrid:
943 win_textgrid_redraw(win);
944 break;
945 case wintype_TextBuffer:
946 win_textbuffer_redraw(win);
947 break;
948 case wintype_Graphics:
949 win_graphics_redraw(win);
950 break;
951 }
952 }
953
gli_windows_set_paging(int forcetoend)954 void gli_windows_set_paging(int forcetoend)
955 {
956 window_t *win;
957
958 for (win=gli_window_fixiterate(NULL);
959 win;
960 win=gli_window_fixiterate(win)) {
961 switch (win->type) {
962 case wintype_TextBuffer:
963 win_textbuffer_set_paging(win->data, forcetoend);
964 break;
965 }
966 }
967 }
968
gli_windows_trim_buffers()969 void gli_windows_trim_buffers()
970 {
971 window_t *win;
972
973 for (win=gli_window_fixiterate(NULL);
974 win;
975 win=gli_window_fixiterate(win)) {
976 switch (win->type) {
977 case wintype_TextBuffer:
978 win_textbuffer_trim_buffer(win->data);
979 break;
980 }
981 }
982 }
983
gli_window_perform_click(window_t * win,int dir,XPoint * pt,int butnum,int clicknum,unsigned int state)984 void gli_window_perform_click(window_t *win, int dir, XPoint *pt, int butnum,
985 int clicknum, unsigned int state)
986 {
987 switch (win->type) {
988 case wintype_TextGrid:
989 win_textgrid_perform_click(win, dir, pt, butnum, clicknum, state);
990 break;
991 case wintype_TextBuffer:
992 win_textbuffer_perform_click(win, dir, pt, butnum, clicknum, state);
993 break;
994 case wintype_Graphics:
995 win_graphics_perform_click(win, dir, pt, butnum, clicknum, state);
996 break;
997 }
998 }
999
gli_window_get_rect(window_t * win)1000 XRectangle *gli_window_get_rect(window_t *win)
1001 {
1002 switch (win->type) {
1003 case wintype_Blank: {
1004 window_blank_t *dwin = win->data;
1005 return &dwin->bbox;
1006 }
1007 case wintype_Pair: {
1008 window_pair_t *dwin = win->data;
1009 return &dwin->bbox;
1010 }
1011 case wintype_TextGrid:
1012 return win_textgrid_get_rect(win);
1013 case wintype_TextBuffer:
1014 return win_textbuffer_get_rect(win);
1015 case wintype_Graphics:
1016 return win_graphics_get_rect(win);
1017 default:
1018 return NULL;
1019 }
1020 }
1021
glk_request_char_event(window_t * win)1022 void glk_request_char_event(window_t *win)
1023 {
1024 if (!win) {
1025 gli_strict_warning("request_char_event: invalid ref");
1026 return;
1027 }
1028
1029 if (win->char_request || win->line_request) {
1030 gli_strict_warning("request_char_event: window already has keyboard request");
1031 return;
1032 }
1033
1034 switch (win->type) {
1035 case wintype_TextBuffer:
1036 case wintype_TextGrid:
1037 win->char_request = TRUE;
1038 break;
1039 default:
1040 gli_strict_warning("request_char_event: window does not support keyboard input");
1041 break;
1042 }
1043
1044 }
1045
glk_cancel_char_event(window_t * win)1046 void glk_cancel_char_event(window_t *win)
1047 {
1048 if (!win) {
1049 gli_strict_warning("cancel_char_event: invalid ref");
1050 return;
1051 }
1052
1053 switch (win->type) {
1054 case wintype_TextBuffer:
1055 case wintype_TextGrid:
1056 win->char_request = FALSE;
1057 break;
1058 default:
1059 /* do nothing */
1060 break;
1061 }
1062 }
1063
glk_request_line_event(window_t * win,char * buf,glui32 maxlen,glui32 initlen)1064 void glk_request_line_event(window_t *win, char *buf, glui32 maxlen,
1065 glui32 initlen)
1066 {
1067 if (!win) {
1068 gli_strict_warning("request_line_event: invalid ref");
1069 return;
1070 }
1071
1072 if (win->char_request || win->line_request) {
1073 gli_strict_warning("request_line_event: window already has keyboard request");
1074 return;
1075 }
1076
1077 switch (win->type) {
1078 case wintype_TextBuffer:
1079 win->line_request = TRUE;
1080 win_textbuffer_init_line(win, buf, maxlen, initlen);
1081 break;
1082 case wintype_TextGrid:
1083 win->line_request = TRUE;
1084 win_textgrid_init_line(win, buf, maxlen, initlen);
1085 break;
1086 default:
1087 gli_strict_warning("request_line_event: window does not support keyboard input");
1088 break;
1089 }
1090
1091 }
1092
glk_cancel_line_event(window_t * win,event_t * ev)1093 void glk_cancel_line_event(window_t *win, event_t *ev)
1094 {
1095 event_t dummyev;
1096
1097 if (!ev) {
1098 ev = &dummyev;
1099 }
1100
1101 gli_event_clearevent(ev);
1102
1103 if (!win) {
1104 gli_strict_warning("cancel_line_event: invalid ref");
1105 return;
1106 }
1107
1108 switch (win->type) {
1109 case wintype_TextBuffer:
1110 if (win->line_request) {
1111 win_textbuffer_cancel_line(win, ev);
1112 }
1113 break;
1114 case wintype_TextGrid:
1115 if (win->line_request) {
1116 win_textgrid_cancel_line(win, ev);
1117 }
1118 break;
1119 default:
1120 /* do nothing */
1121 break;
1122 }
1123 }
1124
glk_request_mouse_event(window_t * win)1125 void glk_request_mouse_event(window_t *win)
1126 {
1127 if (!win) {
1128 gli_strict_warning("request_mouse_event: invalid ref");
1129 return;
1130 }
1131
1132 switch (win->type) {
1133 case wintype_Graphics:
1134 case wintype_TextGrid:
1135 win->mouse_request = TRUE;
1136 break;
1137 default:
1138 /* do nothing */
1139 break;
1140 }
1141
1142 return;
1143 }
1144
glk_cancel_mouse_event(window_t * win)1145 void glk_cancel_mouse_event(window_t *win)
1146 {
1147 if (!win) {
1148 gli_strict_warning("cancel_mouse_event: invalid ref");
1149 return;
1150 }
1151
1152 switch (win->type) {
1153 case wintype_Graphics:
1154 case wintype_TextGrid:
1155 win->mouse_request = FALSE;
1156 break;
1157 default:
1158 /* do nothing */
1159 break;
1160 }
1161
1162 return;
1163 }
1164
glk_request_hyperlink_event(window_t * win)1165 void glk_request_hyperlink_event(window_t *win)
1166 {
1167 if (!win) {
1168 gli_strict_warning("request_hyperlink_event: invalid ref");
1169 return;
1170 }
1171
1172 switch (win->type) {
1173 case wintype_TextBuffer:
1174 case wintype_TextGrid:
1175 win->hyperlink_request = TRUE;
1176 break;
1177 default:
1178 /* do nothing */
1179 break;
1180 }
1181
1182 return;
1183 }
1184
glk_cancel_hyperlink_event(window_t * win)1185 void glk_cancel_hyperlink_event(window_t *win)
1186 {
1187 if (!win) {
1188 gli_strict_warning("cancel_hyperlink_event: invalid ref");
1189 return;
1190 }
1191
1192 switch (win->type) {
1193 case wintype_Graphics:
1194 case wintype_TextGrid:
1195 win->hyperlink_request = FALSE;
1196 break;
1197 default:
1198 /* do nothing */
1199 break;
1200 }
1201
1202 return;
1203 }
1204
gli_window_put_char(window_t * win,unsigned char ch)1205 void gli_window_put_char(window_t *win, unsigned char ch)
1206 {
1207 switch (win->type) {
1208 case wintype_TextBuffer:
1209 win_textbuffer_add(win->data, ch, -1);
1210 break;
1211 case wintype_TextGrid:
1212 win_textgrid_add(win->data, ch);
1213 break;
1214 }
1215 }
1216
gli_window_set_style(window_t * win,glui32 val)1217 void gli_window_set_style(window_t *win, glui32 val)
1218 {
1219 win->style = val;
1220
1221 switch (win->type) {
1222 case wintype_TextBuffer:
1223 win_textbuffer_set_style_text(win->data, win->style);
1224 break;
1225 /* Don't need a TextGrid case, since the code in macstat.c puts
1226 in style info as characters are added. */
1227 }
1228 }
1229
gli_window_set_hyperlink(window_t * win,glui32 linkval)1230 void gli_window_set_hyperlink(window_t *win, glui32 linkval)
1231 {
1232 win->linkid = linkval;
1233
1234 switch (win->type) {
1235 case wintype_TextBuffer:
1236 win_textbuffer_set_style_link(win->data, win->linkid);
1237 break;
1238 /* Don't need a TextGrid case, since the code in macstat.c puts
1239 in style info as characters are added. */
1240 }
1241 }
1242
glk_image_draw(winid_t win,glui32 image,glsi32 val1,glsi32 val2)1243 glui32 glk_image_draw(winid_t win, glui32 image, glsi32 val1, glsi32 val2)
1244 {
1245 picture_t *pic;
1246
1247 switch (win->type) {
1248 case wintype_TextBuffer:
1249 pic = picture_find(image);
1250 if (!pic)
1251 return FALSE;
1252 win_textbuffer_set_style_image(win->data, image, val1,
1253 pic->width, pic->height);
1254 win_textbuffer_add(win->data, '*', -1);
1255 win_textbuffer_set_style_text(win->data, 0xFFFFFFFF);
1256 picture_release(pic);
1257 return TRUE;
1258 case wintype_Graphics:
1259 return win_graphics_draw_picture(win->data, image, val1, val2,
1260 FALSE, 0, 0);
1261 }
1262
1263 return FALSE;
1264 }
1265
glk_image_draw_scaled(winid_t win,glui32 image,glsi32 val1,glsi32 val2,glui32 width,glui32 height)1266 glui32 glk_image_draw_scaled(winid_t win, glui32 image, glsi32 val1, glsi32 val2,
1267 glui32 width, glui32 height)
1268 {
1269 picture_t *pic;
1270
1271 switch (win->type) {
1272 case wintype_TextBuffer:
1273 pic = picture_find(image);
1274 if (!pic)
1275 return FALSE;
1276 win_textbuffer_set_style_image(win->data, image, val1, width, height);
1277 win_textbuffer_add(win->data, '*', -1);
1278 win_textbuffer_set_style_text(win->data, 0xFFFFFFFF);
1279 picture_release(pic);
1280 return TRUE;
1281 case wintype_Graphics:
1282 return win_graphics_draw_picture(win->data, image, val1, val2,
1283 TRUE, width, height);
1284 }
1285
1286 return FALSE;
1287 }
1288
glk_image_get_info(glui32 image,glui32 * width,glui32 * height)1289 glui32 glk_image_get_info(glui32 image, glui32 *width, glui32 *height)
1290 {
1291 picture_t *pic = picture_find(image);
1292 if (!pic)
1293 return FALSE;
1294
1295 if (width)
1296 *width = pic->width;
1297 if (height)
1298 *height = pic->height;
1299
1300 picture_release(pic);
1301 return TRUE;
1302 }
1303
glk_window_flow_break(winid_t win)1304 void glk_window_flow_break(winid_t win)
1305 {
1306 switch (win->type) {
1307 case wintype_TextBuffer:
1308 win_textbuffer_set_style_break(win->data);
1309 win_textbuffer_add(win->data, '*', -1);
1310 win_textbuffer_set_style_text(win->data, 0xFFFFFFFF);
1311 break;
1312 }
1313 }
1314
glk_window_erase_rect(winid_t win,glsi32 left,glsi32 top,glui32 width,glui32 height)1315 void glk_window_erase_rect(winid_t win,
1316 glsi32 left, glsi32 top, glui32 width, glui32 height)
1317 {
1318 if (!win) {
1319 gli_strict_warning("window_erase_rect: invalid ref");
1320 return;
1321 }
1322 if (win->type != wintype_Graphics) {
1323 gli_strict_warning("window_erase_rect: not a graphics window");
1324 return;
1325 }
1326 win_graphics_erase_rect(win->data, FALSE, left, top, width, height);
1327 }
1328
glk_window_fill_rect(winid_t win,glui32 color,glsi32 left,glsi32 top,glui32 width,glui32 height)1329 void glk_window_fill_rect(winid_t win, glui32 color,
1330 glsi32 left, glsi32 top, glui32 width, glui32 height)
1331 {
1332 if (!win) {
1333 gli_strict_warning("window_fill_rect: invalid ref");
1334 return;
1335 }
1336 if (win->type != wintype_Graphics) {
1337 gli_strict_warning("window_fill_rect: not a graphics window");
1338 return;
1339 }
1340 win_graphics_fill_rect(win->data, color, left, top, width, height);
1341 }
1342
glk_window_set_background_color(winid_t win,glui32 color)1343 void glk_window_set_background_color(winid_t win, glui32 color)
1344 {
1345 if (!win) {
1346 gli_strict_warning("window_set_background_color: invalid ref");
1347 return;
1348 }
1349 if (win->type != wintype_Graphics) {
1350 gli_strict_warning("window_set_background_color: not a graphics window");
1351 return;
1352 }
1353 win_graphics_set_background_color(win->data, color);
1354 }
1355
1356 /* ----- subwindow functions ---------- */
1357
win_blank_create(window_t * win)1358 window_blank_t *win_blank_create(window_t *win)
1359 {
1360 window_blank_t *dwin = (window_blank_t *)malloc(sizeof(window_blank_t));
1361 dwin->owner = win;
1362
1363 return dwin;
1364 }
1365
win_blank_destroy(window_blank_t * dwin)1366 void win_blank_destroy(window_blank_t *dwin)
1367 {
1368 dwin->owner = NULL;
1369 free(dwin);
1370 }
1371
win_blank_rearrange(window_t * win,XRectangle * box)1372 void win_blank_rearrange(window_t *win, XRectangle *box)
1373 {
1374 window_blank_t *dwin = win->data;
1375 dwin->bbox = *box;
1376 }
1377
win_blank_redraw(window_t * win)1378 void win_blank_redraw(window_t *win)
1379 {
1380 window_blank_t *dwin = win->data;
1381 gli_draw_window_outline(&dwin->bbox);
1382
1383 XFillRectangle(xiodpy, xiowin, gctech, dwin->bbox.x, dwin->bbox.y,
1384 dwin->bbox.width, dwin->bbox.height);
1385 }
1386
win_pair_create(window_t * win,glui32 method,window_t * key,glui32 size)1387 window_pair_t *win_pair_create(window_t *win, glui32 method, window_t *key,
1388 glui32 size)
1389 {
1390 window_pair_t *dwin = (window_pair_t *)malloc(sizeof(window_pair_t));
1391 dwin->owner = win;
1392
1393 dwin->dir = method & winmethod_DirMask;
1394 dwin->division = method & winmethod_DivisionMask;
1395 dwin->key = key;
1396 dwin->keydamage = FALSE;
1397 dwin->size = size;
1398
1399 dwin->vertical =
1400 (dwin->dir == winmethod_Left || dwin->dir == winmethod_Right);
1401 dwin->backward =
1402 (dwin->dir == winmethod_Left || dwin->dir == winmethod_Above);
1403
1404 dwin->child1 = NULL;
1405 dwin->child2 = NULL;
1406
1407 return dwin;
1408 }
1409
win_pair_destroy(window_pair_t * dwin)1410 void win_pair_destroy(window_pair_t *dwin)
1411 {
1412 dwin->owner = NULL;
1413 /* We leave the children untouched, because gli_window_close takes care
1414 of that if it's desired. */
1415 dwin->child1 = NULL;
1416 dwin->child2 = NULL;
1417 dwin->key = NULL;
1418 free(dwin);
1419 }
1420
win_pair_rearrange(window_t * win,XRectangle * box)1421 void win_pair_rearrange(window_t *win, XRectangle *box)
1422 {
1423 window_pair_t *dwin = win->data;
1424 XRectangle box1, box2;
1425 long min, diff, split, max;
1426 window_t *key;
1427 window_t *ch1, *ch2;
1428
1429 dwin->bbox = *box;
1430 dwin->flat = FALSE;
1431
1432 if (dwin->vertical) {
1433 min = dwin->bbox.x;
1434 max = dwin->bbox.x+dwin->bbox.width;
1435 }
1436 else {
1437 min = dwin->bbox.y;
1438 max = dwin->bbox.y+dwin->bbox.height;
1439 }
1440 diff = max-min;
1441
1442 switch (dwin->division) {
1443 case winmethod_Proportional:
1444 split = (diff * dwin->size) / 100;
1445 break;
1446 case winmethod_Fixed:
1447 key = dwin->key;
1448 if (!key) {
1449 split = 0;
1450 }
1451 else {
1452 switch (key->type) {
1453 case wintype_TextBuffer:
1454 split = win_textbuffer_figure_size(key, dwin->size, dwin->vertical);
1455 break;
1456 case wintype_TextGrid:
1457 split = win_textgrid_figure_size(key, dwin->size, dwin->vertical);
1458 break;
1459 case wintype_Graphics:
1460 split = win_graphics_figure_size(key, dwin->size, dwin->vertical);
1461 break;
1462 default:
1463 split = 0;
1464 break;
1465 }
1466 }
1467 split += HALF_MATTE_WIDTH; /* extra space for split bar */
1468 break;
1469 default:
1470 split = diff / 2;
1471 break;
1472 }
1473
1474 if (!dwin->backward) {
1475 split = diff-split;
1476 }
1477 else {
1478 split = 0+split;
1479 }
1480
1481 if (split < (MATTE_WIDTH/2))
1482 split = (MATTE_WIDTH/2);
1483 else if (split > diff - (MATTE_WIDTH - (MATTE_WIDTH/2)))
1484 split = diff - (MATTE_WIDTH - (MATTE_WIDTH/2));
1485
1486 if (diff < MATTE_WIDTH) {
1487 /* blow off the whole routine */
1488 dwin->flat = TRUE;
1489 split = diff / 2;
1490 }
1491
1492 if (dwin->vertical) {
1493 dwin->splithgt = split;
1494 if (dwin->flat) {
1495 box1.x = dwin->bbox.x+split;
1496 box1.width = 0;
1497 box2.x = dwin->bbox.x+split;
1498 box2.width = 0;
1499 }
1500 else {
1501 box1.x = dwin->bbox.x;
1502 box1.width = split - (MATTE_WIDTH/2);
1503 box2.x = box1.x + box1.width + MATTE_WIDTH;
1504 box2.width = dwin->bbox.x+dwin->bbox.width - box2.x;
1505 }
1506 box1.y = dwin->bbox.y;
1507 box1.height = dwin->bbox.height;
1508 box2.y = dwin->bbox.y;
1509 box2.height = dwin->bbox.height;
1510 if (!dwin->backward) {
1511 ch1 = dwin->child1;
1512 ch2 = dwin->child2;
1513 }
1514 else {
1515 ch1 = dwin->child2;
1516 ch2 = dwin->child1;
1517 }
1518 }
1519 else {
1520 dwin->splithgt = split;
1521 if (dwin->flat) {
1522 box1.y = dwin->bbox.y+split;
1523 box1.height = 0;
1524 box2.y = dwin->bbox.y+split;
1525 box2.height = 0;
1526 }
1527 else {
1528 box1.y = dwin->bbox.y;
1529 box1.height = split - (MATTE_WIDTH/2);
1530 box2.y = box1.y+box1.height + MATTE_WIDTH;
1531 box2.height = dwin->bbox.y+dwin->bbox.height - box2.y;
1532 }
1533 box1.x = dwin->bbox.x;
1534 box1.width = dwin->bbox.width;
1535 box2.x = dwin->bbox.x;
1536 box2.width = dwin->bbox.width;
1537 if (!dwin->backward) {
1538 ch1 = dwin->child1;
1539 ch2 = dwin->child2;
1540 }
1541 else {
1542 ch1 = dwin->child2;
1543 ch2 = dwin->child1;
1544 }
1545 }
1546
1547 gli_window_rearrange(ch1, &box1);
1548 gli_window_rearrange(ch2, &box2);
1549 }
1550
win_pair_redraw(window_t * win)1551 void win_pair_redraw(window_t *win)
1552 {
1553 XRectangle box;
1554 window_pair_t *dwin;
1555
1556 if (!win)
1557 return;
1558
1559 dwin = win->data;
1560
1561 if (xiodepth > 1) {
1562 if (dwin->vertical) {
1563 box.y = dwin->bbox.y - MATTE_WIDTH/2;
1564 box.height = dwin->bbox.height + MATTE_WIDTH;
1565 box.x = dwin->bbox.x + dwin->splithgt - (MATTE_WIDTH/2);
1566 box.width = MATTE_WIDTH;
1567 }
1568 else {
1569 box.x = dwin->bbox.x - MATTE_WIDTH/2;
1570 box.width = dwin->bbox.width + MATTE_WIDTH;
1571 box.y = dwin->bbox.y + dwin->splithgt - (MATTE_WIDTH/2);
1572 box.height = MATTE_WIDTH;
1573 }
1574 XFillRectangle(xiodpy, xiowin, gctech, box.x, box.y,
1575 box.width, box.height);
1576 }
1577
1578 gli_window_redraw(dwin->child1);
1579 gli_window_redraw(dwin->child2);
1580 }
1581
xgc_movecursor(window_t * win,int op)1582 void xgc_movecursor(window_t *win, int op)
1583 {
1584 if (!win) {
1585 if (xmsg_msgmode == xmsg_mode_Line)
1586 xgc_msg_movecursor(op);
1587 else
1588 xmsg_set_message("invalid window for cursor movement", FALSE);
1589 return;
1590 }
1591
1592 switch (win->type) {
1593 case wintype_TextBuffer:
1594 xgc_buf_movecursor(win->data, op);
1595 break;
1596 case wintype_TextGrid:
1597 xgc_grid_movecursor(win->data, op);
1598 break;
1599 default:
1600 xmsg_set_message("invalid window for cursor movement", FALSE);
1601 break;
1602 }
1603 }
1604
xgc_scroll(window_t * win,int op)1605 void xgc_scroll(window_t *win, int op)
1606 {
1607 switch (win->type) {
1608 case wintype_TextBuffer:
1609 xgc_buf_scroll(win->data, op);
1610 break;
1611 default:
1612 xmsg_set_message("invalid window for scrolling", FALSE);
1613 break;
1614 }
1615 }
1616
xgc_scrollto(window_t * win,int op)1617 void xgc_scrollto(window_t *win, int op)
1618 {
1619 switch (win->type) {
1620 case wintype_TextBuffer:
1621 xgc_buf_scrollto(win->data, op);
1622 break;
1623 default:
1624 xmsg_set_message("invalid window for scrolling", FALSE);
1625 break;
1626 }
1627 }
1628
xgc_insert(window_t * win,int op)1629 void xgc_insert(window_t *win, int op)
1630 {
1631 if (!win) {
1632 if (xmsg_msgmode == xmsg_mode_Line)
1633 xgc_msg_insert(op);
1634 else
1635 xmsg_set_message("invalid window for inserting", FALSE);
1636 return;
1637 }
1638
1639 switch (win->type) {
1640 case wintype_TextBuffer:
1641 xgc_buf_insert(win->data, op);
1642 break;
1643 case wintype_TextGrid:
1644 xgc_grid_insert(win->data, op);
1645 break;
1646 default:
1647 xmsg_set_message("invalid window for inserting", FALSE);
1648 break;
1649 }
1650 }
1651
xgc_delete(window_t * win,int op)1652 void xgc_delete(window_t *win, int op)
1653 {
1654 if (!win) {
1655 if (xmsg_msgmode == xmsg_mode_Line)
1656 xgc_msg_delete(op);
1657 else
1658 xmsg_set_message("invalid window for deleting", FALSE);
1659 return;
1660 }
1661
1662 switch (win->type) {
1663 case wintype_TextBuffer:
1664 xgc_buf_delete(win->data, op);
1665 break;
1666 case wintype_TextGrid:
1667 xgc_grid_delete(win->data, op);
1668 break;
1669 default:
1670 xmsg_set_message("invalid window for deleting", FALSE);
1671 break;
1672 }
1673 }
1674
xgc_getchar(window_t * win,int op)1675 void xgc_getchar(window_t *win, int op)
1676 {
1677 if (!win) {
1678 if (xmsg_msgmode == xmsg_mode_Char)
1679 xgc_msg_getchar(op);
1680 else
1681 xmsg_set_message("invalid window for key entry", FALSE);
1682 return;
1683 }
1684
1685 switch (win->type) {
1686 case wintype_TextBuffer:
1687 xgc_buf_getchar(win->data, op);
1688 break;
1689 case wintype_TextGrid:
1690 xgc_grid_getchar(win->data, op);
1691 break;
1692 default:
1693 xmsg_set_message("invalid window for key entry", FALSE);
1694 break;
1695 }
1696 }
1697
xgc_enter(window_t * win,int op)1698 void xgc_enter(window_t *win, int op)
1699 {
1700 if (!win) {
1701 if (xmsg_msgmode == xmsg_mode_Line)
1702 xgc_msg_enter(op);
1703 else
1704 xmsg_set_message("invalid window for line entry", FALSE);
1705 return;
1706 }
1707
1708 switch (win->type) {
1709 case wintype_TextBuffer:
1710 xgc_buf_enter(win->data, op);
1711 break;
1712 case wintype_TextGrid:
1713 xgc_grid_enter(win->data, op);
1714 break;
1715 default:
1716 xmsg_set_message("invalid window for line entry", FALSE);
1717 break;
1718 }
1719 }
1720
xgc_cutbuf(window_t * win,int op)1721 void xgc_cutbuf(window_t *win, int op)
1722 {
1723 switch (win->type) {
1724 case wintype_TextBuffer:
1725 xgc_buf_cutbuf(win->data, op);
1726 break;
1727 case wintype_TextGrid:
1728 xgc_grid_cutbuf(win->data, op);
1729 break;
1730 default:
1731 xmsg_set_message("invalid window for cut/paste", FALSE);
1732 break;
1733 }
1734 }
1735
xgc_history(window_t * win,int op)1736 void xgc_history(window_t *win, int op)
1737 {
1738 switch (win->type) {
1739 case wintype_TextBuffer:
1740 xgc_buf_history(win->data, op);
1741 break;
1742 default:
1743 xmsg_set_message("invalid window for command history", FALSE);
1744 break;
1745 }
1746 }
1747
1748