/* ************************************************************************* * Revision Control System * ======================================================================= * $Revision: 2.3 $ $Source: /u2/MRS/osrevisions/aes/gemctrl.c,v $ * ======================================================================= * $Author: mui $ $Date: 89/04/26 18:21:33 $ $Locker: kbad $ * ======================================================================= * $Log: gemctrl.c,v $ * Revision 2.3 89/04/26 18:21:33 mui * TT * * Revision 2.2 89/04/06 17:58:24 kbad * changed hctl_window to use delay() system tick timer rather than evnt_ calls. * * Revision 2.1 89/02/22 05:25:15 kbad * *** TOS 1.4 FINAL RELEASE VERSION *** * * Revision 1.3 89/02/16 10:47:41 mui * Fix dclicks: take out gl_bpend stuf in ctrlmgr * * Revision 1.2 89/02/14 08:51:45 kbad * fix at hctl_window to prevent double events being generated by single * clicks in window controls. * * Revision 1.1 88/06/02 12:31:14 lozben * Initial revision * * Revision 1.1 87/11/20 14:14:07 lozben * Initial revision * * ======================================================================= * * $Revision: 2.3 $ * ======================================================================= * * $Source: /u2/MRS/osrevisions/aes/gemctrl.c,v $ * ======================================================================= * ************************************************************************* */ /* GEMCTRL.C 5/14/84 - 02/23/85 Lee Jay Lorenzen */ /* pstart bugs,1.1 2/12/85 - 04/05/85 LKW */ /* Reg Opt 03/09/85 Derek Mui */ /* Fix at hctl_window 05/11/85 - 10/21/85 Derek Mui */ /* Fix the button semaphore at ctlmgr 2/27/86 Derek Mui */ /* Ctlmouse to control the mouse 03/05/86 Derek Mui */ /* Change at ctlmouse to save mouse form by using line a function, */ /* take out tmpmaddr 1/7/87 Derek Mui */ /* Smooth scrolling 2/4/87 Derek Mui */ /* Change at ctlmgr for smooth scrolling 3/11/87 Derek Mui */ /* Fix at ctlmouse of gsx_ncode 12/11/87 D.Mui */ /* Take out gl_fakemsg at hctl_button 2/17/88 D.Mui */ /* Take out gl_fakemsg at hctl_button 6/25/90 D.Mui */ /* Change the way it sends the arrow message 4/3/91 D.Mui */ /* Change mn_do to mn_hdo 7/8/92 D.Mui */ /* New codes to handle new window library 8/1/92 D.Mui */ /* * ------------------------------------------------------------- * GEM Application Environment Services Version 1.1 * Serial No. XXXX-0000-654321 All Rights Reserved * Copyright (C) 1985 Digital Research Inc. * ------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #define THEDESK 3 #define MBDOWN 0x0001 #define BELL 0x07 /* bell */ EXTERN LONG ad_armice; EXTERN PD *pstart(); /* in INPUT88.C */ EXTERN WORD os_mchg(); /* in EVLIB.C */ EXTERN WORD ev_mesag(); EXTERN WORD ev_multi(); /*EXTERN WORD ev_timer();*/ /* ratrbp.s */ EXTERN VOID delay(); EXTERN WINDOW *srchwp(); /* in WMLIB.C */ EXTERN WORD w_getsize(); EXTERN WORD w_bldactive(); EXTERN WORD w_setactive(); EXTERN WORD topw; EXTERN LONG newdesk; EXTERN WORD newroot; /* in GEMINIT.C */ EXTERN LONG ad_stdesk; EXTERN VOID w_union(); EXTERN VOID w_clipdraw(); /* in PD88.C */ EXTERN PD *fpdnm(); /* in GSXIF.C */ EXTERN WORD bb_screen(); /* in */ EXTERN WORD dsptch(); EXTERN LONG gl_mntree; EXTERN WORD gl_mnpid; EXTERN WORD gl_dacnt; EXTERN WORD gl_dabase; EXTERN WORD desk_pid[]; EXTERN WORD gl_wchar; EXTERN WORD gl_hchar; EXTERN WORD gl_wbox; EXTERN WORD gl_hbox; EXTERN WORD gl_width; EXTERN WORD gl_height; EXTERN GRECT gl_rfull; EXTERN GRECT gl_rmenu; EXTERN WORD button, xrat, yrat; EXTERN GRECT gl_rmnactv; EXTERN GRECT gl_rscreen; EXTERN GRECT ctrl; EXTERN THEGLO D; EXTERN WORD gl_moff; EXTERN WORD gl_mouse; EXTERN WORD gl_dclick; /* gemevlib.c - double click speed */ EXTERN WORD gl_ticktime; /* gemevlib.c - MS per tick */ EXTERN PD *gl_cowner; EXTERN PD *gl_mowner; EXTERN PD *gl_kowner; EXTERN WORD button; EXTERN WORD xrat, yrat; GLOBAL WORD ml_ocnt; MLOCAL LONG ml_mnhold; MLOCAL GRECT ml_ctrl; MLOCAL PD *ml_pmown, *ml_pkown; EXTERN PD *ctl_pd; GLOBAL WORD tmpmoff; GLOBAL WORD tmpmon; GLOBAL MOBLK gl_ctwait; GLOBAL WORD appl_msg[8]; WORD deskwind; /* added 7/25/91 window handle of DESKTOP */ WORD rets[6]; /* added 2/4/87 */ /* used to convert from */ /* window object # to */ /* window message code*/ GLOBAL WORD gl_wa[] = { WA_UPLINE, WA_DNLINE, WA_UPPAGE, WA_DNPAGE, 0x0, WA_LFLINE, WA_RTLINE, WA_LFPAGE, WA_RTPAGE }; /* * Send message and wait for the mouse button to come up */ VOID ct_msgup(message, owner, wh, m1, m2, m3, m4) WORD message; WORD owner, wh; WORD m1, m2, m3, m4; { if (message) ap_sendmsg(appl_msg, message, owner, wh, m1, m2, m3, m4); /* wait for button to */ /* come up */ while( (button & 0x0001) != 0x0 ) dsptch(); } VOID hctl_window(w_handle, mx, my) REG WORD w_handle; WORD mx, my; { GRECT t, f; WORD x, y, w, h; WORD wm, hm; REG WORD kind, gadget; WORD xelev, yelev; REG WORD message, cpt; LONG tree; REG WINDOW *pwin; WORD rets[6]; LONG bwait; PD *p; WORD selst, nrmst, dummy; pwin = srchwp(w_handle); message = 0; /* initialize message */ /* if window is top window, handle control points */ if (w_handle == topw) { /* changed ROOT to W_BOX 072691 - ml. */ gadget = cpt = ob_find(pwin->obj, W_BOX, MAX_DEPTH, mx, my); nrmst = pwin->obj[gadget].ob_state & ~SELECTED; selst = nrmst | SELECTED; r_get(&pwin->curr, &x, &y, &w, &h); kind = pwin->kind; /* fix 10/21/85 */ ob_gclip( pwin->obj, gadget, &dummy, &dummy, &f.g_x, &f.g_y, &f.g_w, &f.g_h ); /* f.g_w = pwin->obj[gadget].ob_width; f.g_h = pwin->obj[gadget].ob_height; ob_offset(pwin->obj, gadget, &f.g_x, &f.g_y); f.g_x -= ADJ3DPIX; f.g_y -= ADJ3DPIX; f.g_w += (ADJ3DPIX << 1); f.g_h += (ADJ3DPIX << 1); */ gsx_sclip(&f); switch(cpt) { case W_CLOSER: case W_FULLER: if (gr_watchbox(pwin->obj, gadget, selst, nrmst)) { message = (gadget == W_CLOSER) ? WM_CLOSED : WM_FULLED; } break; case W_NAME: if (kind & MOVER) { ob_change(pwin->obj, gadget, selst, TRUE); r_set(&f, 0, gl_hbox, (gl_rscreen.g_w + w - gl_wbox - 6), 10000); gr_dragbox(w, h, x, y, &f, &x, &y); message = WM_MOVED; } break; /* For debugging tobot() */ #if 0 case W_INFO: /* tobot(w_handle); */ break; #endif case W_SIZER: if (kind & SIZER) { /* fix 10/21/85 */ ob_change(pwin->obj, gadget, selst, TRUE); t = *(GRECT *)&(pwin->obj[W_WORK].ob_x); t.g_x -= x; t.g_y -= y; t.g_w -= w; t.g_h -= h; wm_min( kind, &wm, &hm ); gr_rubwind(x, y, wm, hm, &t, &w, &h); message = WM_SIZED; } break; case W_HSLIDE: case W_VSLIDE: ob_offset(pwin->obj, cpt + 1, &xelev, &yelev); if (cpt == W_HSLIDE) { /* fix up for index into gl_wa */ if (!(mx < xelev)) cpt += 1; } else { if (!(my < yelev)) cpt += 1; } /* fall thru */ case W_UPARROW: case W_DNARROW: case W_LFARROW: case W_RTARROW: message = WM_ARROWED; break; case W_HELEV: case W_VELEV: message = (cpt == W_HELEV) ? WM_HSLID : WM_VSLID; ob_change(pwin->obj, gadget, selst, TRUE); /* slide is 1 less than elev */ x = gr_slidebox(pwin->obj, cpt - 1, cpt, (cpt == W_VELEV)); break; } if (message == WM_ARROWED) { if (gadget != W_HSLIDE && gadget != W_VSLIDE) ob_change(pwin->obj, gadget, selst, TRUE); x = gl_wa[cpt - W_UPARROW]; wm_update(FALSE); /* give up the screen */ cpt = TRUE; p = pwin->owner; do { if (p->p_stat == PS_MWAIT) { ap_sendmsg(appl_msg, message, pwin->owner->p_pid, w_handle, x, y, w, h); } else { if (!p->p_message[0]) { /* message is sent */ p->p_message[0] = 1; p->p_message[1] = message; /* message */ p->p_message[2] = rlr->p_pid; /* sender */ p->p_message[3] = 0; /* size in bytes */ p->p_message[4] = w_handle; p->p_message[5] = x; p->p_message[6] = y; p->p_message[7] = w; p->p_message[8] = h; } } dsptch(); /* * Delay for half current double click time: * allow button to come back up on single click */ if (cpt) { /* Only delay 1st time through */ cpt = FALSE; delay((LONG)(gl_dclick)); } } while(button & 1); /* button is global */ wm_update(TRUE); /* take back the screen */ if (gadget != W_HSLIDE && gadget != W_VSLIDE) { ob_gclip( pwin->obj, gadget, &dummy, &dummy, &f.g_x, &f.g_y, &f.g_w, &f.g_h ); /* f.g_w = pwin->obj[gadget].ob_width; f.g_h = pwin->obj[gadget].ob_height; ob_offset(pwin->obj, gadget, &f.g_x, &f.g_y); f.g_x -= ADJ3DPIX; f.g_y -= ADJ3DPIX; f.g_w += (ADJ3DPIX << 1); f.g_h += (ADJ3DPIX << 1); */ gsx_sclip(&f); ob_change(pwin->obj, gadget, nrmst, TRUE); } return; } } else { /* if window is not top, tell application to bring it to top */ message = WM_TOPPED; } if (message) ct_msgup(message, pwin->owner->p_pid, w_handle, x, y, w, h); if (message && (message != WM_TOPPED)) ob_change(pwin->obj, gadget, nrmst, TRUE); } WORD hctl_button( mx, my ) REG WORD mx, my; { REG WORD wh; /* find out which wind. */ /* the mouse clicked */ /* over and handle it */ if ( ( wh = wm_find(mx, my) ) > 0 ) hctl_window( wh, mx, my); } WORD hctl_rect(mx, my) WORD mx, my; { WORD title, item; REG WORD owner, mesag; LONG *ptree; WORD pmenu,keyret; if ( ( gl_mntree != 0x0L ) && ( inside(mx, my, &gl_rmnactv) ) ) { mesag = 0; if ( mn_hdo( &title, &ptree, &pmenu, &item, &keyret ) ) { /* check system menu: */ /* title == 1st menu */ /* && item == deskacc */ if ( (gl_dacnt) && (title == THEDESK ) && (item >= gl_dabase) ) { item -= gl_dabase; owner = desk_pid[item]; do_chg(gl_mntree, title, SELECTED, FALSE, TRUE, TRUE); mesag = AC_OPEN; } else { owner = gl_mnpid; mesag = MN_SELECTED; } } /* application menu */ /* item has been */ /* selected so send it*/ ct_msgup(mesag, owner, title, item, ptree, pmenu); } } /* * Hctl_msg() - handle messages received by control manager * (currently only redraw message is handled) */ VOID hctl_msg(msgbuf) WORD msgbuf[]; { if (msgbuf[0] == WM_REDRAW) drawdesk(msgbuf[4], msgbuf[5], msgbuf[6], msgbuf[7]); } /* * Drawdesk() - redraw portion of DESKTOP specified by the * given rectangle */ VOID drawdesk(x, y, w, h) WORD x, y, w, h; { GRECT t1, t2; WORD temp[4]; OBJECT *tree; WORD stobj; gsx_moff(); wm_update(TRUE); t2.g_x = x; t2.g_y = y; t2.g_w = w; t2.g_h = h; wm_get(deskwind, WF_FIRSTXYWH, temp); if (newdesk) { tree = (OBJECT *)newdesk; stobj = newroot; } else { tree = ad_stdesk; stobj = ROOT; } while (temp[2] && temp[3]) { t1 = *(GRECT *)temp; if (rc_intersect(&t2, &t1)) { gsx_sclip(&t1); ob_draw(tree, stobj, MAX_DEPTH); } wm_get(deskwind, WF_NEXTXYWH, temp); } wm_update(FALSE); gsx_mon(); } /* * Control change of ownership to this rectangle and this process * Doing the control rectangle first is important. */ VOID ct_chgown(ppd, pr) PD *ppd; GRECT *pr; { rc_copy( pr, &ctrl); /* set_ctrl(pr), copy the rect */ /* into contro */ /* set_mkown(ppd, ppd); */ /* change the owner */ gl_cowner = gl_mowner = ppd; /* pretend mouse */ /* moved to get the */ /* right form showing */ /* and get mouse event*/ /* posted correctly */ post_mouse(gl_mowner, xrat, yrat); /* post a button event */ /* in case the new */ /* owner was waiting */ /* post_button(gl_mowner, button, 1); */ gl_kowner = ppd; } /* * 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. */ WORD ctlmgr() { REG WORD ev_which; WORD rets[6]; WORD msgbuf[8]; /* set defaults for */ /* multi wait */ rc_copy(&gl_rmenu, &gl_ctwait.m_x); gl_ctwait.m_out = FALSE; /* CHANGED LKW */ while(TRUE) { w_setactive(); /* if no waiting to go */ /* go out of menu area*/ /* then give mouse to */ /* owner of top window*/ /* gsx_mxmy(&mx, &my); */ /* gl_ctwait.m_out = inside(mx, my, &gl_ctwait.m_x);*/ /* wait for something to*/ /* happen */ ev_which = ev_multi(MU_KEYBD | MU_BUTTON | MU_M1 | MU_MESAG, &gl_ctwait, &gl_ctwait, 0x0L, 0x0001ff01L, &msgbuf[0], &rets[0]); /* grab screen sink */ wm_update(TRUE); /* button down over area*/ /* ctrl mgr owns */ if (ev_which & MU_BUTTON) { hctl_button(rets[0], rets[1]); } /* mouse over menu bar */ if (ev_which & MU_M1) { hctl_rect(rets[0], rets[1]); } if (ev_which & MU_MESAG) /* need to redraw */ { hctl_msg(msgbuf); } /* give up screen sink */ wm_update(FALSE); } } /* * Create a process for the Screen Control Manager and start him * executing. Also do all the initialization that is required. * Also zero out the desk accessory count. */ PD *ictlmgr(pid) WORD pid; { PD *px; REG LONG ldaddr; gl_dacnt = 0; gl_dabase = 0; /* figure out load addr */ ldaddr = LLCS() + ((LONG) &ctlmgr); /* create process to */ /* execute it */ return( pstart(&ctlmgr, "SCRENMGR.LOC", ldaddr) ); } /* New routine to force arrow mouse and show mouse when it is over */ /* the menu bar or there is an alert box 3/05/86 */ WORD ctlmouse( mon ) WORD mon; { if ( mon ) /* turn on and show the mouse */ { getmouse(); tmpmon = gl_mouse; /* mouse on flag */ tmpmoff = gl_moff; gsx_xmfset ( ad_armice ); /* change the mouse form */ if (!gl_mouse) /* if currently the mouse is */ { gsx_1code( SHOW_CUR, 0 ); /* off, then turn it on */ gl_mouse = TRUE; /* set the flag */ } gl_moff = 0; /* reset the flag to make bbset */ } /* work */ else { gsx_ncode( HIDE_CUR, 0x0L ); /* turn off the mouse anyway */ putmouse(); /* put the mouse back to the */ gl_mouse = FALSE; /* way it was */ if ( tmpmon ) /* the mouse was on */ { gsx_ncode( SHOW_CUR, 0x0L ); gl_mouse = TRUE; } gl_moff = tmpmoff; } return; } /* 0 = end mouse control */ /* 1 = mouse control */ VOID take_ownership(beg_ownit) WORD beg_ownit; { if ( beg_ownit ) { wm_update(TRUE); if (ml_ocnt == 0) { ml_mnhold = gl_mntree; /* save the current menu */ gl_mntree = 0x0L; /* no menu */ rc_copy( &ctrl, &ml_ctrl ); /* get_ctrl(&ml_ctrl); */ /* save the control rect */ /* get_mkown(&ml_pmown, &ml_pkown); */ ml_pmown = gl_mowner; /* save the mouse owner */ ml_pkown = gl_kowner; /* save the keyboard owner */ ct_chgown( rlr, &gl_rscreen ); /* change mouse ownership */ } /* and the control rect */ ml_ocnt++; } else { ml_ocnt--; if (ml_ocnt == 0) { ct_chgown(ml_pkown, &ml_ctrl); /* restore mouse owner */ gl_mntree = ml_mnhold; /* restore menu tree */ } wm_update(FALSE); } }