1 /*
2 * MicroEMACS 4.00 XVT.C
3 * written by Daniel M. Lawrence
4 *
5 * (C)Copyright 1995 by Daniel M. Lawrence
6 * MicroEMACS 4.00 can be copied and distributed freely for any
7 * non-commercial purposes. MicroEMACS 4.00 can only be incorporated
8 * into commercial software with the permission of the current author.
9 *
10 * The routines in this file provide support for the XVT windowing system
11 *
12 * Notice that the xvt header files force stdlib.h into the compile
13 * even though it conflicts with some of our declarations......
14 * This forced us to use the standard definitions and ditch ours.
15 */
16
17 #define termdef 1 /* don't define term external */
18 #define XVTDRIVER 1 /* this is the XVT driver */
19 #define DXVT(a) xvt_dbg(a); xvt_dbg(NULL)
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "estruct.h"
24 #include "eproto.h"
25 #include "edef.h"
26 #include "elang.h"
27
28 #if XVT
29 #undef COLOR
30
31 #include <xvt.h>
32 #include <xvtmenu.h>
33 #include "uemacs.h"
34
35 int PASCAL NEAR fnclabel(int f, int n);
36
37 #define NROW 25 /* Screen size. */
38 #define NCOL 80 /* Edit if you want to. */
39 #define NPAUSE 100 /* # times thru update to pause */
40 #define MARGIN 8 /* size of minimim margin and */
41 #define SCRSIZ 64 /* scroll size for extended lines */
42 #define BEL 0x07 /* BEL character. */
43 #define ESC 0x1B /* ESC character. */
44
45 /* Forward references. */
46 extern int PASCAL NEAR xvtmove();
47 extern int PASCAL NEAR xvteeol();
48 extern int PASCAL NEAR xvteeop();
49 extern int PASCAL NEAR xvtbeep();
50 extern int PASCAL NEAR xvtopen();
51 extern int PASCAL NEAR xvtrev();
52 extern int PASCAL NEAR xvtclose();
53 extern int PASCAL NEAR xvtkopen();
54 extern int PASCAL NEAR xvtkclose();
55 extern int PASCAL NEAR xvtcres();
56 extern int PASCAL NEAR xvtgetc();
57 extern int PASCAL NEAR xvtputc();
58 extern int PASCAL NEAR xvtflush();
59 extern int PASCAL NEAR xvtfcol();
60 extern int PASCAL NEAR xvtbcol();
61 static int rev_state = FALSE;
62
63 static int cfcolor = -1; /* current foreground color */
64 static int cbcolor = -1; /* current background color */
65
66 /* mouse status information */
67 static int oldcol; /* previous x position of mouse */
68 static int oldrow; /* previous y position of mouse */
69
70 /* Info held for XVT! */
71
72 #define MAXOBUF 256 /* maximum number of output characters buffered */
73
74 WINDOW xvt_win; /* current window being displayed by XVT */
75 WINDOW init_win; /* the initial window we are to toss */
76 int xvt_char_width; /* width of characters in pixels */
77 int xvt_char_height; /* height of characters in pixels */
78 int xvt_descent; /* height of descenders (character offset) */
79 int xvt_row = 0; /* current output row in window */
80 int xvt_col = 0; /* current column in window */
81 int xvt_fcolor = COLOR_WHITE; /* current xvt forground color */
82 int xvt_bcolor = COLOR_BLACK; /* current xvt background color */
83 COLOR xvt_colors[] = { /* xvt color translation table */
84 COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
85 COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE,
86 COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
87 COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
88 };
89 char xvt_obuf[MAXOBUF]; /* output characters buffer */
90 char *xvt_next = xvt_obuf; /* next output character position */
91 char *xvt_end = &xvt_obuf[MAXOBUF-1]; /* end of the buffer */
92
93 /*
94 * Standard terminal interface dispatch table. Most of the fields point into
95 * "termio" code.
96 */
97 NOSHARE TERM term = {
98 NROW-1,
99 NROW-1,
100 NCOL,
101 NCOL,
102 0, 0,
103 MARGIN,
104 SCRSIZ,
105 NPAUSE,
106 xvtopen,
107 xvtclose,
108 xvtkopen,
109 xvtkclose,
110 xvtgetc,
111 xvtputc,
112 xvtflush,
113 xvtmove,
114 xvteeol,
115 xvteeop,
116 xvteeop,
117 xvtbeep,
118 xvtrev,
119 xvtcres,
120 xvtfcol,
121 xvtbcol
122 };
123
124 /* Some XVT specific globals */
125
126 int xvt_argc; /* save the command line arguments to */
127 char **xvt_argv; /* pass to the emacs mainline */
128
dump_event(char * typ,EVENT * ep)129 dump_event(char *typ, EVENT *ep)
130
131 {
132 char m[128]; /* message buffer */
133
134 DXVT(typ);
135 switch (ep->type) {
136 case E_CREATE:
137 DXVT("E_CREATE:");
138 break;
139 case E_FOCUS:
140 DXVT("E_FOCUS:");
141 break;
142 case E_CLOSE:
143 DXVT("E_CLOSE:");
144 break;
145 case E_DESTROY:
146 DXVT("E_DESTROY:");
147 break;
148 case E_UPDATE:
149 DXVT("E_UPDATE:");
150 break;
151 case E_COMMAND:
152 DXVT("E_COMMAND:");
153 break;
154 case E_SIZE:
155 DXVT("E_SIZE:");
156 break;
157 case E_CHAR:
158 sprintf(m, "E_CHAR: %d S%d C%d", ep->v.chr.ch,
159 ep->v.chr.shift, ep->v.chr.control);
160 DXVT(m);
161 break;
162 case E_MOUSE_DOWN:
163 sprintf(m, "E_MOUSE_DOWN: [%d] %d/%d S%d C%d",
164 ep->v.mouse.button,
165 ep->v.mouse.where.v,ep->v.mouse.where.h,
166 ep->v.mouse.shift, ep->v.mouse.control);
167 DXVT(m);
168 break;
169 case E_MOUSE_UP:
170 sprintf(m, "E_MOUSE_UP: [%d] %d/%d S%d C%d",
171 ep->v.mouse.button,
172 ep->v.mouse.where.v,ep->v.mouse.where.h,
173 ep->v.mouse.shift, ep->v.mouse.control);
174 DXVT(m);
175 break;
176 case E_MOUSE_MOVE:
177 sprintf(m, "E_MOUSE_MOVE: [%d] %d/%d S%d C%d",
178 ep->v.mouse.button,
179 ep->v.mouse.where.v,ep->v.mouse.where.h,
180 ep->v.mouse.shift, ep->v.mouse.control);
181 DXVT(m);
182 break;
183 default:
184 sprintf(m, "E_UNKNOWN: %d", ep->type);
185 DXVT(m);
186 break;
187 }
188 }
189
windowHandler(WINDOW win,EVENT * ep)190 static long windowHandler(WINDOW win, EVENT *ep)
191
192 {
193 register int etype; /* event type byte */
194 register int event; /* encoded mouse event */
195 int mouserow, mousecol; /* mouse row/column position */
196
197 /*dump_event("win", ep);*/
198
199 switch (ep->type) {
200 case E_CREATE:
201 clear_window(win, COLOR_RED);
202
203 case E_CHAR: /* a character has been typed */
204
205 /* if it was a simple one */
206 if (ep->v.chr.ch < UCHAR_MAX) {
207 in_put(ep->v.chr.ch);
208 break;
209 }
210
211 /* otherwise, its a function key! */
212 in_fkey(ep->v.chr.ch);
213 break;
214
215 case E_FOCUS:
216 break;
217 case E_UPDATE:
218 /* sgarbf = TRUE;*/
219 break;
220
221 case E_MOUSE_MOVE: /* the mouse has moved */
222 case E_MOUSE_DOWN: /* a button has gone down */
223 case E_MOUSE_UP: /* a button has been released */
224
225 /* locate the new charactor position */
226 mouserow = ep->v.mouse.where.v / xvt_char_height;
227 mousecol = ep->v.mouse.where.h / xvt_char_width;
228
229 /* if its in the same character cell... ignore it */
230 if ((ep->type == E_MOUSE_MOVE) &&
231 (mouserow == oldrow) && (mousecol == oldcol))
232 return;
233
234 /* get the event type */
235 etype = MOUS >> 8;
236 if (ep->v.mouse.shift == TRUE)
237 etype |= (SHFT >> 8);
238 if (ep->v.mouse.control == TRUE)
239 etype |= (CTRL >> 8);
240
241 /* no buttons changes */
242 if (ep->type == E_MOUSE_MOVE) {
243
244 /* generate a mouse movement */
245 if (((mouse_move == 1) && (mmove_flag == TRUE)) ||
246 (mouse_move == 2)) {
247 in_put(0);
248 in_put(etype);
249 in_put(mousecol);
250 in_put(mouserow);
251 in_put('m');
252 }
253
254 /* save the new mouse location */
255 oldcol = mousecol;
256 oldrow = mouserow;
257 break;
258 }
259
260
261 /* encode the mouse button press */
262 in_put(0);
263 in_put(etype);
264 in_put(mousecol);
265 in_put(mouserow);
266
267 /* direction of the button press */
268 event = ((ep->type == E_MOUSE_DOWN) ? 0 : 1);
269 if (ep->v.mouse.button == 1) /* right button */
270 event += 4;
271 if (ep->v.mouse.button == 2) /* center button */
272 event += 2;
273 event += 'a';
274 in_put(event);
275
276 /* save the new mouse location */
277 oldcol = mousecol;
278 oldrow = mouserow;
279 break;
280
281 case E_CLOSE:
282 xvt_terminate();
283 }
284 return(0L);
285 }
286
in_fkey(xvt_code)287 in_fkey(xvt_code) /* input an xvt key code into the MicroEMACS
288 input stream */
289
290 int xvt_code;
291
292 {
293 unsigned int code; /* resulting MicroEMACS extended key code */
294
295 switch (xvt_code) {
296 case K_F1: /* function key 1 */
297 code = SPEC | '1'; break;
298 case K_F2:
299 code = SPEC | '2'; break;
300 case K_F3:
301 code = SPEC | '3'; break;
302 case K_F4:
303 code = SPEC | '4'; break;
304 case K_F5:
305 code = SPEC | '5'; break;
306 case K_F6:
307 code = SPEC | '6'; break;
308 case K_F7:
309 code = SPEC | '7'; break;
310 case K_F8:
311 code = SPEC | '8'; break;
312 case K_F9:
313 code = SPEC | '9'; break;
314 case K_F10:
315 code = SPEC | '0'; break;
316 case K_F11:
317 code = SPEC | '-'; break;
318 case K_F12:
319 code = SPEC | '='; break;
320 #if 0
321 case K_F13:
322 code = SPEC | ''; break;
323 case K_F14:
324 code = SPEC | ''; break;
325 case K_F15: /* function key 15 */
326 code = SPEC | ''; break;
327 #endif
328 case K_UP: /* up arrow */
329 code = SPEC | 'P'; break;
330 case K_DOWN: /* down arrow */
331 code = SPEC | 'N'; break;
332 case K_RIGHT: /* right arrow */
333 code = SPEC | 'F'; break;
334 case K_LEFT: /* left arrow */
335 code = SPEC | 'B'; break;
336 case K_PREV: /* previous screen */
337 code = SPEC | 'Z'; break;
338 case K_NEXT: /* next screen */
339 code = SPEC | 'V'; break;
340 case K_LHOME: /* line home */
341 code = SPEC | '<'; break;
342 case K_LEND: /* line end */
343 code = SPEC | '>'; break;
344 case K_HOME: /* home */
345 code = SPEC | SHFT | 'B'; break;
346 case K_END: /* end */
347 code = SPEC | SHFT | 'F'; break;
348 case K_INS: /* insert */
349 code = SPEC | 'C'; break;
350 case K_WLEFT: /* word left */
351 code = SPEC | CTRL | 'B'; break;
352 case K_WRIGHT: /* word right */
353 code = SPEC | CTRL | 'F'; break;
354 case K_BTAB: /* back tab */
355 code = SPEC | CTRL | 'I'; break;
356 case K_HELP: /* help */
357 code = SPEC | CTRL | '>'; break;
358 case K_CLEAR: /* clear */
359 code = SPEC | 'k'; break;
360 }
361
362 /* put the key in the input stream */
363 in_put(0);
364 in_put(code >> 8);
365 in_put(code & 0xFF);
366
367 }
368
taskHandler(WINDOW win,EVENT * ep)369 static long taskHandler(WINDOW win, EVENT *ep)
370 {
371 RCT rct;
372 char aname[80]; /* application name */
373 DRAW_CTOOLS dtool;
374 CBRUSH brush; /* brushed used for the clearing */
375 FONT fptr; /* font to select */
376 int leading, ascent, descent;
377
378
379 /* dump_event("tsk", ep); */
380
381 switch (ep->type) {
382 case E_CREATE:
383
384 /* set the drawing mode to opaque */
385 win_get_draw_ctools(win, &dtool);
386 dtool.opaque_text = TRUE;
387 win_set_draw_ctools(win, &dtool);
388
389 /* select an appropriate non-proportional font */
390 select_font(FF_FIXED, 0, 10, &fptr);
391 win_set_font(win, &fptr, FALSE);
392
393 /* set the current brush color! */
394 brush.pat = PAT_SOLID;
395 brush.color = xvt_colors[cbcolor];
396 win_set_cbrush(win, &brush);
397
398 /* discover the size of the current font */
399 win_get_font_metrics(win, &leading, &ascent, &descent);
400 xvt_char_height = leading + ascent + descent;
401 xvt_descent = descent;
402 xvt_char_width = win_get_text_width(win, "M", 1);
403
404 /* hide the task window... we aren't going to use it */
405 show_window(win, FALSE);
406
407 /* set up a rect to get an 25 x 80 window */
408 set_rect(&rct, xvt_char_width * 1, xvt_char_height * 2,
409 xvt_char_width * 82, xvt_char_height * 27);
410 strcpy(aname, PROGNAME);
411 strcat(aname, " ");
412 strcat(aname, VERSION);
413
414 /* create the first screen window */
415 xvt_win = create_window(W_DOC, &rct, aname, 0,
416 SCREEN_WIN, WSF_SIZE|WSF_CLOSE|/*WSF_HSCROLL|
417 WSF_VSCROLL|*/WSF_NO_MENUBAR,
418 EM_ALL, windowHandler, 0L);
419 called_main(xvt_argc, xvt_argv);
420 case E_CLOSE:
421 close_window(win);
422 break;
423 }
424 return(0L);
425 }
426
xvt_main(argc,argv)427 xvt_main(argc, argv)
428
429 int argc;
430 char **argv;
431
432 {
433 XVT_CONFIG config;
434 char aname[80]; /* application name */
435
436 /* save the command line arguments to pass to emacs */
437 xvt_argc = argc;
438 xvt_argv = argv;
439
440 /* set up the structure to let XVT know how to start */
441 config.menu_bar_ID = MAIN_MENUBAR;
442 config.about_box_ID = 0;
443 config.base_appl_name = "uemacs";
444 strcpy(aname, PROGNAME);
445 strcat(aname, " ");
446 strcat(aname, VERSION);
447 config.appl_name = aname;
448 config.taskwin_title = aname;
449
450 xvt_system(argc, argv, 0L, taskHandler, &config);
451 }
452
xvtfcol(color)453 PASCAL NEAR xvtfcol(color) /* set the current output color */
454
455 int color; /* color to set */
456
457 {
458 if (color == cfcolor)
459 return;
460 xvtflush();
461 win_set_fore_color(xvt_win, xvt_colors[color]);
462 cfcolor = color;
463 }
464
xvtbcol(color)465 PASCAL NEAR xvtbcol(color) /* set the current background color */
466
467 int color; /* color to set */
468
469 {
470 if (color == cbcolor)
471 return;
472 xvtflush();
473 win_set_back_color(xvt_win, xvt_colors[color]);
474 cbcolor = color;
475 }
476
xvtmove(row,col)477 PASCAL NEAR xvtmove(row, col)
478 {
479 xvtflush();
480 xvt_row = row;
481 xvt_col = col;
482 }
483
xvteeol()484 PASCAL NEAR xvteeol()
485 {
486 RCT rect; /* rectangle to use to clear to end of this line */
487 CBRUSH brush; /* brushed used for the clearing */
488
489 xvtflush();
490
491 /* set the rectangles limits */
492 set_rect(&rect, xvt_col * xvt_char_width,
493 xvt_row * xvt_char_height - 1,
494 term.t_ncol * xvt_char_width,
495 (xvt_row + 1) * xvt_char_height - 1);
496
497 /* set the current brush color! */
498 brush.pat = PAT_SOLID;
499 brush.color = xvt_colors[cbcolor];
500 win_set_cbrush(xvt_win, &brush);
501 win_set_std_cpen(xvt_win, TL_PEN_HOLLOW);
502
503 /* and clear it */
504 win_draw_rect(xvt_win, &rect);
505 }
506
xvteeop()507 PASCAL NEAR xvteeop()
508 {
509 RCT rect; /* rectangle to use to clear to end of this line */
510 CBRUSH brush; /* brushed used for the clearing */
511
512 xvtflush();
513
514 /* set the current brush color! */
515 brush.pat = PAT_SOLID;
516 brush.color = xvt_colors[gbcolor];
517 win_set_cbrush(xvt_win, &brush);
518 win_set_std_cpen(xvt_win, TL_PEN_HOLLOW);
519
520 /* first erase to the end of this line... */
521 /* set the rectangles limits */
522 set_rect(&rect, xvt_col * xvt_char_width,
523 xvt_row * xvt_char_height - 1,
524 term.t_ncol * xvt_char_width,
525 (xvt_row + 1) * xvt_char_height + 1);
526
527 /* and clear it */
528 win_draw_rect(xvt_win, &rect);
529
530 /* and then the rest of the window downward */
531 /* set the rectangles limits */
532 set_rect(&rect, 0,
533 (xvt_row + 1) * xvt_char_height - 1,
534 term.t_ncol * xvt_char_width,
535 term.t_nrow * xvt_char_height);
536
537 /* and clear it */
538 win_draw_rect(xvt_win, &rect);
539 }
540
xvtrev(state)541 PASCAL NEAR xvtrev(state) /* change reverse video state */
542
543 int state; /* TRUE = reverse, FALSE = normal */
544
545 {
546 int ftmp, btmp; /* temporaries for colors */
547
548 if (state != rev_state) {
549 ftmp = cfcolor;
550 btmp = cbcolor;
551 cfcolor = -1;
552 cbcolor = -1;
553 xvtfcol(btmp);
554 xvtbcol(ftmp);
555 rev_state = state;
556 }
557 }
558
xvtcres()559 PASCAL NEAR xvtcres() /* change screen resolution */
560
561 {
562 return(TRUE);
563 }
564
spal(char * dummy)565 PASCAL NEAR spal(char *dummy) /* change pallette settings */
566
567 {
568 /* none for now */
569 }
570
xvtbeep()571 PASCAL NEAR xvtbeep()
572 {
573 xvt_beep();
574 }
575
xvtopen()576 PASCAL NEAR xvtopen()
577
578 {
579 DRAW_CTOOLS dtool;
580 CBRUSH brush; /* brushed used for the clearing */
581 FONT fptr; /* font to select */
582 int leading, ascent, descent;
583
584 /* set the drawing mode to opaque */
585 win_get_draw_ctools(xvt_win, &dtool);
586 dtool.opaque_text = TRUE;
587 win_set_draw_ctools(xvt_win, &dtool);
588
589 /* select an appropriate non-proportional font */
590 select_font(FF_FIXED, 0, 10, &fptr);
591 win_set_font(xvt_win, &fptr, FALSE);
592
593 /* set the current brush color! */
594 brush.pat = PAT_SOLID;
595 brush.color = xvt_colors[cbcolor];
596 win_set_cbrush(xvt_win, &brush);
597
598 /* discover the size of the current font */
599 win_get_font_metrics(xvt_win, &leading, &ascent, &descent);
600 xvt_char_height = leading + ascent + descent;
601 xvt_descent = descent;
602 xvt_char_width = win_get_text_width(xvt_win, "M", 1);
603
604 /* initialize the mouse status */
605 oldcol = -1;
606 oldrow = -1;
607
608 /* initialize the output character queue */
609 xvt_next = xvt_obuf;
610
611 /* let emacs know the screen is open */
612 strcpy(sres, "XVT");
613 revexist = TRUE;
614 ttopen();
615 }
616
xvtclose()617 PASCAL NEAR xvtclose()
618
619 {
620 xvtfcol(7);
621 xvtbcol(0);
622 ttclose();
623 }
624
xvtkopen()625 PASCAL NEAR xvtkopen() /* open the keyboard (a noop here) */
626
627 {
628
629 }
630
xvtkclose()631 PASCAL NEAR xvtkclose() /* close the keyboard (a noop here) */
632
633 {
634 xvtflush();
635 }
636
637 /*
638 * Read a character from the terminal, performing no editing and doing no echo
639 * at all. Also mouse events are forced into the input stream here.
640 */
xvtgetc()641 int PASCAL NEAR xvtgetc()
642
643 {
644 xvtflush();
645
646 /* try first.... */
647 if (in_check())
648 return(in_get());
649
650 /* turn on the text cursor! */
651 caret_on(xvt_win, xvt_col * xvt_char_width, (xvt_row + 1) * xvt_char_height - 1);
652
653 /* loop waiting for something to happen */
654 while (TRUE) {
655 process_events();
656 if (in_check()) {
657 /* turn off the text cursor */
658 caret_off(xvt_win);
659
660 /* and return the event */
661 return(in_get());
662 }
663 }
664 }
665
xvtflush()666 int PASCAL NEAR xvtflush()
667
668 {
669 /* if there's nothing to flush */
670 if (xvt_next == xvt_obuf)
671 return;
672
673 /* draw the characters out */
674 win_draw_text(xvt_win, xvt_col * xvt_char_width,
675 (xvt_row + 1) * xvt_char_height - 1 - xvt_descent,
676 &xvt_obuf[0], (xvt_next - xvt_obuf));
677
678 xvt_col += (xvt_next - xvt_obuf);
679 xvt_next = xvt_obuf;
680 }
681
xvtputc(c)682 int PASCAL NEAR xvtputc(c)
683
684 char c; /* character to write to the current xvt window */
685
686 {
687 /* backspaces just backup the pointers */
688 if (c == '\b') {
689 xvtflush();
690 xvt_col--;
691 if (xvt_col < 0)
692 xvt_col = 0;
693 return;
694 }
695
696 /* don't go too far! */
697 if (xvt_next == xvt_end)
698 xvtflush();
699
700 *xvt_next++ = c;
701 }
702
703 #if FLABEL
fnclabel(f,n)704 int PASCAL NEAR fnclabel(f, n) /* label a function key */
705
706 int f,n; /* default flag, numeric argument [unused] */
707
708 {
709 /* on machines with no function keys...don't bother */
710 return(TRUE);
711 }
712 #endif
713 #else
xvthello()714 xvthello()
715 {
716 }
717 #endif
718