1
2 /*
3 initialize_screen()
4 reset_screen()
5 restart_screen()
6 set_attribute(int attr)
7 input_character(int timeout)
8 input_line(int buflen, char *buffer, int timeout, int *read_size)
9 display_char(int ch)
10 clear_line()
11 clear_screen()
12 clear_status_window()
13 clear_text_window()
14 create_status_window(int lines)
15 delete_status_window()
16 get_cursor_position(int *row, int *col)
17 move_cursor(int row, int col)
18 scroll_line()
19 select_status_window()
20 select_text_window()
21 */
22
23 #include <stdio.h>
24 #ifdef NEEDS_SELECT_H
25 #include <sys/select.h>
26 #endif
27 #include <ctype.h>
28 #include <sys/time.h>
29 #include <X11/Xlib.h>
30 #include <X11/Xutil.h>
31 #include <X11/keysym.h>
32
33 #include "ztypes.h"
34 #include "xio.h"
35 #include "greypm.bm"
36
37 #define EVENTMASK (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | StructureNotifyMask | ExposureMask)
38 #define STATEVENTMASK (ButtonPressMask | KeyPressMask | StructureNotifyMask | ExposureMask)
39 #define TICKLENGTH (100000)
40
41 Display *xiodpy;
42 int xioscn;
43 Window xiowin, xioswin;
44 int xiodepth;
45 int xiobackstore;
46 GC gcblack, gcwhite, gcflip, gcgrey;
47 GC gcfont[NUMFONTS];
48 GC gcsblack, gcsflip;
49 GC gcsfont[NUMFONTS], gcsnegfont[NUMFONTS];
50 XFontStruct *fontstr[NUMFONTS];
51 int spacewidth[NUMFONTS];
52 int lineheight, lineheightoff;
53 preferences prefs;
54
55 static int screen_inited = FALSE;
56
57 static int xiowinwid, xiowinhgt;
58 static int statusmode;
59 static int machineattr;
60
61 static int escapemode = FALSE;
62 static int modifymode = op_Cancel;
63
64 #ifdef __STDC__
65 static char *ansicheck = "\nThis binary was compiled with ANSI C.\n";
66 #else
67 static char *ansicheck = "\nThis binary was compiled with non-ANSI C.\n";
68 #endif
69
70 #ifdef __STDC__
71 static void loop(int stringmode, int *killflag, int timeout);
72 static void eventloop(int stringmode, int *killflag, int timeout);
73 static void redraw(int xpos, int ypos, int wid, int hgt);
74 static void rearrange_window();
75 #else
76 static void loop();
77 static void eventloop();
78 static void redraw();
79 static void rearrange_window();
80 #endif
81
82 #ifdef TESTING
83 static char *wordlist[10] = { "One ", "two ", "three ", "seventeen ", "a ", "veryvery ", "short ", "maybenot ", "I ", "stop. "};
84 #ifdef __STDC__
main()85 main()
86 #else
87 main()
88 #endif
89 {
90 int numl;
91 initialize_screen();
92 SRANDOM_FUNC(getpid() + time(NULL));
93 for (numl=0; numl>=0; numl++) {
94 int numwords = RANDOM_FUNC() % 20 + 10;
95 int ix, jx;
96 char *cx;
97 char buf[256];
98 int pos;
99 pos = 0;
100 input_line(256, buf, 0, &pos);
101 if (pos >= 4 && !strncmp(buf, "quit", 4))
102 break;
103 for (ix=0; ix<numwords; ix++) {
104 jx = RANDOM_FUNC() % 10;
105 for (cx=wordlist[jx]; *cx; cx++) {
106 display_char(*cx);
107 }
108 }
109 display_char('\n');
110 /*ix = input_character(0);
111 if (ix=='q')
112 break;*/
113 }
114 /*while (1) {
115 char buf[256];
116 int pos;
117 input_line(256, buf, 0, &pos);
118 }*/
119 reset_screen();
120 return 0;
121 }
122 #endif
123
124 #ifdef __STDC__
display_char(int ch)125 void display_char(int ch)
126 #else
127 void display_char(ch)
128 int ch;
129 #endif
130 {
131 if (!statusmode) {
132 xtext_add(ch, -1);
133 }
134 else {
135 if (ch=='\n' || ch=='\r')
136 xstat_newline();
137 else
138 xstat_insert(ch);
139 }
140 }
141
142 /* timeout is in tenth-seconds; 0 means never timeout. returns char gotten, or -1 for timed-out. */
143 #ifdef __STDC__
input_character(int timeout)144 int input_character(int timeout)
145 #else
146 int input_character(timeout)
147 int timeout;
148 #endif
149 {
150 int killflag;
151
152 if (statusmode) {
153 xstat_set_dot_active(TRUE);
154 }
155
156 killflag = (-1);
157 loop(FALSE, &killflag, timeout);
158
159 if (statusmode) {
160 xstat_set_dot_active(FALSE);
161 }
162
163 return killflag;
164 }
165
166 #ifdef __STDC__
xio_pause()167 void xio_pause()
168 #else
169 void xio_pause()
170 #endif
171 {
172 int killflag;
173
174 killflag = (-1);
175 eventloop(FALSE, &killflag, 0);
176 }
177
178 /* timeout is in tenth-seconds; 0 means never timeout. returns -1 for timed-out (and don't affect other vars). returns '\n' if enter is hit.
179 buffer and readpos are set on entry and should be set on exit.
180 cannot be called reentrantly. */
181 #ifdef __STDC__
input_line(int buflen,char * buffer,int timeout,int * readpos,int firsttime)182 int input_line(int buflen, char *buffer, int timeout, int *readpos,
183 int firsttime)
184 #else
185 int input_line(buflen, buffer, timeout, readpos, firsttime)
186 int buflen;
187 char *buffer;
188 int timeout;
189 int *readpos;
190 int firsttime;
191 #endif
192 {
193 int killflag;
194 int ix;
195
196 xted_init(buflen, buffer, readpos, &killflag, firsttime);
197
198 loop(TRUE, &killflag, timeout);
199
200 if (killflag == (-1)) {
201 xtext_line_timeout();
202 }
203
204 return killflag;
205 }
206
207 #ifdef __STDC__
initialize_screen()208 void initialize_screen()
209 #else
210 void initialize_screen()
211 #endif
212 {
213 int ix;
214 Pixmap greypm;
215
216 XSetWindowAttributes attr;
217 XGCValues gcvalues;
218
219 xinit_openconnection();
220
221 /* --- status window --- */
222
223 xioswin = XCreateSimpleWindow(xiodpy, DefaultRootWindow(xiodpy), prefs.statwinx, prefs.statwiny, prefs.statwid*spacewidth[FIXED_FONT], prefs.stathgt*lineheight, 1, prefs.forecolor, prefs.backcolor);
224
225 {
226 XSizeHints szhints;
227 szhints.flags = PMinSize|PResizeInc|USPosition|USSize;
228 szhints.x = prefs.statwinx;
229 szhints.y = prefs.statwiny;
230 szhints.width_inc = spacewidth[FIXED_FONT];
231 szhints.height_inc = lineheight;
232 szhints.width = prefs.statwid * szhints.width_inc;
233 szhints.height = prefs.stathgt * szhints.height_inc;
234 szhints.min_width = 1 * szhints.width_inc;
235 szhints.min_height = 1 * szhints.height_inc;
236 XSetNormalHints(xiodpy, xioswin, &szhints);
237 }
238 { /* make some window managers happy */
239 XWMHints wmhints;
240 wmhints.flags = InputHint;
241 wmhints.input = True;
242 XSetWMHints(xiodpy, xioswin, &wmhints);
243 }
244
245 attr.event_mask = STATEVENTMASK;
246 /*attr.backing_store = WhenMapped;*/
247 XChangeWindowAttributes(xiodpy, xioswin, CWEventMask /*|CWBackingStore*/, &attr);
248
249 XStoreName(xiodpy, xioswin, "XZip Status");
250 XMapWindow(xiodpy, xioswin);
251
252 gcvalues.function = GXcopy;
253 gcvalues.foreground = prefs.forecolor;
254 gcvalues.background = prefs.backcolor;
255 gcsblack = XCreateGC(xiodpy, xioswin, GCForeground|GCBackground, &gcvalues);
256 XSetGraphicsExposures(xiodpy, gcsblack, FALSE);
257
258 gcvalues.function = GXxor;
259 gcvalues.foreground = (prefs.textcolor[FIXED_FONT])^(prefs.backcolor);
260 gcvalues.background = (prefs.textcolor[FIXED_FONT])^(prefs.backcolor);
261 gcsflip = XCreateGC(xiodpy, xioswin, GCFunction|GCForeground|GCBackground, &gcvalues);
262
263 gcvalues.function = GXcopy;
264 for (ix=0; ix<NUMFONTS; ix++) {
265 gcvalues.font = fontstr[ix]->fid;
266 gcvalues.foreground = prefs.backcolor;
267 gcvalues.background = prefs.textcolor[ix];
268 gcsnegfont[ix] = XCreateGC(xiodpy, xioswin, GCForeground|GCBackground|GCFont, &gcvalues);
269 gcvalues.foreground = prefs.textcolor[ix];
270 gcvalues.background = prefs.backcolor;
271 gcsfont[ix] = XCreateGC(xiodpy, xioswin, GCForeground|GCBackground|GCFont, &gcvalues);
272 }
273
274 /* --- text window --- */
275
276 xiowinwid = prefs.winw;
277 xiowinhgt = prefs.winh;
278 xiowin = XCreateSimpleWindow(xiodpy, DefaultRootWindow(xiodpy), prefs.winx, prefs.winy, xiowinwid, xiowinhgt, 1, prefs.forecolor, prefs.backcolor);
279
280 {
281 XSizeHints szhints;
282 szhints.flags = PMinSize|USPosition|USSize;
283 szhints.min_width = 250;
284 szhints.min_height = 200;
285 szhints.x = prefs.winx;
286 szhints.y = prefs.winy;
287 szhints.width = xiowinwid;
288 szhints.height = xiowinhgt;
289 XSetNormalHints(xiodpy, xiowin, &szhints);
290 }
291 { /* make some window managers happy */
292 XWMHints wmhints;
293 wmhints.flags = InputHint;
294 wmhints.input = True;
295 XSetWMHints(xiodpy, xiowin, &wmhints);
296 }
297
298 attr.event_mask = EVENTMASK;
299 attr.backing_store = WhenMapped;
300 XChangeWindowAttributes(xiodpy, xiowin, CWEventMask|CWBackingStore, &attr);
301
302 XStoreName(xiodpy, xiowin, "XZip");
303 XMapWindow(xiodpy, xiowin);
304
305 gcvalues.function = GXcopy;
306 gcvalues.foreground = prefs.forecolor;
307 gcvalues.background = prefs.backcolor;
308 gcblack = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
309 XSetGraphicsExposures(xiodpy, gcblack, FALSE);
310
311 gcvalues.foreground = prefs.backcolor;
312 gcvalues.background = prefs.forecolor;
313 gcwhite = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
314
315 if (xiodepth==1) {
316 gcvalues.fill_style = FillOpaqueStippled;
317 greypm = XCreateBitmapFromData(xiodpy, xiowin, greypm_bits, greypm_width, greypm_height);
318 gcvalues.foreground = prefs.forecolor;
319 gcvalues.background = prefs.backcolor;
320 gcvalues.stipple = greypm;
321 gcgrey = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground|GCFillStyle|GCStipple, &gcvalues);
322 }
323 else {
324 gcvalues.foreground = prefs.greycolor;
325 gcvalues.background = prefs.backcolor;
326 gcgrey = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
327 }
328
329 gcvalues.function = GXxor;
330 gcvalues.foreground = (prefs.textcolor[0])^(prefs.backcolor);
331 gcvalues.background = (prefs.textcolor[0])^(prefs.backcolor);
332 gcflip = XCreateGC(xiodpy, xiowin, GCFunction|GCForeground|GCBackground, &gcvalues);
333
334 gcvalues.function = GXcopy;
335 for (ix=0; ix<NUMFONTS; ix++) {
336 gcvalues.font = fontstr[ix]->fid;
337 if (ix & REVERSE) {
338 gcvalues.foreground = prefs.backcolor;
339 gcvalues.background = prefs.textcolor[ix];
340 }
341 else {
342 gcvalues.foreground = prefs.textcolor[ix];
343 gcvalues.background = prefs.backcolor;
344 }
345 gcfont[ix] = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground|GCFont, &gcvalues);
346 }
347
348 /* --- final initing */
349
350 screen_inited = TRUE;
351
352 statusmode = FALSE;
353 xtext_init();
354 xmess_init();
355 rearrange_window();
356 {
357 char buf[64];
358 sprintf(buf, "Welcome to XZip version %s.", XZIPVERSION);
359 xmess_set_message(buf, FALSE);
360 }
361 xstat_init(prefs.statwid, prefs.stathgt, prefs.statwinx, prefs.statwiny);
362
363 machineattr = NORMAL;
364 }
365
366 #ifdef __STDC__
restart_screen()367 void restart_screen()
368 #else
369 void restart_screen()
370 #endif
371 {
372 zbyte_t val;
373
374 /* H_CONFIG is "flags 1"; H_FLAGS[0,1] is "flags 2". */
375
376 switch (h_type) {
377 case V1:
378 case V2:
379 case V3:
380 val = get_byte (H_CONFIG);
381 val |= (0x20 | 0x40); /* screen-splitting, variable-pitch font */
382 set_byte (H_CONFIG, val);
383 break;
384 case V4:
385 val = get_byte (H_CONFIG);
386 val |= (0x04 | 0x08 | 0x10 | 0x80); /* bold, italic, fixed-width, timed input */
387 set_byte (H_CONFIG, val);
388 break;
389 case V5:
390 case V8:
391 val = get_byte (H_CONFIG);
392 val |= (0x04 | 0x08 | 0x10 | 0x80); /* bold, italic, fixed-width, timed input */
393 set_byte (H_CONFIG, val);
394 val = get_byte (H_FLAGS+1);
395 val &= (~0x08); /* no graphics */
396 val &= (~0x20); /* no mouse */
397 val &= (~0x80); /* no sound */
398 set_byte (H_FLAGS+1, val);
399 break;
400 }
401 }
402
403 #ifdef __STDC__
reset_screen()404 void reset_screen()
405 #else
406 void reset_screen()
407 #endif
408 {
409 static char *killmessage = "[Hit any key to exit.]";
410
411 if (!screen_inited)
412 return;
413
414 xmess_set_message(killmessage, TRUE);
415 input_character(0);
416 XCloseDisplay(xiodpy);
417 }
418
419 /* I have extended the definition of this function; a value of -1 does not affect the style, except to re-check the force-fixed bit that the game can set.
420 The original Zip program never called set_attribute with a negative value, so this should be ok. */
421 #ifdef __STDC__
set_attribute(int attr)422 void set_attribute(int attr)
423 #else
424 void set_attribute(attr)
425 int attr;
426 #endif
427 {
428 int finalattr;
429
430 if (!attr)
431 machineattr = NORMAL;
432 else if (attr > 0)
433 machineattr |= attr;
434 else {
435 }
436
437 if (get_word (H_FLAGS) & FIXED_FONT_FLAG)
438 finalattr = machineattr | FIXED_FONT;
439 else
440 finalattr = machineattr;
441
442 if (!statusmode) {
443 xtext_setstyle(-1, finalattr);
444 }
445 else {
446 xstat_setattr(finalattr);
447 }
448 }
449
450 #ifdef __STDC__
clear_line()451 void clear_line()
452 #else
453 void clear_line()
454 #endif
455 {
456 /* ### do something! */
457 }
458
459 /* clear both text and status window */
460 #ifdef __STDC__
clear_screen()461 void clear_screen()
462 #else
463 void clear_screen()
464 #endif
465 {
466 xstat_clear_window();
467 xtext_clear_window();
468 }
469
470 #ifdef __STDC__
clear_status_window()471 void clear_status_window()
472 #else
473 void clear_status_window()
474 #endif
475 {
476 xstat_clear_window();
477 }
478
479 #ifdef __STDC__
clear_text_window()480 void clear_text_window()
481 #else
482 void clear_text_window()
483 #endif
484 {
485 xtext_clear_window();
486 }
487
488 #ifdef __STDC__
create_status_window(int lines)489 void create_status_window(int lines)
490 #else
491 void create_status_window(lines)
492 int lines;
493 #endif
494 {
495 xstat_set_window_size(lines);
496 }
497
498 #ifdef __STDC__
delete_status_window()499 void delete_status_window()
500 #else
501 void delete_status_window()
502 #endif
503 {
504 xstat_set_window_size(0);
505 }
506
507 #ifdef __STDC__
get_cursor_position(int * row,int * col)508 void get_cursor_position(int *row, int *col)
509 #else
510 void get_cursor_position(row, col)
511 int *row;
512 int *col;
513 #endif
514 {
515 if (statusmode) {
516 xstat_getpos(row, col);
517 }
518 else {
519 *row = 1;
520 *col = 1;
521 }
522 }
523
524 #ifdef __STDC__
move_cursor(int row,int col)525 void move_cursor(int row, int col)
526 #else
527 void move_cursor(row, col)
528 int row;
529 int col;
530 #endif
531 {
532 if (statusmode) {
533 xstat_setpos(row, col);
534 }
535 }
536
537 #ifdef __STDC__
scroll_line()538 void scroll_line()
539 #else
540 void scroll_line()
541 #endif
542 {
543 if (statusmode) {
544 /* ### do something? */
545 }
546 else
547 display_char ('\n');
548 }
549
550 #ifdef __STDC__
select_status_window()551 void select_status_window()
552 #else
553 void select_status_window()
554 #endif
555 {
556 statusmode = TRUE;
557 }
558
559 #ifdef __STDC__
select_text_window()560 void select_text_window()
561 #else
562 void select_text_window()
563 #endif
564 {
565 statusmode = FALSE;
566 }
567
568
569 #ifdef __STDC__
xio_bell()570 void xio_bell()
571 #else
572 void xio_bell()
573 #endif
574 {
575 XBell(xiodpy, 0);
576 }
577
578
579 #ifdef __STDC__
redraw(int xpos,int ypos,int wid,int hgt)580 static void redraw(int xpos, int ypos, int wid, int hgt)
581 #else
582 static void redraw(xpos, ypos, wid, hgt)
583 int xpos;
584 int ypos;
585 int wid;
586 int hgt;
587 #endif
588 {
589 /* yes, we ignore the exposure region. */
590 XClearWindow(xiodpy, xiowin);
591 xtext_redraw();
592 xmess_redraw();
593 }
594
595 #ifdef __STDC__
handlekey(XKeyEvent * event,int stringmode,int * killflag)596 static void handlekey(XKeyEvent *event, int stringmode, int *killflag)
597 #else
598 static void handlekey(event, stringmode, killflag)
599 XKeyEvent *event;
600 int stringmode;
601 int *killflag;
602 #endif
603 {
604 int ix;
605 char ch;
606 KeySym ksym;
607
608 ix = XLookupString(event, &ch, 1, &ksym, NULL);
609 if (IsModifierKey(ksym) || ksym==XK_Multi_key) {
610 return;
611 }
612 /* not yet set up to do keybindings */
613 if (!stringmode) {
614 if (!ix) {
615 /* ignore non-ascii characters, except arrow keys */
616 switch (ksym) {
617 case XK_Up:
618 *killflag = 129;
619 break;
620 case XK_Down:
621 *killflag = 130;
622 break;
623 case XK_Left:
624 *killflag = 131;
625 break;
626 case XK_Right:
627 *killflag = 132;
628 break;
629 }
630 return;
631 }
632 switch (ch) {
633 case '\014': /* ctrl-L */
634 xtexted_redraw(op_AllWindows);
635 break;
636 default:
637 *killflag = (unsigned char)ch;
638 break;
639 }
640 }
641 else {
642 cmdentry *command;
643 int val, which, keynum, op;
644 if (!ix) {
645 val = (ksym & 255);
646 which = keytype_sym;
647 }
648 else {
649 if (escapemode || (event->state & Mod1Mask)) {
650 escapemode = FALSE;
651 val = (ch & 255);
652 which = keytype_meta;
653 }
654 else {
655 val = (ch & 255);
656 which = keytype_main;
657 }
658 }
659 keynum = (val | which);
660 command = keycmds[keynum];
661 if (modifymode != op_Cancel && !(command && command->ignoremods)) {
662 op = modifymode;
663 modifymode = op_Cancel;
664 xtexted_modify(keynum, op);
665 }
666 else if (!command) {
667 char buf[128];
668 char *cx;
669 cx = xkey_get_key_name(keynum);
670 sprintf(buf, "Key <%s> not bound", cx);
671 xmess_set_message(buf, FALSE);
672 }
673 else {
674 if (command->operand == (-1))
675 op = keynum;
676 else
677 op = command->operand;
678 (*(command->func))(op);
679 }
680 }
681 }
682
683 /* based on new xiowinwid, xiowinhgt */
684 #ifdef __STDC__
rearrange_window()685 static void rearrange_window()
686 #else
687 static void rearrange_window()
688 #endif
689 {
690 int botwidth = lineheight+3;
691 xtext_resize(0, 0, xiowinwid, xiowinhgt-botwidth);
692 xmess_resize(0, xiowinhgt-botwidth, xiowinwid, botwidth);
693 }
694
695 /* do one round of iteration -- getchar, getline, whatever is relevant. return -1 after timeout tenth-seconds (if timeout > 0).
696 If stringmode==FALSE, return the first keystroke (immediately).
697 Otherwise, do a line of input using loop_*, returning \n. */
698 #ifdef __STDC__
loop(int stringmode,int * killflag,int timeout)699 static void loop(int stringmode, int *killflag, int timeout)
700 #else
701 static void loop(stringmode, killflag, timeout)
702 int stringmode;
703 int *killflag;
704 int timeout;
705 #endif
706 {
707 xstat_layout();
708 xtext_layout(); /* the biggie; everything has to be right after this */
709 xtext_end_visible();
710
711 eventloop(stringmode, killflag, timeout);
712 xtext_set_lastseen();
713 }
714
715 /* guts of the event loop */
716 #ifdef __STDC__
eventloop(int stringmode,int * killflag,int timeout)717 static void eventloop(int stringmode, int *killflag, int timeout)
718 #else
719 static void eventloop(stringmode, killflag, timeout)
720 int stringmode;
721 int *killflag;
722 int timeout;
723 #endif
724 {
725 int ix, jx;
726 int eventp;
727 XEvent event;
728 long evmasks;
729 struct timeval tv, curtime, outtime;
730 struct timezone tz;
731 fd_set readbits;
732 static unsigned int buttonhit;
733 static unsigned int buttonmods;
734 static int clicknum;
735 static int lastclickx=(-999), lastclicky=(-999);
736
737 if (timeout) {
738 gettimeofday (&outtime, &tz);
739 outtime.tv_sec += (timeout/10);
740 outtime.tv_usec += ((timeout%10)*100000);
741 if (outtime.tv_usec >= 1000000) {
742 outtime.tv_sec++;
743 outtime.tv_usec -= 1000000;
744 }
745 }
746
747 while (1) {
748 evmasks = ~(NoEventMask);
749 eventp = XCheckMaskEvent(xiodpy, evmasks, &event);
750 if (!eventp) {
751 tv.tv_sec = 0;
752 tv.tv_usec = TICKLENGTH;
753 FD_ZERO(&readbits);
754 FD_SET(ConnectionNumber(xiodpy), &readbits);
755 XFlush(xiodpy);
756 select(1+ConnectionNumber(xiodpy), &readbits, 0, 0, &tv);
757 }
758 else if (event.xany.window==xioswin) {
759 switch (event.type) {
760 case ButtonPress:
761 break;
762 case KeyPress:
763 xmess_check_timeout();
764 handlekey(&event.xkey, stringmode, killflag);
765 break;
766 case ConfigureNotify:
767 xstat_newgeometry(event.xconfigure.x, event.xconfigure.y, event.xconfigure.width, event.xconfigure.height);
768 break;
769 case Expose:
770 do {
771 ix = XCheckWindowEvent(xiodpy, xioswin, ExposureMask, &event);
772 } while (ix);
773 xstat_redraw();
774 break;
775 }
776 }
777 else {
778 switch (event.type) {
779 case ButtonPress:
780 xmess_check_timeout();
781 buttonhit = event.xbutton.button;
782 buttonmods = event.xbutton.state;
783 ix = lastclickx-event.xbutton.x;
784 jx = lastclicky-event.xbutton.y;
785 if (ix<=1 && ix>=(-1) && jx<=1 && jx>=(-1)) {
786 clicknum++;
787 }
788 else {
789 clicknum = 1;
790 lastclickx = event.xbutton.x;
791 lastclicky = event.xbutton.y;
792 }
793 xtext_hitdown(event.xbutton.x, event.xbutton.y, buttonhit, buttonmods, clicknum);
794 break;
795 case MotionNotify:
796 xtext_hitmove(event.xbutton.x, event.xbutton.y, buttonhit, buttonmods, clicknum);
797 break;
798 case ButtonRelease:
799 xtext_hitup(event.xbutton.x, event.xbutton.y, buttonhit, buttonmods, clicknum);
800 break;
801 case KeyPress:
802 xmess_check_timeout();
803 handlekey(&event.xkey, stringmode, killflag);
804 break;
805 case ConfigureNotify:
806 xmess_check_timeout();
807 if (event.xconfigure.width != xiowinwid || event.xconfigure.height != xiowinhgt) {
808 xiowinwid = event.xconfigure.width;
809 xiowinhgt = event.xconfigure.height;
810 rearrange_window();
811 }
812 break;
813 case Expose:
814 do {
815 ix = XCheckWindowEvent(xiodpy, xiowin, ExposureMask, &event);
816 } while (ix);
817 redraw(event.xexpose.x, event.xexpose.y, event.xexpose.width, event.xexpose.height);
818 break;
819 default:
820 break;
821 }
822 }
823
824 if (*killflag != (-1)) {
825 return;
826 }
827 if (timeout) {
828 gettimeofday (&curtime, &tz);
829 if (curtime.tv_sec > outtime.tv_sec || (curtime.tv_sec == outtime.tv_sec && curtime.tv_usec > outtime.tv_usec)) {
830 /* timed out */
831 *killflag = (-1);
832 return;
833 }
834 }
835 }
836 }
837
838 #ifdef __STDC__
xtexted_redraw(int op)839 void xtexted_redraw(int op)
840 #else
841 void xtexted_redraw(op)
842 int op;
843 #endif
844 {
845 switch (op) {
846 case op_Screen:
847 redraw(0, 0, xiowinwid, xiowinhgt);
848 break;
849 case op_Status:
850 xstat_redraw();
851 break;
852 case op_AllWindows:
853 redraw(0, 0, xiowinwid, xiowinhgt);
854 xstat_redraw();
855 break;
856 }
857 }
858
859 #ifdef __STDC__
xtexted_meta(int op)860 void xtexted_meta(int op)
861 #else
862 void xtexted_meta(op)
863 int op;
864 #endif
865 {
866 switch (op) {
867 case op_Cancel:
868 escapemode = FALSE;
869 modifymode = op_Cancel;
870 xmess_set_message("Cancelled.", FALSE);
871 break;
872 case op_DefineMacro:
873 xmess_set_message("Type a macro key to redefine.", FALSE);
874 modifymode = op_DefineMacro;
875 break;
876 case op_ExplainKey:
877 xmess_set_message("Type a key to explain.", FALSE);
878 modifymode = op_ExplainKey;
879 break;
880 case op_Escape:
881 escapemode = !escapemode;
882 break;
883 }
884 }
885
886 #ifdef __STDC__
xtexted_modify(int keynum,int op)887 void xtexted_modify(int keynum, int op)
888 #else
889 void xtexted_modify(keynum, op)
890 int keynum;
891 int op;
892 #endif
893 {
894 char buf[128];
895 char *cx;
896 cmdentry *command;
897
898 switch (op) {
899 case op_DefineMacro:
900 xted_define_macro(keynum);
901 break;
902 case op_ExplainKey:
903 cx = xkey_get_key_name(keynum);
904 command = keycmds[keynum];
905 if (!command)
906 sprintf(buf, "Key <%s> is not bound", cx);
907 else if (!keycmdargs[keynum])
908 sprintf(buf, "Key <%s>: %s", cx, command->name);
909 else {
910 if (strlen(keycmdargs[keynum]) < sizeof(buf) - 64)
911 sprintf(buf, "Key <%s>: %s \"%s\"", cx, command->name, keycmdargs[keynum]);
912 else {
913 sprintf(buf, "Key <%s>: %s \"", cx, command->name);
914 strncat(buf, keycmdargs[keynum], sizeof(buf) - 64);
915 strcat(buf, "...\"");
916 }
917 }
918 xmess_set_message(buf, FALSE);
919 break;
920 default:
921 sprintf(buf, "Unknown key modifier (%d).", op);
922 xmess_set_message(buf, FALSE);
923 break;
924 }
925 }
926
927