static char rcsid[] = "$Id: gemwind.c,v 1.10 1992/11/18 23:22:46 mike Exp $"; /* $Log: gemwind.c,v $ * Revision 1.10 1992/11/18 23:22:46 mike * - Cleaned up the stuff dealing with the DMA sound. Should work * correctely now on all ST/TT machines and with all TOS versions. * * Revision 1.9 1992/11/14 16:13:48 mike * - Fixed bug: `t_beep()' should work correctely on machines without * DMA sound hardware now. * * Revision 1.8 1992/11/10 21:55:02 mike * - The name of the resource file is `me2.rsc' when `NDEBUG' is * defined and `me2rsc.rsc' otherwise. * * Revision 1.7 1992/11/10 02:21:06 mike * - Some clean ups to prevent warnings from gcc. * * Revision 1.6 1992/11/08 23:11:40 mike * - Initialize `MCO_pathname' and `MUT_pathname' as well. * * Revision 1.5 1992/10/28 15:09:44 mike * - Set the value for `Bw.wkind' here, so it's accessible when `load_setup()' * is called. * * Revision 1.4 1992/10/28 00:25:32 mike * - Some minor fixes. * * Revision 1.3 1992/10/12 22:26:04 mike * - Discarded virtual workstation `Vw_clear'. It's job is done by * `Vw_print' now. * * Revision 1.2 1992/10/12 21:18:58 mike * - Lots'a changes ... * * Revision 1.1 1992/10/02 22:31:40 mike * Initial revision * */ /* * gemwind.c * * GEM window output routines for ME2. */ /* * Copyright 1992 by Michael Brandt * These are the termcap routines from tcap.c by Craig Durland * for the GEM environment. * Distributed under the terms of the GNU General Public License. * Distributed "as is", without warranties of any kind. */ /* Notes: * t_nrow: This is the number of rows on the display MINUS 1. The minus * 1 is to leave a row for the mini buffer. I don't know if this is a * good idea (because everybody has to remember another little detail) * but it has been that way forever and I don't think it would be worth * the gain to change it. */ #include #include #include #include #include "gem.h" #include "me2.h" #include "me2rsc.h" #include "stio.h" extern void display_resized(); extern void ttopen(); extern void ttclose(); int t_nrow; int t_ncol = 0; int tcolor = 0; int mcolor = 1; static int DMA_sound = 0; /* Do we have a DMA sound chip? */ static void init_sound(); /* Prepare the terminal for io. Save the old state. */ void t_open() { OSHEADER *os; char *rsc_file; int dummy; appl_init(); Phys_handle = graf_handle(&Wchar,&Hchar,&dummy,&dummy); #ifdef NDEBUG if ((rsc_file = pathfind("PATH","me2.rsc",":")) == NULL) #else if ((rsc_file = pathfind("PATH","me2rsc.rsc",":")) == NULL) #endif { form_alert(1, "[3][PANIC: Cannot find|resource file][Abort]"); appl_exit(); exit(1); } if (!rsrc_load(rsc_file)) { form_alert(1, "[3][PANIC: Cannot load|resource file][Abort]"); appl_exit(); exit(1); } rsrc_gaddr(R_TREE,RSC_MENU,&Menu); Bw.wkind = NAME | MOVER | INFO | FULLER | CLOSER | SIZER | UPARROW | DNARROW | VSLIDE; os = (OSHEADER *) get_sysvar(_sysbase); os = os->os_beg; TOS_version = os->os_version; strcpy(MC2,"mc2"); MCO_pathname[0] = MUT_pathname[0] = MC2_options[0] = '\0'; init_sound(); ttopen(); wind_update(BEG_UPDATE); wind_update(BEG_MCTRL); } /* Restore the terminal. */ void t_close() { ttclose(); wind_update(END_UPDATE); wind_update(END_MCTRL); rsrc_free(); if (TOS_version >= 0x104) wind_new(); appl_exit(); } /* move the cursor to (row,col) (zero relative). */ void t_move(row,col) int row, col; { Cursor_x = col * Wchar + Workx; Cursor_y = (row + 1) * Hchar + Worky - 1; } /* Clear from cursor to end of line. */ void t_eeol() { int pxyarray[4]; pxyarray[0] = Cursor_x; pxyarray[1] = Cursor_y; pxyarray[2] = Workx + Workw - 1; pxyarray[3] = Cursor_y - Hchar + 1; v_bar(Vw_print,pxyarray); } /* Clear from cursor to end of screen or just clear the screen. */ void t_eeop() { int pxyarray[4]; pxyarray[0] = Workx; pxyarray[1] = Worky; pxyarray[2] = Workx + Workw - 1; pxyarray[3] = Worky + Workh - 1; v_bar(Vw_print,pxyarray); Cursor_x = Workx; Cursor_y = Worky + Hchar - 1; } static char *Sound_mem = NULL; extern int Sound_size; extern char Sound_data[]; /* * See if we have a DMA sound chip. */ static void init_sound() { register long *p_cookie; short tt; /* * Machines with a DMA sound chip are equipped with TOS 1.06 at least. */ if (TOS_version < 0x106) return; p_cookie = (long *) get_sysvar(_p_cookies); if (p_cookie == NULL) return; tt = 0; while (*p_cookie) { if (*p_cookie == 0x5f534e44L /* '_SND' */ ) DMA_sound = p_cookie[1] & 1; else if (*p_cookie == 0x5f4d4348L /* '_MCH' */ ) tt = (p_cookie[1] & 0xffff0000L) == 0x20000L; p_cookie += 2; } if (tt) { /* * If this is a TT be sure to play the sound from the ST ram. */ if ((Sound_mem = (char * ) Mxalloc((long) Sound_size + 10, 0)) == 0L) { DMA_sound = 0; form_alert(1,"[3][Cannot allocate|sound memory][Ok]"); } else memcpy(Sound_mem,Sound_data,Sound_size); } else Sound_mem = Sound_data; } static void play_sample() { register unsigned short *base; register unsigned long p; base = (unsigned short *) 0xff8900L; p = (long) Sound_mem; base[3] = (p & 0xff); base[2] = (p & 0xff00) >> 8; base[1] = (p & 0xff0000) >> 16; p += Sound_size; base[9] = (p & 0xff); base[8] = (p & 0xff00) >> 8; base[7] = (p & 0xff0000) >> 16; base[16] = 129; /* Mono, 12517 Hz */ *base = 1; /* Go! */ } /* Honk the horn. beeper has the volume (0-100%). * If the terminal has visable bell set, sending it a BEL will cause * a flash and not a beep. */ void t_beep() { extern int beeper; if (beeper) { if (DMA_sound) Supexec(play_sample); else { Bconout(2,'\007'); return; } } } void setcolor(color,x) int color; int x; { int pxyarray[4]; pxyarray[0] = Workx; pxyarray[1] = Worky; pxyarray[2] = Workx + Workw - 1; pxyarray[3] = Worky + Workh - 1; switch (color) { case 0 : vst_effects(Vw_print,0); /* turn off bold text */ if (Clip_sem) return; vs_clip(Vw_print,0,pxyarray); break; case 1 : vst_effects(Vw_print,1); /* turn on bold text */ if (Clip_sem) return; vs_clip(Vw_print,1,pxyarray); } } /* * Ensure that the window with the given coordinates lies * completely within the bounds of the physical screen. */ void rc_constrain(x,y,w,h) int *x,*y; int w,h; { if (*x < Deskx) *x = Deskx; if (*y < Desky) *y = Desky; if ((*x + w) > (Deskx + Deskw)) *x = (Deskx + Deskw) - w; if ((*y + h) > (Desky + Deskh)) *y = (Desky + Deskh) - h; } /* * Change the size of the text window. */ void new_window_size(rows,cols) int rows; int cols; { static char title[32]; int x,y,w,h; Workw = cols * Wchar; if (Workw > Fullw) { cols = Fullw / Wchar; Workw = cols * Wchar; } Workh = rows * Hchar; if (Workh > Fullh) { rows = Fullh / Hchar; Workh = rows * Hchar; } wind_calc(WC_BORDER,Wkind,Workx,Worky,Workw,Workh,&x,&y,&w,&h); rc_constrain(&x,&y,w,h); wind_calc(WC_WORK,Wkind,x,y,w,h,&Workx,&Worky,&Workw,&Workh); wind_set(Text_window,WF_CURRXYWH,x,y,w,h); sprintf(title," Mutt Editor 2 (%dx%d) ",cols,rows); wind_set(Text_window,WF_NAME,title); display_resized(rows,cols); redraw_text_window(); } /* * Prepare the screen for a program to run in text mode. * save the GEM environment. */ void TOS_mode() { graf_mouse(M_OFF,NULL); Cursconf(1,0); Cursconf(2,0); Cconws("\033E"); } /* * Restore the GEM environment after a program run in text mode * terminated. */ void GEM_mode() { Cursconf(0,0); redraw_screen(); graf_mouse(ARROW,NULL); graf_mouse(M_ON,NULL); }