1 /* ST52.C: Atari ST1040/520 screen support functions
2 written by lots of people (see below)
3
4 Daniel Lawrence
5 James Turner
6 Jeff Lomicka
7 J. C. Benoist
8
9 Modification History:
10 31-dec-87 Jeff Lomicka
11 - massive changes/additions for accessories and mouse
12 20-jan-87 Daniel Lawrence
13 - changed code in domousekey() to pass five bytes, two zeros
14 (to tell input.c that this is a mouse event), x/ypos
15 and the mouse event type.
16 may 88 Jeff Lomicka and Dan Lawrence
17 - a lot of changes. Through out aline.h, use the MWC and
18 ATARI names for things now.
19 - moving the mouse to the extreme upper left brings up
20 the desk accessory menu. EMACS won't replot on the
21 way out yet.
22 - cleaned up behavior of the mouse and the cursor on exit
23 26-feb-89 Daniel Lawrence
24 - rewote input layer to conform to new specs in input.c
25 01-may-91 Daniel Lawrence/Suggested by Allan Pratt
26 - renamed atari source files to TOS.C and ST52.c
27 - changed symbols ATARI => ST52 and ST520 => TOS
28 */
29
30 #define termdef 1 /* don't define "term" external */
31
32 #include <stdio.h>
33 #include "estruct.h"
34 #include "eproto.h"
35 #include "edef.h"
36 #include "elang.h"
37
38 #if ST52
39
40 /*
41 These routines provide support for the ATARI 1040ST and 520ST
42 using the virtual VT52 Emulator
43
44 */
45
46 #include <aesbind.h>
47 #include <gemdefs.h>
48 #include <obdefs.h>
49 #include <osbind.h>
50 #include <xbios.h>
51 #include <linea.h>
52
53 #define NROW 50 /* Screen size. */
54 #define NCOL 80 /* Edit if you want to. */
55 #define MARGIN 8 /* size of minimim margin and */
56 #define SCRSIZ 64 /* scroll size for extended lines */
57 #define NPAUSE 300 /* # times thru update to pause */
58 #define BIAS 0x20 /* Origin 0 coordinate bias. */
59 #define ESC 0x1B /* ESC character. */
60 #define SCRFONT 2 /* index of 8x16 monochrome system default font */
61 #define DENSIZE 50 /* # of lines in a dense screen */
62
63 /**** ST Internals definitions *****/
64
65 /* BIOS calls */
66
67 #define BCONSTAT 1 /* return input device status */
68 #define CONIN 2 /* read character from device */
69 #define BCONOUT 3 /* write character to device */
70
71 /* XBIOS calls */
72
73 #define INITMOUS 0 /* initialize the mouse */
74 #define GETREZ 4 /* get current resolution */
75 #define SETSCREEN 5 /* set screen resolution */
76 #define SETPALETTE 6 /* set the color pallette */
77 #define SETCOLOR 7 /* set or read a color */
78 #define CURSCONF 21 /* set cursor configuration */
79 #define IKBDWS 25 /* intelligent keyboard send command */
80 #define KBDVBASE 34 /* get keyboard table base */
81
82 /* GEMDOS calls */
83
84 #define EXEC 0x4b /* Exec off a process */
85 #define CON 2 /* CON: Keyboard and screen device */
86
87 /* Palette color definitions */
88
89 #define LOWPAL "000700070770007707077777333733373773337737377777"
90 #define MEDPAL "000700007777"
91 #define HIGHPAL "111000"
92
93 /* ST Global definitions */
94
95 int initrez; /* initial screen resolution */
96 int currez; /* current screen resolution */
97 int gemflag; /* were we called from the desktop? */
98 int mouseon; /* True if mouse is on */
99 char resname[][8] = { /* screen resolution names */
100 "LOW", "MEDIUM", "HIGH", "DENSE"
101 };
102 short spalette[16]; /* original color palette settings */
103 short palette[16]; /* current palette settings */
104 static short scursor; /* original text cursor mode */
105
106 struct la_data *aline; /* Line A data structure */
107
108 struct la_ext *naline; /* extended Line A data structure */
109
110 struct la_font **fonts; /* Array of pointers to the three system
111 font headers returned by init (in register A1) */
112
113 struct la_font *system_font; /* pointer to default system font */
114 struct la_font *small_font; /* pointer to small font */
115
116 /*
117 These are needed to make GEM happy
118 */
119 int contrl[ 11], intin[ 128], intout[ 128], ptsin[ 256], ptsout[ 12];
120 static int worki[ 11] = {1,1,1,1,1,1,1,1,1,1,2}, worko[ 57];
121
122 /*
123 Some useful information about our environment
124 */
125 static int
126 g_wchar, g_hchar, /* VDI's idea of current font size */
127 junk, gid, wkid; /* Graphics ID, workstation ID */
128
129 static int oldbut = 0; /* Previous state of mouse buttons */
130 static int mctrl; /* current BEG_MOUSE state */
131 static struct { char *norm, *shift, *caps;} *kt; /* Keyboard mapping */
132
133 /*
134 This object tree is for displaying the desk accessory menu.
135 Actual positions are written into this structure when the
136 screen size is known.
137 */
138 OBJECT menu[] =
139 {
140 -1, 1, 4, G_IBOX, NONE, NORMAL, 0x0L, 0 , 0, 0, 0,/* Root */
141 4, 2, 2, G_BOX, NONE, NORMAL, 0x10F0L, 0, 0, 1, 1,/* BAR */
142 1, 3, 3, G_IBOX, NONE, NORMAL, 0x0L, 0, 0, 1, 1,/* Active */
143 2,-1,-1, G_TITLE, NONE, NORMAL, "", 0, 0, 1, 1,/* title */
144 0, 5, 5, G_IBOX, NONE, NORMAL, 0x0L, 0, 0, 0, 0,/* screen */
145 4, 6,13, G_BOX, NONE, NORMAL, 0xFF1100L, 0, 0, 0, 0,/* box */
146 7,-1,-1, G_STRING, NONE, NORMAL, TEXT179,0,0,168, 16,
147 /* " About MicroEmacs" */
148 8,-1,-1, G_STRING, NONE,DISABLED, "---------------------",
149 0, 16, 168, 16,
150 9,-1,-1, G_STRING, NONE, NORMAL, "", 0, 32, 168, 16,
151 10,-1,-1, G_STRING, NONE, NORMAL, "", 0, 48, 168, 16,
152 11,-1,-1, G_STRING, NONE, NORMAL, "", 0, 64, 168, 16,
153 12,-1,-1, G_STRING, NONE, NORMAL, "", 0, 80, 168, 16,
154 13,-1,-1, G_STRING, NONE, NORMAL, "", 0, 96, 168, 16,
155 5,-1,-1, G_STRING, LASTOB, NORMAL, "", 0,112, 168, 16
156 };
157
158 extern mymouse(); /* .s file for calling two mouse handlers */
159 int (*first_mhandler)(); /* Address of first handler */
160 int (*second_mhandler)(); /* Address of second handler */
161 struct kbdvbase *kv; /* Keyboard vector table */
162 static int msevntsiz = 0; /* Events in private mouse event queue */
163 static unsigned short msevntq[16];/* State of mouse keys at event */
164 static int msevntin = 0; /* Queue input ptr */
165 static int msevntout = 0; /* Queue output ptr */
166 static int mousekeys1 = 0; /* Last mouse key event */
167 static int mousecol = HUGE; /* current mouse column */
168 static int mouserow = HUGE; /* current mouse row */
169
170 extern int ttopen(); /* Forward references. */
171 extern int ttgetc();
172 extern int ttputc();
173 extern int ttflush();
174 extern int ttclose();
175 extern int stmove();
176 extern int steeol();
177 extern int steeop();
178 extern int stbeep();
179 extern int stopen();
180 extern int stclose();
181 extern int stgetc();
182 extern int stputc();
183 extern int strev();
184 extern int strez();
185 extern int stkopen();
186 extern int stkclose();
187
188 #if COLOR
189 extern int stfcol();
190 extern int stbcol();
191 #endif
192
193 /*
194 * Dispatch table. All the
195 * hard fields just point into the
196 * terminal I/O code.
197 */
198 TERM term = {
199 NROW-1,
200 NROW-1,
201 NCOL,
202 NCOL,
203 0, 0,
204 MARGIN,
205 SCRSIZ,
206 NPAUSE,
207 &stopen,
208 &stclose,
209 &stkopen,
210 &stkclose,
211 &stgetc,
212 &stputc,
213 &ttflush,
214 &stmove,
215 &steeol,
216 &steeop,
217 &steeop,
218 &stbeep,
219 &strev,
220 &strez
221 #if COLOR
222 , &stfcol,
223 &stbcol
224 #endif
225 };
226
227 /* input buffers and pointers */
228
229 #define IBUFSIZE 64 /* this must be a power of 2 */
230
231 unsigned char in_buf[IBUFSIZE]; /* input character buffer */
232 int in_next = 0; /* pos to retrieve next input character */
233 int in_last = 0; /* pos to place most recent input character */
234
in_init()235 in_init() /* initialize the input buffer */
236
237 {
238 in_next = in_last = 0;
239 }
240
in_check()241 in_check() /* is the input buffer non-empty? */
242
243 {
244 if (in_next == in_last)
245 return(FALSE);
246 else
247 return(TRUE);
248 }
249
in_put(event)250 in_put(event)
251
252 int event; /* event to enter into the input buffer */
253
254 {
255 in_buf[in_last++] = event;
256 in_last &= (IBUFSIZE - 1);
257 }
258
in_get()259 int in_get() /* get an event from the input buffer */
260
261 {
262 register int event; /* event to return */
263
264 event = in_buf[in_next++];
265 in_next &= (IBUFSIZE - 1);
266 return(event);
267 }
268
init_aline()269 void init_aline()
270
271 {
272 int *ld_contrl;
273 int *ld_intin;
274
275 linea0();
276
277 /* save if the current mouse is hidden (ie we are not in GEM) */
278 gemflag = (mousehidden == 0);
279 while (mousehidden) {
280 showmouse();
281 }
282 aline = (struct la_data *)(la_init.li_a0);
283 fonts = (struct la_font **)(la_init.li_a1);
284 naline = ((struct la_ext *)aline) - 1;
285 scursor = naline->ld_status; /* State of text cursor */
286 ld_contrl = aline->ld_contrl; /* -> control junk */
287 ld_intin = aline->ld_intin; /* -> intin junk */
288 }
289
init()290 init()
291
292 {
293 init_aline();
294 system_font = fonts[SCRFONT]; /* save it */
295 small_font = fonts[1];
296 }
297
298
299 switch_font(fp)
300
301 struct la_font *fp;
302
303 {
304 /* See linea.h for description of fields */
305
306 V_CEL_HT = fp->font_height;
307 V_CEL_WR = aline->ld_vwrap * fp->font_height;
308 V_CEL_MY = (naline->ld_y_max / fp->font_height) - 1;
309 V_CEL_MX = (naline->ld_x_max / fp->font_fat_cell) - 1;
310 V_FNT_WR = fp->font_width;
311 V_FNT_ST = fp->font_low_ade;
312 V_FNT_ND = fp->font_hi_ade;
313 V_OFF_AD = (long) fp->font_char_off;
314 V_FNT_AD = (long) fp->font_data;
315 }
316
stmove(row,col)317 stmove(row, col)
318
319 {
320 stputc(ESC);
321 stputc('Y');
322 stputc(row+BIAS);
323 stputc(col+BIAS);
324 }
325
steeol()326 steeol()
327
328 {
329 stputc(ESC);
330 stputc('K');
331 }
332
steeop()333 steeop()
334
335 {
336 #if COLOR
337 stfcol(gfcolor);
338 stbcol(gbcolor);
339 #endif
340 stputc(ESC);
341 stputc('J');
342 }
343
strev(status)344 strev(status) /* set the reverse video state */
345
346 int status; /* TRUE = reverse video, FALSE = normal video */
347
348 {
349 if (currez > 1) {
350 stputc(ESC);
351 stputc(status ? 'p' : 'q');
352 }
353 }
354
355 #if COLOR
mapcol(clr)356 mapcol(clr) /* medium rez color translation */
357
358 int clr; /* emacs color number to translate */
359
360 {
361 static int mctable[] = {0, 1, 2, 3, 2, 1, 2, 3};
362
363 if (currez != 1)
364 return(clr);
365 else
366 return(mctable[clr]);
367 }
368
stfcol(color)369 stfcol(color) /* set the forground color */
370
371 int color; /* color to set forground to */
372
373 {
374 if (currez < 2) {
375 stputc(ESC);
376 stputc('b');
377 stputc(mapcol(color));
378 }
379 }
380
stbcol(color)381 stbcol(color) /* set the background color */
382
383 int color; /* color to set background to */
384
385 {
386 if (currez < 2) {
387 stputc(ESC);
388 stputc('c');
389 stputc(mapcol(color));
390 }
391 }
392 #endif
393
394 static char beep[] = {
395 0x00, 0x00,
396 0x01, 0x01,
397 0x02, 0x01,
398 0x03, 0x01,
399 0x04, 0x02,
400 0x05, 0x01,
401 0x07, 0x38,
402 0x08, 0x10,
403 0x09, 0x10,
404 0x0A, 0x10,
405 0x0B, 0x00,
406 0x0C, 0x30,
407 0x0D, 0x03,
408 0xFF, 100,
409 0x09, 0x00,
410 0x0A, 0x00,
411 0xFF, 0x00
412 };
413
stbeep()414 stbeep()
415
416 {
417 Dosound(beep);
418 }
419
mouse_on()420 mouse_on() /* turn the gem mouse ON */
421
422 {
423 if (!mouseon) {
424 graf_mouse( M_ON, 0L);
425 graf_mouse(ARROW, 0L);
426 mouseon = 1;
427 }
428 }
429
mouse_off()430 mouse_off() /* turn the gem mouse OFF */
431
432 {
433 if (mouseon) {
434 graf_mouse( M_OFF, 0L);
435 mouseon = 0;
436 }
437 if( !mousehidden) stbeep();
438 }
439
440 /*
441 me_mh - MicroEmacs Mouse interrupt Handler. This handler is called,
442 in addition to the regular mouse handler, in order for microemacs
443 to have access to some more information about the mouse events.
444
445 What it does is:
446
447 - Queue a copy of the mouse button state at the actual moment of
448 the event, rather than after GEM is finished playing with timers.
449
450 - Convert all right-mouse-button events into left-mouse-button
451 events BEFORE GEM's mouse interrupt handler, so that GEM will generate
452 a left-mouse-button event.
453 */
me_mh(a)454 me_mh(a)
455
456 char *a;
457 {
458 register unsigned mousekeys;
459
460 mousekeys = a[0] & 7;
461 if (mousekeys != 0)
462 a[0] = 0xFA; /* Any key down means button 1 down */
463 else
464 a[0] = 0xf8; /* Otherwise button 1 up */
465 if (msevntsiz < 16) {
466 /* Previous event was processed, look for next one */
467 if (mousekeys != mousekeys1) {
468 /* A button change is detected, insert it in queue */
469 msevntq[msevntin++] = mousekeys;
470 msevntin &= 15;
471 msevntsiz++;
472 mousekeys1 = mousekeys;
473 }
474 }
475 }
476
477
stkopen()478 stkopen() /* open the keyboard (and mouse) */
479 {
480 }
481
stopen()482 stopen() /* open the screen */
483
484 {
485 register int i;
486
487 init();
488 strcpy(os, "TOS");
489
490 /*
491 Set up an interrupt handler for the mouse that performs both
492 me_mh() and the default mouse handling. The .s file "stmouse.s"
493 contains some special code for this purpose.
494 */
495 first_mhandler = me_mh;
496 kv = Kbdvbase();
497 second_mhandler = kv->kb_mousevec;
498 kv->kb_mousevec = mymouse;
499 /*
500 In order to have both the mouse cursor and the text cursor on the
501 screen at the same time, we have to flash it ourselves, turning
502 the mouse cursor on and off for each flash.
503
504 The cursors are both off whenever we are not in an input wait.
505 */
506 Cursconf(3, 0); /* Stop text cursor from flashing */
507 Cursconf(0, 0); /* Turn text cursor off */
508 /*
509 Wake up GEM and the VDI
510 */
511 appl_init();
512 gid = graf_handle(&g_wchar, &g_hchar, &junk, &junk);
513 #if 0
514 /* We never use the VDI, but if you do, turn this back on */
515 v_opnvwk(worki, &wkid, worko);
516 #endif
517 graf_mouse( M_OFF, 0L);
518 mouseon = 0;
519 /*
520 Set up the menu bar's coordinates to match the font and screen size
521 for this screen resolution
522 */
523 wind_get(0, WF_CURRXYWH, /* Fetch actual screen size for menu */
524 &menu[0].ob_x, &menu[0].ob_y,
525 &menu[0].ob_width, &menu[0].ob_height);
526 menu[1].ob_x = menu[0].ob_width - 1; /* Locate "desk" box */
527 menu[4].ob_width = menu[0].ob_width;
528 menu[4].ob_height = 8*g_hchar;
529 menu[5].ob_width = 21*g_wchar;
530 menu[5].ob_height = 8*g_hchar;
531 menu[5].ob_x = menu[0].ob_width - menu[5].ob_width;
532 for(i=6; i<14; i++) {
533 /* Desk accessory items */
534 menu[i].ob_y = (i-6)*g_hchar;
535 menu[i].ob_width = menu[5].ob_width;
536 menu[i].ob_height = g_hchar;
537 }
538 menu_bar(menu, 1);
539 /*
540 Shut off GEM's user interface until we enter an input wait.
541 Note that unless we claim the mouse with BEG_MCTRL, we will not
542 get scheduled to run any time the left mouse button goes down while
543 the mouse is on the top 16 pixels of the screen. We keep Emacs
544 "hung" whenever MCTRL is given to desk accessories or GEM, and keep
545 GEM hung whenever we have control.
546 */
547 wind_update(BEG_UPDATE); /* Shuts off GEM drawing */
548 wind_update(BEG_MCTRL); /* Shuts off GEM use of mouse */
549
550 mctrl = 0; /* Flag that we have mouse control */
551 kt = Keytbl( -1L, -1L, -1L);
552
553 ttopen();
554 eolexist = TRUE;
555
556 /* save the current color palette */
557 for (i=0; i<16; i++)
558 spalette[i] = xbios(SETCOLOR, i, -1);
559
560 /* and find the current resolution */
561 initrez = currez = xbios(GETREZ);
562 strcpy(sres, resname[currez]);
563
564 /* set up the screen size and palette */
565 switch (currez) {
566 case 0: term.t_mrow = 25 - 1;
567 term.t_nrow = 25 - 1;
568 term.t_ncol = 40;
569 strcpy(palstr, LOWPAL);
570 break;
571
572 case 1: term.t_mrow = 25 - 1;
573 term.t_nrow = 25 - 1;
574 strcpy(palstr, MEDPAL);
575 break;
576
577 case 2: term.t_mrow = DENSIZE - 1;
578 term.t_nrow = 25 - 1;
579 strcpy(palstr, HIGHPAL);
580 }
581
582 /* and set up the default palette */
583 spal(palstr);
584
585 stputc(ESC); /* automatic overflow off */
586 stputc('w');
587
588 /* initialize the input buffer */
589 in_init();
590 }
591
stkclose()592 stkclose() /* close the keyboard (and mouse) */
593 {
594 }
595
stclose()596 stclose()
597
598 {
599 stputc(ESC); /* auto overflow on */
600 stputc('v');
601
602 /* restore the original screen resolution */
603 if (currez == 3)
604 switch_font(system_font);
605 strez(resname[initrez]);
606
607 /* restore the original palette settings */
608 xbios(SETPALETTE, spalette);
609
610 ttclose();
611
612 kv->kb_mousevec = second_mhandler; /* Restore original handler */
613
614 mouse_on(); /* turn the mouse on */
615 if (gemflag != 0) {
616 /* coming from gem..... we */
617 Cursconf(0, 0); /* turn the cursor off */
618 } else {
619 /* coming from a shell, we */
620 Cursconf(1, 0); /* turn the cursor on */
621 Cursconf(2, 0); /* Turn text cursor blinking */
622 hidemouse(); /* Turn mouse off for shell */
623 }
624
625 wind_update(END_MCTRL); /* Return GEM's control of screen */
626 wind_update(END_UPDATE);
627 #if 0
628 v_clsvwk(wkid); /* Clean up GEM */
629 #endif
630 appl_exit();
631 }
632
633 /* spal(pstr): reset the current palette according to a
634 "palette string" of the form
635
636 000111222333444555666777
637
638 which contains the octal values for the palette registers
639 */
640
spal(pstr)641 spal(pstr)
642
643 char *pstr; /* palette string */
644
645 {
646 int pal; /* current palette position */
647 int clr; /* current color value */
648 int i;
649
650 for (pal = 0; pal < 16; pal++) {
651 if (*pstr== 0)
652 break;
653
654 /* parse off a color */
655 clr = 0;
656 for (i = 0; i < 3; i++)
657 if (*pstr)
658 clr = clr * 16 + (*pstr++ - '0');
659 palette[pal] = clr;
660 };
661
662 /* and now set it */
663 xbios(SETPALETTE, palette);
664 }
665
domousekey(newbut,sk)666 static domousekey(newbut, sk)
667
668 int sk;
669
670 {
671 register int k;
672
673 for(k=1; k!=4; k = k<<1) { /* J is butnum, k is bit num */
674 /* For each button on the mouse */
675 if ((oldbut&k) != (newbut&k)) {
676 /* This button changed, generate an event */
677 in_put(0); /* escape indicator */
678 in_put(MOUS >> 8); /* mouse event */
679 in_put(mousecol); /* x-position */
680 in_put(mouserow); /* y-position */
681 in_put(((newbut&k) ? 0 : 1)
682 + (k==1 ? 4 : 0)
683 + ((sk&3) ? 'A' : 'a'));
684 }
685 }
686 oldbut = newbut;
687 }
688
stgetc()689 stgetc() /* get a char from the keyboard */
690
691 {
692 register int flashcounter; /* Counter for flashing cursor */
693 register int ev_which; /* Event returned */
694 register int sc; /* Keyboard scan code */
695 static int bexpected = 1; /* Expected next mouse state */
696 int mx, my, bstate, sk, key, mc;/* Event parameters */
697 int mes[8];
698
699 /* Working out a multi-byte input sequence */
700 if (in_check())
701 return(in_get());
702
703 Cursconf(1, 0); /* Turn text cursor on */
704 mouse_on(); /* Let mouse work */
705 wind_update(END_UPDATE);
706 if (mctrl)
707 wind_update(END_MCTRL);
708 flashcounter = 0;
709 for(;;) {
710 if (!mctrl) {
711 /* We have control, so it is okay to flash cursor */
712 if (flashcounter == 6) {
713 mouse_off();
714 Cursconf(0, 0); /* After 60ms, turn it off */
715 mouse_on();
716 } else if (flashcounter == 10) {
717 /* Wrapped around one cycle of cursor flashing,
718 turn it on */
719 mouse_off();
720 Cursconf(1, 0);
721 mouse_on();
722 flashcounter = 0;
723 }
724 }
725
726 /* do the event-multi thing */
727 ev_which = evnt_multi(
728 MU_TIMER | MU_MESAG | MU_KEYBD | MU_BUTTON | MU_M1,
729 1, /* Maximum clicks to wait for */
730 1, /* Buttons that generate events */
731 bexpected, /* Button states that generate events */
732 0, menu[1].ob_x, menu[1].ob_y,
733 menu[1].ob_width, menu[1].ob_height,
734 0, 0, 0, 0, 0, /* enter/exit, x, y, w, h for rect 2 */
735 mes, /* Buffer to receive mesasge */
736 /* Low and high order miliseconds of counter */
737 100, 0,
738 &mx, &my, /* Mouse location */
739 &bstate, /* State of the mouse buttons */
740 &sk, /* State of the shift keys */
741 &key, /* Key pressed */
742 &mc); /* Actual number of clicks */
743
744 if (ev_which & MU_KEYBD) {
745 /* Keyboard events cause keystrokes, add SPC prefix to fn keys */
746 if (mctrl)
747 wind_update(BEG_MCTRL);
748 Giaccess(0, 9+128);
749 Giaccess(0, 10+128);
750
751 /* Cancel any double-clicking */
752 nclicks = 0;
753 mctrl = 0;
754
755 sc = key>>8;
756 key &= 0xff;
757 extcode( sk, sc, key);
758 } else if (ev_which & MU_BUTTON) {
759 /* Mouse event, look at our actual mouse event */
760 int top, junk;
761 wind_get(0, WF_TOP, &top, &junk, &junk, &junk);
762 if (top == 0) {
763 /* Desktop is top window,
764 allow Emacs to continue */
765 bexpected = (~bstate)&1;
766 mousecol = mx/g_wchar;
767 mouserow = my/g_hchar;
768 while(msevntsiz > 0) {
769 /* Process each queued event */
770 domousekey(msevntq[msevntout++], sk);
771 msevntout &= 15;
772 msevntsiz--;
773 }
774 if (mctrl) wind_update(BEG_MCTRL);
775 mctrl = 0;
776 }
777 } else if (ev_which & MU_M1) {
778 /* Mouse entered desk menu, allow it to appear */
779 if (!mctrl) wind_update(END_MCTRL);
780 mctrl = 1;
781 sgarbf = TRUE;
782 } else if (ev_which & MU_TIMER) {
783 flashcounter++;
784 } else {
785 /* Most likely is the about message */
786 }
787
788 /* is there now a pending event? */
789 if (in_check()) {
790 key = in_get();
791 break;
792 }
793 }
794
795 if (mctrl)
796 wind_update(BEG_MCTRL);
797 wind_update(BEG_UPDATE);
798 mouse_off();
799 Cursconf(0, 0); /* Turn text cursor off */
800 return(key & 0xFF);
801 }
802
stputc(c)803 stputc(c) /* output char c to the screen */
804
805 char c; /* character to print out */
806
807 {
808 bios(BCONOUT, CON, c);
809 }
810
strez(newrez)811 strez(newrez) /* change screen resolution */
812
813 char *newrez; /* requested resolution */
814
815 {
816 int nrez; /* requested new resolution */
817
818 /* first, decode the resolution name */
819 for (nrez = 0; nrez < 4; nrez++)
820 if (strcmp(newrez, resname[nrez]) == 0)
821 break;
822 if (nrez == 4) {
823 mlwrite(TEXT180);
824 /* "%%No such resolution" */
825 return(FALSE);
826 }
827
828 /* next, make sure this resolution is legal for this monitor */
829 if ((currez < 2 && nrez > 1) || (currez > 1 && nrez < 2)) {
830 mlwrite(TEXT181);
831 /* "%%Resolution illegal for this monitor" */
832 return(FALSE);
833 }
834
835 /* eliminate non-changes */
836 if (currez == nrez)
837 return(TRUE);
838
839 /* finally, make the change */
840 switch (nrez) {
841 case 0: /* low resolution - 16 colors */
842 newwidth(TRUE, 40);
843 strcpy(palstr, LOWPAL);
844 xbios(SETSCREEN, -1L, -1L, 0);
845 g_wchar = g_hchar = 8;
846 break;
847
848 case 1: /* medium resolution - 4 colors */
849 newwidth(TRUE, 80);
850 strcpy(palstr, MEDPAL);
851 xbios(SETSCREEN, -1L, -1L, 1);
852 g_wchar = g_hchar = 8;
853 break;
854
855 case 2: /* High resolution - 2 colors - 25 lines */
856 newsize(TRUE, 25);
857 strcpy(palstr, HIGHPAL);
858 switch_font(system_font);
859 g_wchar = g_hchar = 16;
860 break;
861
862 case 3: /* Dense resolution - 2 colors - 40 lines */
863 newsize(TRUE, DENSIZE);
864 strcpy(palstr, HIGHPAL);
865 switch_font(small_font);
866 g_wchar = g_hchar = 8;
867 break;
868 }
869
870 /* and set up the default palette */
871 spal(palstr);
872 currez = nrez;
873 strcpy(sres, resname[currez]);
874
875 stputc(ESC); /* automatic overflow off */
876 stputc('w');
877 return(TRUE);
878 }
879
880 /* extcode: resolve Atari-ST extended character codes
881 encoding the proper sequences into emacs
882 printable character specifications
883 */
884
extcode(sk,sc,key)885 int extcode( sk, sc, key)
886 unsigned sk; /* Shift keys from event */
887 unsigned sc; /* ST scancode */
888 unsigned key; /* GEMDOS translation of the key */
889 {
890 int shift; /* CAPS LOCK flag doesn't come from EVENT_MULTI */
891 unsigned code; /* Build up special function code */
892 /*
893 Identify any shit-key codes associated with this keystorke
894 */
895 code = 0;
896 /*
897 I don't know why, but for some reason the codes for ALT of top row and
898 for CTRL of left, right and HOME come up wrong, and this fixes them.
899 */
900 if( sc == 0x77) sc = 0x47;
901 else if( sc == 0x73) sc = 0x4b;
902 else if( sc == 0x74) sc = 0x4d;
903 else if( sc > 0x76) sc -= 0x76;
904 /*
905 Bring the shifted function key scan codes back into regular range
906 */
907 if( sc >= 0x54 && sc <= 0x5d) sc -= (0x54-0x3B);
908 if( sk & K_ALT)
909 { /* ALT shift requires special handling */
910 code |= ALTD;
911 /*
912 ALT of ordinary keys always returns '0' for the key. Look up
913 the actual key as if ALT weren't there.
914 */
915 shift = Getshift(-1); /* Get state of shift keys (CAPS lock) */
916 /*
917 Map the key to a normal keystroke. Keypad keys are treated special,
918 everyone else is mapped using the installed keytables. This
919 means it will work right on German and other keyboards.
920 */
921 if( sk & K_CTRL) { code |= CTRL; key = kt->caps[ sc];}
922 else if( sk & 3) key = kt->shift[ sc]; /* shift */
923 else if( shift & 16) key = kt->caps[ sc]; /* Caps lock */
924 else key = kt->norm[ sc];
925 }
926 /*
927 Peel of the numeric keypad keys
928 */
929 if( sc == 0x72) key = 'E';
930 if( sc >= 0x63 || sc == 0x4A || sc == 0x4E)
931 { /* Keypad keys are SPEC or CTRL of what's on the key */
932 code |= SPEC | CTRL;
933 }
934 /*
935 translate function keys into digits
936 */
937 if( sc >= 0x3b && sc <= 0x5d)
938 { /* This is a F1 thry F9 */
939 code |= SPEC;
940 key = sc - 0x3b + '1';
941 if( key == '9'+1) key = '0';
942 }
943 if( sc == 0x62) { code |= SPEC; key = 'H';}
944 if( sc == 0x61) { code |= SPEC; key = 'X';}
945 if( sc == 0x52) { code |= SPEC; key = 'C';}
946 if( sc == 0x47) { code |= SPEC; key = 'D';}
947 if( sc == 0x48) { code |= SPEC; key = 'P';}
948 if( sc == 0x4b) { code |= SPEC; key = 'B';}
949 if( sc == 0x50) { code |= SPEC; key = 'N';}
950 if( sc == 0x4d) { code |= SPEC; key = 'F';}
951 /*
952 translate CTRL-shifted of keys that don't usually CTRL
953 */
954 if((sk & K_CTRL) && (sc <= 0x0D || key == 0))
955 { /* Control of a non-usually-control key */
956 shift = Getshift(-1); /* Get state of CAPS lock */
957 code |= CTRL;
958 if( sk & 3) key = kt->shift[ sc]; /* shift */
959 else if( shift & 16) key = kt->caps[ sc]; /* Caps lock */
960 else key = kt->norm[ sc];
961 }
962 if( key == 0) key = '@'; /* Catch junk */
963 if( code != 0)
964 { /* This is a special key */
965 if( code & SPEC)
966 { /* Get shift and ctrl of function keys */
967 if( sk & 3) code |= SHFT;
968 if( sk & K_CTRL) code |= CTRL;
969 }
970 in_put( 0);
971 in_put( code>>8);
972 in_put( key);
973 }
974 else in_put( key);
975 }
976
977 #if FLABEL
fnclabel(f,n)978 fnclabel(f, n) /* label a function key */
979
980 int f,n; /* default flag, numeric argument [unused] */
981
982 {
983 /* on machines with no function keys...don't bother */
984 return(TRUE);
985 }
986 #endif
987 #else
sthello()988 sthello()
989 {
990 }
991 #endif
992