/* GEMFMALT.C 09/01/84 - 01/07/85 Lee Lorenzen */ /* CHANGED 02/19/85 - 02/23/85 Derek Mui */ /* Reg Opt 03/08/85 Derek Mui */ /* 1.1 03/21/85 - 05/11/85 Lowell Webster */ /* Modify fm_build to handle 6 resolutions 2/6/86 Derek Mui */ /* Change the mouse logic at fm_alert 3/5/86 Derek Mui */ /* Fix at fm_strbrk 3/16/87 - 3/17/87 Derek Mui */ /* Fix at fm_strbrk to allow 31 characters 4/8/87 Derek Mui */ /* Fix at fm_alert 4/9/87 Derek Mui */ /* Add more defines 11/23/87 D.Mui */ /* New rsc update 12/9/87 D.Mui */ /* Change fm_alert to make alert box moves 11/6/90 D.Mui */ /* Changed fm_build and fm_alert to build 3d buttons 7/16/92 D.Mui */ /* Convert to Lattice C 5.51 2/17/93 C.Gee */ /* Force the use of prototypes 2/24/93 C.Gee */ /* ----------------------------------------------------------- * AES Version 4.0 MultiTOS version is written by Derek M. Mui * Copyright (C) 1992 * Atari (U.S.) Corp * All Rights Reserved * ----------------------------------------------------------- */ /* * ------------------------------------------------------------- * GEM Application Environment Services Version 1.1 * Serial No. XXXX-0000-654321 All Rights Reserved * Copyright (C) 1985 Digital Research Inc. * ------------------------------------------------------------- */ #include "pgem.h" #include "pmisc.h" #include "machine.h" #include "objaddr.h" #include "rslib.h" #include "osbind.h" #include "mintbind.h" #include "gemusa.h" #define MAX_MSGS 5 #define MAX_BTNS 3 #define MSG_OFF 2 #define BUT_OFF 7 #define NUM_ALOBJS 10 #define NUM_ALSTRS 8 #define MAX_MSGLEN 30 /* changed */ #define INTER_WSPACE 2 #define INTER_HSPACE 0 EXTERN WS gl_ws; EXTERN UWORD gl_alrtcol; EXTERN PD *errpd; EXTERN FDB gl_tmp; EXTERN FDB gl_crit; EXTERN GRECT gl_rcenter; EXTERN WORD gl_mouse; EXTERN LONG ad_sysglo; EXTERN LONG ad_armice; EXTERN WORD gl_hbox; EXTERN WORD gl_hchar; EXTERN WORD gl_wchar; EXTERN WORD gl_width; EXTERN WORD gl_ncols; EXTERN WORD gl_moff; /* CHANGED 5/10 LKW */ EXTERN GRECT gl_rscreen; EXTERN PD *currpd; EXTERN WORD gl_xrat; EXTERN WORD gl_yrat; EXTERN WORD gl_button; OBJECT *critobj[MAXERR]; /* critical error objects */ GLOBAL BYTE gl_nils[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; GLOBAL WORD ml_alrt[MAXERR] = {ALRT00CR,ALRT01CR,ALRT02CR,ALRT03CR,ALRT04CR, ALRT05CR, ALRTDSWA, ALRTINSS }; MLOCAL WORD ml_ted[MAXERR] = { A00,A01,A02,A03,-1,-1,A06,-1 }; GLOBAL WORD tmpmoff; GLOBAL WORD tmpmon; GLOBAL WORD gl_incerr; /* set to "1" when we are in the critical error handler */ GRECT al_grect; /* for form alert */ WORD al_center; /* * Routine to break a string into smaller strings. Breaks occur * whenever an | or a ] is encountered. */ VOID fm_strbrk(tree, palstr, stroff, pcurr_id, pnitem, pmaxlen) LONG tree; LONG palstr; WORD stroff; WORD *pcurr_id; WORD *pnitem; WORD *pmaxlen; { REG WORD nitem, curr_id; REG WORD len, maxlen; REG BYTE tmp; LONG pstr; WORD nxttmp; nitem = maxlen = 0; curr_id = *pcurr_id; tmp = NULL; while( tmp != ']') { pstr = LLGET(OB_SPEC(stroff + nitem)); len = 0; do { tmp = LBGET(palstr + curr_id); if ( len >= 31 ) { LBSET(pstr + len, NULL); tmp = NULL; while( TRUE ) { tmp = LBGET(palstr + curr_id); if ( ( tmp != ']' ) && ( tmp != '|' ) ) { curr_id++; continue; } else break; } } curr_id++; nxttmp = LBGET(palstr + curr_id); if ( (tmp == ']') || (tmp == '|') ) { if (tmp == nxttmp) { if ( len < 31 ) curr_id++; else tmp = NULL; } else { nxttmp = tmp; tmp = NULL; } } LBSET(pstr + len, tmp); len++; } while( tmp != NULL ); tmp = nxttmp; maxlen = max(len - 1, maxlen); nitem++; } *pcurr_id = curr_id; *pnitem = nitem; *pmaxlen = maxlen; } /* * Routine to parse a string into an icon #, multiple message * strings, and multiple button strings. For example, * * [0][This is some text|for the screen.][Ok|Cancel] * 0123456 * * becomes: * icon# = 0; * 1st msg line = This is some text * 2nd msg line = for the screen. * 1st button = Ok * 2nd button = Cancel */ VOID fm_parse(tree, palstr, picnum, pnummsg, plenmsg, pnumbut, plenbut) LONG tree; REG LONG palstr; WORD *picnum; WORD *pnummsg, *plenmsg; WORD *pnumbut, *plenbut; { WORD curr_id; *picnum = LBGET(palstr + 1) - '0'; curr_id = 4; fm_strbrk(tree, palstr, MSG_OFF, &curr_id, pnummsg, plenmsg); curr_id++; fm_strbrk(tree, palstr, BUT_OFF, &curr_id, pnumbut, plenbut); *plenbut += 1; } VOID fm_build(tree, haveicon, nummsg, mlenmsg, numbut, mlenbut) REG LONG tree; WORD haveicon; WORD nummsg, mlenmsg; WORD numbut, mlenbut; { REG WORD i,j; GRECT al, ic; GRECT bt, ms; WORD icw,ich; /* define the icw and ich at here please */ #if 0 icw = 4; ich = 4; #else icw = (31+gl_wchar)/gl_wchar; ich = (31+gl_hchar)/gl_hchar; #endif i = (mlenbut * numbut) + ( (numbut-1) * 2 ); i = max( i, mlenmsg ); /* find the max char length */ /* find the max char height */ j = max( nummsg, 1 ); r_set( ( WORD *)&al, 0x0, 0x0, i+2, j); /* this is the alert box */ /* this is the message object */ r_set( ( WORD *)&ms, 2, 0x0300, mlenmsg, 1); if (haveicon) { r_set( ( WORD *)&ic, 1, 1, icw, ich); al.g_w += icw + 1; al.g_h = max( al.g_h, 1 + ich ); ms.g_x += icw; } al.g_h += 3; /* center the buttons */ i = (al.g_w - ( (numbut - 1) * 2 ) - (mlenbut * numbut)) / 2; /* set the button */ r_set( ( WORD *)&bt, i, al.g_h - 2, mlenbut, 1 ); /* now make the al.g_h smaller */ /* al.g_h -= 1; al.g_h += ( (gl_hchar/2) << 8 ); */ ob_setxywh(tree, ROOT, &al); for(i=0; ip_name ); Debug1( "calls Fm_alert\r\n" ); wm_update( 3 ); /* init tree pointer */ rs_gaddr(ad_sysglo, R_TREE, ALERT, ( LONG *)&addr); tree = ( LONG )addr; spec = LLGET( OB_SPEC(ROOT) ); spec &= 0xFFFFFF80L; spec |= 0x70L; /* was 0x40 (dithered) */ if ( gl_alrtcol >= gl_ws.ws_ncolors ) color = WHITE; else color = gl_alrtcol; spec |= ( color & 0x000F ); LLSET( OB_SPEC(ROOT), spec ); bheight = LWGET( OB_HEIGHT(BUT_OFF) ); LWSET( OB_FLAGS( 0 ), TOUCHEXIT | IS3DACT); LWSET( OB_TYPE( 1 ), G_CICON ); rs_gaddr( ad_sysglo, R_TREE, CICONS, (LONG *)&cicons ); LLSET( OB_SPEC( 1 ), cicons[NOTECC].ob_spec ); LWSET(OB_STATE(ROOT), OUTLINED); fm_parse(tree, palstr, &inm, &nummsg, &mlenmsg, &numbut, &mlenbut); fm_build(tree, (inm != 0), nummsg, mlenmsg, numbut, mlenbut); if (defbut) { plong = OB_FLAGS(BUT_OFF + defbut - 1); LWSET(plong, LWGET(plong) | DEFAULT); } if (inm != 0) { LLSET(OB_SPEC(1), cicons[inm].ob_spec ); } /* convert to pixels */ for(i=0; i 0 && i < BUT_OFF) /* object 0's is made TOUCHEXIT above */ LWSET( OB_FLAGS(i), TOUCHEXIT ); rs_obfix(tree, i); } /* LWSET(OB_WIDTH(1), 32); */ /* LWSET(OB_HEIGHT(1), 32); */ LLSET( OB_WIDTH(1), 0x00200020L ); /* fixed 7/16/92 */ for( i=0; i<3; i++ ) LWSET( OB_HEIGHT(BUT_OFF+i), bheight ); if ( !defbut ) defbut = 1; ob_gclip( tree, BUT_OFF + defbut - 1, &x1, &y1, &x, &y, &w, &h ); y = y - LWGET( OB_Y(0) ); y += h + 2; LWSET(OB_HEIGHT(ROOT), y ); /* center tree on screen*/ r_set( ( WORD *)&f, 0, gl_hbox, gl_rscreen.g_w, gl_rscreen.g_h-gl_hbox ); ob_center(tree, &m); if ( !al_center ) /* not center alert */ { m.g_x = al_grect.g_x; m.g_y = al_grect.g_y; rc_constrain( &f, &m ); addr->ob_x = m.g_x + 3; addr->ob_y = m.g_y + 3; } /* save screen under- */ /* neath the alert */ wm_update( 1 ); /* This was commented out: why? */ gsx_gclip( &t ); /* save the old clip */ gsx_moff(); bb_save( &m ); gsx_mon(); /* draw the alert */ gsx_sclip(&m); ob_draw(tree, ROOT, MAX_DEPTH); /* let user pick button */ moved = FALSE; state = currpd->p_state; ctlmouse( 1 ); /* turn on the mouse */ for(;;) { i = fm_do( tree, 0 ) & 0x7fff; if (i >= BUT_OFF ) break; gr_dragbox( m.g_w, m.g_h, m.g_x, m.g_y, &f, &x, &y ); if ( ( m.g_x == x ) && ( m.g_y == y ) ) continue; moved = TRUE; bb_restore( &m ); m.g_x = x; m.g_y = y; LWSET( OB_X(0), x+3 ); LWSET( OB_Y(0), y+3 ); bb_save( &m ); ob_draw(tree, ROOT, MAX_DEPTH); } currpd->p_state = state; gsx_sclip( &m ); gsx_moff(); bb_restore( &m ); /* restore saved screen */ gsx_mon(); gsx_sclip( &t ); /* restore clip rect */ ctlmouse ( 0 ); /* back to the way it was */ wm_update( 0 ); /* This was commented out: why? */ if ( moved ) { al_center = FALSE; al_grect.g_x = m.g_x; al_grect.g_y = m.g_y; } wm_update( 2 ); return( i - BUT_OFF + 1 ); /* return selection */ } /* AES Critical error handler */ WORD eralert( n, d ) WORD n; /* n = alert #, 0-5 */ WORD d; /* d = drive code, 0=A */ { WORD *pdrive_let; WORD drive_let; WORD ret, oldret; GRECT t,m; OBJECT *obj; FDB tmp; PD *p; p = currpd; currpd = errpd; gl_incerr = 1; /* remember that we're in a critical error handler */ ctlmouse( 1 ); pdrive_let = &drive_let; drive_let = ( d + 'A' ) << 8; /* make it a 2 char string! */ gsx_gclip( &t ); /* * Kludge for MultiTOS on single floppy, no hard drive systems; * if the error alert is the "Please insert disk B: into drive A:" * one, and it's not for a floppy, then we change it to * "Please insert system disk into drive A:". */ if (n == MAXERR-2 && d > 1) { n = MAXERR-1; } obj = critobj[n]; if ( ml_ted[n] != -1 ) /* set the drive name */ inf_sset( ( LONG )obj, ml_ted[n], ( BYTE *)pdrive_let ); ob_center( ( LONG )obj, &m ); tmp = gl_tmp; /* save old blt buffer */ gl_tmp = gl_crit; bb_save( &m ); gsx_sclip( &m ); ob_draw( ( LONG )obj, ROOT, MAX_DEPTH ); do { if ( gl_button & 0x01 ) { ret = ob_find( ( LONG )obj, 0, MAX_DEPTH, gl_xrat, gl_yrat ); if ( ret != -1 ) { if ( obj[ret].ob_flags & EXIT ) { obj[ret].ob_state |= SELECTED; ob_draw( (LONG)obj, ret, MAX_DEPTH ); oldret = ret; do { ret = ob_find( (LONG)obj, 0, MAX_DEPTH, gl_xrat, gl_yrat ); } while (gl_button != 0 && oldret == ret); obj[oldret].ob_state &= ~SELECTED; ob_draw( (LONG)obj, oldret, MAX_DEPTH ); if (ret == oldret && (obj[ret].ob_flags & EXIT)) { ret = ( obj[ret].ob_flags & DEFAULT ) ? 1 : 0; break; } } } } else { #if 1 /* we have to use the BIOS, because GEMDOS isn't re-entrant. Fortunately, * this works even under MiNT, because MiNT restores the "native" BIOS * trap while it is inside of GEMDOS. Otherwise, BIOS I/O would be coming * from the AES_BIOS device under MiNT, which would be real bad news. * If MiNT ever changes this, you may have to change the "#if 1" above to * a "#if 0". */ if ( Bconstat( 2 ) == -1 ) { if ( ( Bconin( 2 ) & 0x00ff ) == 0x0D ) { ret = 1; break; } } #else /* see comment above */ if ( (newchkkbd() & 0x00ff) == 0x0D ) { ret = 1; break; } #endif } }while( 1 ); bb_restore( &m ); gl_tmp = tmp; gsx_sclip( &t ); gl_incerr = 0; ctlmouse(0); currpd = p; return( ret ); /* 1 retry 0 cancel */ } WORD fm_error(n) WORD n; /* n = dos error number */ { REG WORD string; WORD ret; ret = FALSE; if ( n > 63 ) /* nothing for xtal errors */ return( ret ); switch (n) { case 2: /* file not found */ case 18: /* no more files */ case 3: /* path not found */ string = ALRT18ER; break; case 4: /* too many open files */ string = ALRT04ER; break; case 5: /* access denied */ string = ALRT05ER; break; case 8: /* insufficient memory */ case 10: /* invalid environmeny */ case 11: /* invalid format */ string = ALRT08ER; break; case 15: /* invalid drive */ string = ALRT15ER; break; case 35: /* bad executable */ string = ALRT35ER; break; default: string = ALRTXXER; } ret = fm_show(string, (string == ALRTXXER) ? (UWORD *)&n : (UWORD *)0, 1 ); return( ret != 1 ); } /* * New routine to force arrow mouse and show * mouse when it is over an alert box * 6/12/92 */ VOID ctlmouse( mon ) WORD mon; { if ( mon ) { gr_mouse( M_ARROW|0xC000, ( MFORM *)0L ); tmpmon = gl_mouse; /* save the mouse on flag */ tmpmoff = gl_moff; while( gl_moff ) gsx_mon(); /* gsx_1code( SHOW_CUR, 0 ); */ /* force the mouse on */ /* gl_mouse = TRUE; */ /* gl_moff = 0; */ /* reset the flag to make bbset work */ } else { while( tmpmoff-- ) gsx_moff(); /* gl_mouse = tmpmon; */ /* gl_moff = tmpmoff; */ /* gr_mouse( M_RESTORE, (BYTE*)0 ); */ } }