/* * perform window untopping: send WM_UNTOPPED message to window owner, * wait for button up, then dispatch any waiting gem processes */ static void perform_untop(WORD wh) { WORD i; /* send msg, wait for button up */ ct_msgup(WM_UNTOPPED, D.w_win[wh].w_owner, wh, 0, 0, 0, 0); for (i = 0; i < num_accs; i++) dsptch(); }
/* * Supervisor entry point. Stack frame must be exactly like * this if supret is to work. */ WORD super(WORD cx, LONG pcrys_blk) { if (cx == 200) xif(pcrys_blk); if ((dspcnt++ % 8) == 0 || cx == 201) dsptch(); return 0; }
/* * Internal process context used to control the screen for use by * the menu manager, and the window manager. * This process never terminates and forms an integral part of * the system. */ void ctlmgr(void) { WORD ev_which; WORD rets[6]; WORD i, wh; /* * set defaults for multi wait */ gl_ctwait.m_out = FALSE; rc_copy(&gl_rmenu, (GRECT *)&gl_ctwait.m_x); while(TRUE) { /* fix up ctrl rect */ w_setactive(); /* * wait for something to happen, keys need to be eaten * inc. fake key sent by ... or if button already down, * then let other guys run then do it */ if (button) { for (i = 0; i < (totpds*2); i++) dsptch(); ev_which = MU_BUTTON; rets[0] = xrat; rets[1] = yrat; } else { ev_which = MU_KEYBD | MU_BUTTON; if ( gl_mntree != 0x0L ) /* only wait on bar when there */ ev_which |= MU_M1; /* is a menu */ ev_which = ev_multi(ev_which, &gl_ctwait, &gl_ctwait, 0x0L, 0x0001ff01L, 0x0L, rets); } ct_mouse(TRUE); /* grab screen sink */ /* * button down over area ctrl mgr owns. find out which * window the mouse clicked over and handle it */ if (ev_which & MU_BUTTON) { wh = wm_find(rets[0], rets[1]); if (wh > 0) hctl_window( wh, rets[0], rets[1] ); } /* mouse over menu bar */ if (ev_which & MU_M1) hctl_rect(); ct_mouse(FALSE); /* give up screen sink */ } }
/* * Give everyone a chance to run, at least once */ void all_run(void) { WORD i; /* let all the acc's run*/ for(i=0; i<NUM_ACCS; i++) { dsptch(); } /* then get in the wait line */ wm_update(TRUE); wm_update(FALSE); }
/* * Send message and wait for the mouse button to come up */ static void ct_msgup(WORD message, AESPD *owner, WORD wh, WORD m1, WORD m2, WORD m3, WORD m4) { if (message == 0) return; ap_sendmsg(appl_msg, message, owner, wh, m1, m2, m3, m4); /* * wait for button to come up if not an arrowed message */ if ( message != WM_ARROWED && ( message != WM_CLOSED && !(D.w_win[wh].w_kind & HOTCLOSE) ) ) { while( (button & 0x0001) != 0x0 ) dsptch(); } }
/* * Routine to watch the mouse while the button is down and * it stays inside/outside of the specified rectangle. * Return TRUE as long as the mouse is down. Block until the * mouse moves into or out of the specified rectangle. */ static WORD gr_stilldn(WORD out, WORD x, WORD y, WORD w, WORD h) { WORD rets[6]; MOBLK tmpmoblk; WORD which; dsptch(); tmpmoblk.m_out = out; tmpmoblk.m_x = x; tmpmoblk.m_y = y; tmpmoblk.m_w = w; tmpmoblk.m_h = h; which = ev_multi(MU_KEYBD | MU_BUTTON | MU_M1, &tmpmoblk, NULLPTR, 0x0L, 0x0001ff00L, 0x0L, &rets[0]); if ( which & MU_BUTTON ) return(FALSE); return(TRUE); } /* gr_stilldn */
void gem_main(void) { WORD i; const BITBLK *tmpadbi; sh_rdinf(); /* get start of emudesk.inf */ if (!gl_changerez) /* can't be here because of rez change, */ process_inf1(); /* so see if .inf says we need to change rez */ if (gl_changerez) { switch(gl_changerez) { #if CONF_WITH_SHIFTER case 1: /* ST(e) or TT display */ Setscreen(-1L,-1L,gl_nextrez-2,0); initialise_palette_registers(gl_nextrez-2,0); break; #endif #if CONF_WITH_VIDEL case 2: /* Falcon display */ Setscreen(-1L, -1L, FALCON_REZ, gl_nextrez); initialise_palette_registers(FALCON_REZ,gl_nextrez); break; #endif } gsx_wsclear(); /* avoid artefacts that may show briefly */ } totpds = NUM_PDS; ml_ocnt = 0; gl_changerez = FALSE; ini_dlongs(); /* init longs */ cli(); takecpm(); /* take the 0efh int. */ /* init event recorder */ gl_recd = FALSE; gl_rlen = 0; gl_rbuf = 0x0L; /* initialize pointers to heads of event list and thread list */ elinkoff = (BYTE *) &(D.g_intevb[0].e_link) - (BYTE *) &(D.g_intevb[0]); /* link up all the evb's to the event unused list */ eul = NULLPTR; ev_init(&D.g_intevb[0], NUM_IEVBS); if (totpds > 2) ev_init(&D.g_extevb[0], NUM_EEVBS); /* initialize sync blocks */ wind_spb.sy_tas = 0; wind_spb.sy_owner = NULLPTR; wind_spb.sy_wait = 0; /* * init processes - TODO: should go in gempd or gemdisp. */ /* initialize list and unused lists */ nrl = drl = NULLPTR; dlr = zlr = NULLPTR; fph = fpt = fpcnt = 0; /* init initial process */ for(i=totpds-1; i>=0; i--) { rlr = pd_index(i); if (i < 2) { rlr->p_uda = &D.g_intuda[i]; rlr->p_cda = &D.g_intcda[i]; } else { rlr->p_uda = &D.g_extuda[i-2]; rlr->p_cda = &D.g_extcda[i-2]; } rlr->p_qaddr = (LONG)(&rlr->p_queue[0]); rlr->p_qindex = 0; memset(rlr->p_name, ' ', 8); rlr->p_appdir[0] = '\0'; /* by default, no application directory */ /* if not rlr then initialize his stack pointer */ if (i != 0) rlr->p_uda->u_spsuper = &rlr->p_uda->u_supstk; rlr->p_pid = i; rlr->p_stat = 0; } curpid = 0; rlr->p_pid = curpid++; rlr->p_link = NULLPTR; /* end of process init */ /* restart the tick */ sti(); /* * screen manager process init. this process starts out owning the mouse * and the keyboard. it has a pid == 1 */ gl_dacnt = 0; gl_mowner = ctl_pd = iprocess("SCRENMGR", ctlmgr); /* load gem resource and fix it up before we go */ gem_rsc_init(); { /* get mice forms */ ad_armice = *(LONG *)&rs_bitblk[MICE00]; ad_hgmice = *(LONG *)&rs_bitblk[MICE02]; /* init button stuff */ gl_btrue = 0x0; gl_bdesired = 0x0; gl_bdely = 0x0; gl_bclick = 0x0; gl_logdrv = dos_gdrv() + 'A'; /* boot directory */ gsx_init(); /* do gsx open work station */ /* load all desk acc's */ if (totpds > 2) ldaccs(); /* fix up icons */ for(i=0; i<3; i++) { tmpadbi = &rs_bitblk[NOTEBB+i]; memcpy((char *)&bi, tmpadbi, sizeof(BITBLK)); gsx_trans(bi.bi_pdata, bi.bi_wb, bi.bi_pdata, bi.bi_wb, bi.bi_hl); } /* take the critical err handler int. */ cli(); takeerr(); sti(); /* go into graphic mode */ sh_tographic(); /* take the tick int. */ cli(); gl_ticktime = gsx_tick(tikaddr, &tiksav); sti(); /* set init. click rate: must do this after setting gl_ticktime */ ev_dclick(3, TRUE); /* fix up the GEM rsc. file now that we have an open WS */ gem_rsc_fixit(); /* get st_desk ptr */ ad_stdesk = (LONG) rs_trees[DESKTOP]; /* init. window vars. */ wm_start(); /* startup gem libs */ fs_start(); /* remember current desktop directory */ sh_curdir(D.s_cdir); /* process emudesk.inf part 2 */ process_inf2(); /* off we go !!! */ dsptch(); /* let them run */ all_run(); /* * init for shell loop up thru here it is okay for system to * overlay this initialization code */ sh_init(); /* * main shell loop. From here on down data should not overlay * this code */ sh_main(); /* give back the tick */ cli(); gl_ticktime = gsx_tick(tiksav, &tiksav); sti(); /* close workstation */ gsx_wsclose(); } /* return GEM's 0xEF int*/ cli(); givecpm(); sti(); }
/* * This function is called from accdesk_start (in gemstart.S) which * is itself called from gem_main() below. * * It runs under a separate process which terminates on shutdown or * resolution change (see accdesk_start). This ensures that all * memory allocated to or by desk accessories is automatically freed * on resolution change. */ void run_accs_and_desktop(void) { WORD i; BOOL isgem; /* load gem resource and fix it up before we go */ gem_rsc_init(); /* get mice forms */ ad_armice = (MFORM *)rs_bitblk[MICE00].bi_pdata; ad_hgmice = (MFORM *)rs_bitblk[MICE02].bi_pdata; /* init button stuff */ gl_btrue = 0x0; gl_bdesired = 0x0; gl_bdely = 0x0; gl_bclick = 0x0; gl_logdrv = dos_gdrv() + 'A'; /* boot directory */ gsx_init(); /* do gsx open work station */ load_accs(num_accs); /* load up to 'num_accs' desk accessories */ /* fix up icons */ for (i = 0; i < 3; i++) { memcpy(&bi, &rs_bitblk[NOTEBB+i], sizeof(BITBLK)); gsx_trans(bi.bi_pdata, bi.bi_wb, bi.bi_pdata, bi.bi_wb, bi.bi_hl); } /* take the critical err handler int. */ disable_interrupts(); takeerr(); enable_interrupts(); sh_tographic(); /* go into graphic mode */ /* take the tick interrupt */ disable_interrupts(); gl_ticktime = gsx_tick(tikaddr, &tiksav); enable_interrupts(); /* set initial click rate: must do this after setting gl_ticktime */ ev_dclick(3, TRUE); /* fix up the GEM rsc file now that we have an open WS */ gem_rsc_fixit(); wm_start(); /* initialise window vars */ fs_start(); /* startup gem libs */ sh_curdir(D.s_cdir); /* remember current desktop directory */ isgem = process_inf2(); /* process emudesk.inf part 2 */ dsptch(); /* off we go !!! */ all_run(); /* let them run */ sh_init(); /* init for shell loop */ sh_main(isgem); /* main shell loop */ /* give back the tick */ disable_interrupts(); gl_ticktime = gsx_tick(tiksav, &tiksav); enable_interrupts(); /* close workstation */ gsx_wsclose(); }
static UWORD crysbind(WORD opcode, LONG pglobal, WORD control[], WORD int_in[], WORD int_out[], LONG addr_in[]) { LONG maddr; LONG tree; WORD mouse, ret; WORD unsupported = FALSE; maddr = 0; ret = TRUE; switch(opcode) { /* Application Manager */ case APPL_INIT: #if DBG_GEMSUPER aestrace("appl_init()"); #endif LWSET(pglobal, AES_VERSION); /* version number */ LWSET(pglobal+2, 0x0001); /* num of concurrent procs*/ /* LLSET(pglobal, 0x00010200L); */ LWSET(pglobal+4, rlr->p_pid); sh_deskf(0, pglobal+6); LWSET(pglobal+20, gl_nplanes); LLSET(pglobal+22, ADDR(&D)); /* reset dispatcher */ /* count to let the app*/ /* run a while. */ dspcnt = 0; ret = ap_init(); break; case APPL_READ: case APPL_WRITE: ap_rdwr(opcode == APPL_READ ? MU_MESAG : MU_SDMSG, fpdnm(NULLPTR, AP_RWID), AP_LENGTH, AP_PBUFF); break; case APPL_FIND: ret = ap_find( AP_PNAME ); break; case APPL_TPLAY: ap_tplay(AP_TBUFFER, AP_TLENGTH, AP_TSCALE); break; case APPL_TRECORD: ret = ap_trecd(AP_TBUFFER, AP_TLENGTH); break; #if CONF_WITH_PCGEM case APPL_YIELD: dsptch(); break; #endif case APPL_EXIT: #if DBG_GEMSUPER aestrace("appl_exit()"); #endif ap_exit(); break; /* Event Manager */ case EVNT_KEYBD: ret = ev_block(MU_KEYBD, 0x0L); break; case EVNT_BUTTON: ret = ev_button(B_CLICKS, B_MASK, B_STATE, &EV_MX); break; case EVNT_MOUSE: ret = ev_mouse((MOBLK *)&MO_FLAGS, &EV_MX); break; case EVNT_MESAG: #if DBG_GEMSUPER aestrace("evnt_mesag()"); #endif ap_rdwr(MU_MESAG, rlr, 16, ME_PBUFF); break; case EVNT_TIMER: ev_timer( HW(T_HICOUNT) + LW(T_LOCOUNT) ); break; case EVNT_MULTI: #if DBG_GEMSUPER aestrace("evnt_multi()"); #endif if (MU_FLAGS & MU_TIMER) maddr = HW(MT_HICOUNT) + LW(MT_LOCOUNT); tree = HW(MB_CLICKS) | LW((MB_MASK << 8) | MB_STATE); ret = ev_multi(MU_FLAGS, (MOBLK *)&MMO1_FLAGS, (MOBLK *)&MMO2_FLAGS, maddr, tree, MME_PBUFF, &EV_MX); break; case EVNT_DCLICK: ret = ev_dclick(EV_DCRATE, EV_DCSETIT); break; /* Menu Manager */ case MENU_BAR: if (gl_mnppd == rlr || gl_mnppd == NULL) mn_bar(MM_ITREE, SHOW_IT, rlr->p_pid); else menu_tree[rlr->p_pid] = (SHOW_IT) ? MM_ITREE : 0x0L; break; case MENU_ICHECK: do_chg(MM_ITREE, ITEM_NUM, CHECKED, CHECK_IT, FALSE, FALSE); break; case MENU_IENABLE: do_chg(MM_ITREE, (ITEM_NUM & 0x7fff), DISABLED, !ENABLE_IT, ((ITEM_NUM & 0x8000) != 0x0), FALSE); break; case MENU_TNORMAL: if (gl_mntree == menu_tree[rlr->p_pid]) do_chg(MM_ITREE, TITLE_NUM, SELECTED, !NORMAL_IT, TRUE, TRUE); break; case MENU_TEXT: tree = MM_ITREE; strcpy((char *)LLGET(OB_SPEC(ITEM_NUM)), (char *)MM_PTEXT); break; case MENU_REGISTER: ret = mn_register(MM_PID, MM_PSTR); break; case MENU_UNREGISTER: #if CONF_WITH_PCGEM /* distinguish between menu_unregister() and menu_popup() */ if (IN_LEN == 1) mn_unregister( MM_MID ); else #endif unsupported = TRUE; break; case MENU_CLICK: /* distinguish between menu_click() and menu_attach() */ /* * although menu_click() is PC-GEM only, it's always * enabled because the desktop uses it. */ if (IN_LEN == 2) { if (MN_SETIT) gl_mnclick = MN_CLICK; ret = gl_mnclick; } else unsupported = TRUE; break; /* Object Manager */ case OBJC_ADD: ob_add(OB_TREE, OB_PARENT, OB_CHILD); break; case OBJC_DELETE: ob_delete(OB_TREE, OB_DELOB); break; case OBJC_DRAW: gsx_sclip((GRECT *)&OB_XCLIP); ob_draw(OB_TREE, OB_DRAWOB, OB_DEPTH); break; case OBJC_FIND: ret = ob_find(OB_TREE, OB_STARTOB, OB_DEPTH, OB_MX, OB_MY); break; case OBJC_OFFSET: ob_offset(OB_TREE, OB_OBJ, &OB_XOFF, &OB_YOFF); break; case OBJC_ORDER: ob_order(OB_TREE, OB_OBJ, OB_NEWPOS); break; case OBJC_EDIT: gsx_sclip(&gl_rfull); OB_ODX = OB_IDX; ret = ob_edit(OB_TREE, OB_OBJ, OB_CHAR, &OB_ODX, OB_KIND); break; case OBJC_CHANGE: gsx_sclip((GRECT *)&OB_XCLIP); ob_change(OB_TREE, OB_DRAWOB, OB_NEWSTATE, OB_REDRAW); break; /* Form Manager */ case FORM_DO: ret = fm_do(FM_FORM, FM_START); break; case FORM_DIAL: ret = fm_dial(FM_TYPE, (GRECT *)&FM_X); break; case FORM_ALERT: ret = fm_alert(FM_DEFBUT, FM_ASTRING); break; case FORM_ERROR: ret = fm_error(FM_ERRNUM); break; case FORM_CENTER: ob_center(FM_FORM, (GRECT *)&FM_XC); break; case FORM_KEYBD: gsx_sclip(&gl_rfull); FM_OCHAR = FM_ICHAR; FM_ONXTOB = FM_INXTOB; ret = fm_keybd(FM_FORM, FM_OBJ, &FM_OCHAR, &FM_ONXTOB); break; case FORM_BUTTON: gsx_sclip(&gl_rfull); ret = fm_button(FM_FORM, FM_OBJ, FM_CLKS, &FM_ONXTOB); break; /* Graphics Manager */ case GRAF_RUBBOX: gr_rubbox(GR_I1, GR_I2, GR_I3, GR_I4, &GR_O1, &GR_O2); break; case GRAF_DRAGBOX: gr_dragbox(GR_I1, GR_I2, GR_I3, GR_I4, (GRECT *)&GR_I5, &GR_O1, &GR_O2); break; case GRAF_MBOX: gr_movebox(GR_I1, GR_I2, GR_I3, GR_I4, GR_I5, GR_I6); break; case GRAF_GROWBOX: gr_growbox((GRECT *)&GR_I1, (GRECT *)&GR_I5); break; case GRAF_SHRINKBOX: gr_shrinkbox((GRECT *)&GR_I1, (GRECT *)&GR_I5); break; case GRAF_WATCHBOX: ret = gr_watchbox(GR_TREE, GR_OBJ, GR_INSTATE, GR_OUTSTATE); break; case GRAF_SLIDEBOX: ret = gr_slidebox(GR_TREE, GR_PARENT, GR_OBJ, GR_ISVERT); break; case GRAF_HANDLE: GR_WCHAR = gl_wchar; GR_HCHAR = gl_hchar; GR_WBOX = gl_wbox; GR_HBOX = gl_hbox; ret = gl_handle; break; case GRAF_MOUSE: if (GR_MNUMBER > 255) { if (GR_MNUMBER == M_OFF) gsx_moff(); if (GR_MNUMBER == M_ON) gsx_mon(); } else { if (GR_MNUMBER != 255) { switch(GR_MNUMBER) { case 1: mouse = MICE01; break; case 2: mouse = MICE02; break; case 3: mouse = MICE03; break; case 4: mouse = MICE04; break; case 5: mouse = MICE05; break; case 6: mouse = MICE06; break; case 7: mouse = MICE07; break; default: mouse = MICE00; break; } maddr = *(LONG *) &rs_bitblk[mouse]; } else maddr = GR_MADDR; gsx_mfset(maddr); } break; case GRAF_MKSTATE: gr_mkstate(&GR_MX, &GR_MY, &GR_MSTATE, &GR_KSTATE); break; /* Scrap Manager */ case SCRP_READ: ret = sc_read((BYTE*)SC_PATH); break; case SCRP_WRITE: ret = sc_write((const BYTE*)SC_PATH); break; #if CONF_WITH_PCGEM case SCRP_CLEAR: ret = sc_clear(); break; #endif /* File Selector Manager */ case FSEL_INPUT: ret = fs_input((BYTE*)FS_IPATH, (BYTE*)FS_ISEL, &FS_BUTTON, NULL); break; case FSEL_EXINPUT: ret = fs_input((BYTE*)FS_IPATH, (BYTE*)FS_ISEL, &FS_BUTTON, (BYTE *)FS_ILABEL); break; /* Window Manager */ case WIND_CREATE: ret = wm_create(WM_KIND, (GRECT *)&WM_WX); break; case WIND_OPEN: wm_open(WM_HANDLE, (GRECT *)&WM_WX); break; case WIND_CLOSE: wm_close(WM_HANDLE); break; case WIND_DELETE: wm_delete(WM_HANDLE); break; case WIND_GET: wm_get(WM_HANDLE, WM_WFIELD, &WM_OX); break; case WIND_SET: wm_set(WM_HANDLE, WM_WFIELD, &WM_IX); break; case WIND_FIND: ret = wm_find(WM_MX, WM_MY); break; case WIND_UPDATE: wm_update(WM_BEGUP); break; case WIND_CALC: wm_calc(WM_WCTYPE, WM_WCKIND, WM_WCIX, WM_WCIY, WM_WCIW, WM_WCIH, &WM_WCOX, &WM_WCOY, &WM_WCOW, &WM_WCOH); break; case WIND_NEW: wm_new(); break; /* Resource Manager */ case RSRC_LOAD: ret = rs_load(pglobal, RS_PFNAME); break; case RSRC_FREE: ret = rs_free(pglobal); break; case RSRC_GADDR: ret = rs_gaddr(pglobal, RS_TYPE, RS_INDEX, &ad_rso); break; case RSRC_SADDR: ret = rs_saddr(pglobal, RS_TYPE, RS_INDEX, RS_INADDR); break; case RSRC_OBFIX: rs_obfix(RS_TREE, RS_OBJ); break; /* Shell Manager */ case SHEL_READ: sh_read((BYTE*)SH_PCMD, (BYTE*)SH_PTAIL); break; case SHEL_WRITE: ret = sh_write(SH_DOEX, SH_ISGR, SH_ISCR, (const BYTE*)SH_PCMD, (const BYTE*)SH_PTAIL); break; case SHEL_GET: sh_get((void*)SH_PBUFFER, SH_LEN); break; case SHEL_PUT: sh_put((const void *)SH_PDATA, SH_LEN); break; case SHEL_FIND: ret = sh_find((BYTE*)SH_PATH); break; case SHEL_ENVRN: sh_envrn((BYTE**)SH_PATH, (const BYTE*)SH_SRCH); break; #if CONF_WITH_PCGEM case SHEL_RDEF: sh_rdef((BYTE*)SH_LPCMD, (BYTE*)SH_LPDIR); break; case SHEL_WDEF: sh_wdef((const BYTE*)SH_LPCMD, (const BYTE*)SH_LPDIR); break; #endif default: unsupported = TRUE; break; } if (unsupported) { kprintf("Bad AES function %d\n", opcode); if (opcode != 0) /* Ignore the 0 since some PRGs are this call */ fm_show(ALNOFUNC, &opcode, 1); ret = -1; } return(ret); }