home *** CD-ROM | disk | FTP | other *** search
- /*
- winobj.c
-
- % generic window object
-
- 3/17/88 by Ted.
-
- OWL 1.1
- Copyright (c) 1988, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 6/16/88 Ted revised to have inheritance and class factory functions.
- 8/09/88 jmd revised to use new object stuff
- 9/02/88 ted fixed graphics cursor scrolling
- 9/02/88 ted moved non-object functions out to winfuncs.c
- 9/12/88 jmd Added in and out data to objects
- 11/17/88 ted Added WIN_GO & mouse control default methods.
- 11/20/88 jmd Added ID to obj struct
- 11/22/88 jmd Changed unsingeds to burnts!
- 12/02/88 ted Added REQ message handling for bdmouse
- 3/24/89 ted Moved attribute and curstype into xdata, added SETFONT msg.
- 3/24/89 ted Made win's pure objects. Eliminated win_CreateWin,
- wmgr_Destroy win by folding them into win_Class.
- 4/14/89 ted Added WINM_CHILDCLOSE msg.
- 5/01/89 ted Added break case for WINM msgs not used at this level.
- 5/28/89 jmd added Shadow support
- 7/07/89 gam changed NULL to FNULL where necessary.
- 7/25/89 ted Added explode function call.
- 8/06/89 ted Commented out null inits to save time and code.
- 8/08/89 jmd Added size, pos, and top support.
- 8/10/89 jmd Killed bob, added new messages to windows.
- 8/12/89 jdc Added win_Close function stuff here
- 8/12/89 jdc Added INIT message, added WHO message
- 8/13/89 jmd removed GETEXPLODE message
- 8/16/89 jmd Added initialization for nullfont and resize flags.
- 9/12/89 jmd Fixed Shadow Clear color
- */
-
- #include "oakhead.h"
- #include "disppriv.h"
- #include "bordobj.h"
- #include "winod.h"
-
- OGLOBAL objreq_fptr winreq_loadfptr = objreq_Null;
- OGLOBAL objreq_fptr winreq_savefptr = objreq_Null;
-
- OSTATIC void OWLPRIV win_paintcursor(_arg1(win_type));
-
- /* -------------------------------------------------------------------------- */
-
- int win_Class(objdata, msg, indata, outdata)
- VOID *objdata; /* object instance data pointer */
- int msg; /* message */
- VOID *indata; /* message input data */
- VOID *outdata; /* message output data */
- /*
- win object dispatch function
- */
- {
- win_od *wd;
- win_type win;
- win_xd *winxd;
- ptd_struct *ptd;
- ptd_struct inptd; /* for use in inner-coordinate computations */
- opbox inbox; /* ditto; gets hooked in by ptd_SetInner */
- opbox relbox;
-
- wd = (win_od *) objdata;
- win = winod_GetSelf(wd); /* Note: no GP fault here because GETDATASIZE is never called */
- winxd = win_getxd(win); oak_notused(winxd);/* Here for debugging reference */
-
- switch(msg) {
- /* case OBJM_GETDATASIZE: This class only exists to be inherited */
-
- case OBJM_WHO:
- /* Identify ourselves */
- return (*((int *) indata) == ID_WIN || *((int *) indata) == ID_BOB);
-
- case OBJM_OPEN:
- /*
- Open a new window in pixel coordinates, with a font spec.
- Note: Called only from win_PixOpen, wmgr_Init, & wmgr_ListOpen which
- is called from wmgr_Init. Therefore, it does not need to call
- hard_Claim/Release for reentrancy protection because both of its
- calling paths do it already.
- Note: all inits to 0, FALSE, NULL, & FNULL are superfluous because
- object structures are initted to 0's.
- */
- {
- int i;
-
- /* Initialize win private object data */
-
- #ifdef OAK_NULLNOT0
- wd->current = FALSE; /* init not current */
- wd->curshide = 0; /* init cursor showing */
- wd->cursunder = NULL; /* init cursor under-buffer */
- wd->cudrawn = 0;
- wd->cubox.xmin = 0; wd->cubox.ymin = 0;
- wd->cubox.xmax = 0; wd->cubox.ymax = 0;
-
- /* Initialize win xdata */
-
- win_SetParent(win, NULL);
-
- win_inboxp(win)->xmin = 0; win_inboxp(win)->ymin = 0;
- win_inboxp(win)->xmax = 0; win_inboxp(win)->ymax = 0;
- win_pixboxp(win)->xmin = 0; win_pixboxp(win)->ymin = 0;
- win_pixboxp(win)->xmax = 0; win_pixboxp(win)->ymax = 0;
-
- win_setemployed(win, FALSE);
- win_setabove(win, NULL);
- win_setbelow(win, NULL);
-
- win_setcursx(win, 0);
- win_setcursy(win, 0);
-
- win_SetMouse(win, FNULL);
- win_SetDebounced(win, FALSE);
- win_SetNextWin(win, NULL);
- win_SetExplode(win, FNULL);
-
- win_setbd(win, NULL);
-
- win_setshadowx(win, 0);
- win_setshadowy(win, 0);
- win_SetShadowAttr(win, 0x00);
- #endif
- win_setnullfont(win, TRUE);
- win_SetParentClip(win, TRUE);
-
- win_setattribute(win, ATTR_NORMAL);
- win_setcurstype(win, CURSOR_NORMAL);
-
- win_setidmgr(win, disp_id());
- win_SetCharSize(win, TRUE);
- win_SetResize(win, TRUE);
-
- /* initialize LNF function handle array */
- for (i = 0; i < WIN_FSYM_COUNT; i++) {
- win_getxd(win)->handles[i] = -1;
- }
-
- /* send OPEN to bob superclass */
- return(bob_DoRaw(&(wd->cd), msg, indata, outdata));
- }
-
- case OBJM_INIT:
- {
- winopendata_struct *wod = (winopendata_struct *) indata;
- opbox *boxp;
- ofont_type dfont;
- odim width, height;
-
- boxp = wod->boxp;
-
- if (!disp_TextFree()) {
- dfont = disp_GetDefFont();
- width = opbox_GetWidth(boxp);
- height = opbox_GetHeight(boxp);
- opcoord_GridRound(&boxp->xmin, &boxp->ymin, dfont);
- /* Round up instead of down */
- boxp->xmax = boxp->xmin + width + ofont_GetWidth(dfont) - 1;
- boxp->ymax = boxp->ymin + height + ofont_GetHeight(dfont) - 1;
- opcoord_GridRound(&boxp->xmax, &boxp->ymax, dfont);
- }
- opbox_copy(win_pixboxp(win), boxp);
- win_inboxp(win)->xmax = opbox_GetWidth(boxp);
- win_inboxp(win)->ymax = opbox_GetHeight(boxp);
-
- /* Set up the font, underbuffer, etc. */
- if (!win_SetFont(win, wod->font)) {
- return(FALSE);
- }
- /* Put window into unemployed list (at the top) */
- if (wod->list != NULL) {
- win_ListAdd(wod->list, win);
- }
- break;
- }
-
- case OBJM_CLOSE:
- /*
- Note: Called only from wmgr_ListClose which is called from
- wmgr_Wrapup and wmgr_Init. Therefore, it does not need to call
- hard_Claim/Release for reentrancy protection because all three of its
- calling paths do it already.
- */
- {
- extern win_type vid_win;
-
- owl_Assert(win_Ok(win), OE_WC_WIN);
-
- hard_Claim(); /* Here for re-entrancy protection */
-
- /* Unemploy window first */
- if (win_IsEmployed(win)) {
- win_UnEmploy(win);
- }
- /* remove window from unemployed list */
- win_ListRemove(win);
-
- /* Make sure vid_win ptr is NULL'ed out if vid_win is destroyed */
- if (vid_win == win) {
- vid_win = NULL;
- }
- /* Make sure backwin ptr is NULL'ed out if backwin is destroyed */
- if (disp_GetBackWin() == win) {
- wmgr_setbackwin(NULL);
- }
- /* Make sure the win is not still current after it is freed */
- if (disp_GetCurrentWin() == win) {
- win_MakeCurrent(NULL);
- }
- /* Close the window's border if it has one */
- bord_Close(win);
-
- /* Kill the Window's cursor under-buffer and font reference. */
- win_SetFont(win, NULL);
-
- /* Kill the window's dmgr id so win_Ok will now fail on this win ptr */
- win_setidmgr(win, 0);
-
- /* Notify the window's parent window that its child is closed */
- owl_Assert(((win_GetParent(win) == NULL) || win_Ok(win_GetParent(win))), OE_WC_PARENT);
- win_Do(win_GetParent(win), WINM_CHILDCLOSE, win, NULL);
-
- hard_Release();
-
- /* send CLOSE to bob superclass */
- return(bob_DoRaw(&(wd->cd), msg, indata, outdata));
- }
-
- case OBJM_LOAD:
- return((*winreq_loadfptr)(objdata, msg, indata, outdata));
-
- case OBJM_SAVE:
- return((*winreq_savefptr)(objdata, msg, indata, outdata));
-
- case WINM_SETFONT:
- /* set new font and initialize the cursor under-buffer etc. if needed. */
- {
- ofont_type font = (ofont_type)indata;
-
- win_setfontptr(win, font);
- win_setnullfont(win, font == NULL);
-
- pmap_Close(wd->cursunder);
-
- wd->cudrawn = 0;
- wd->cubox.xmin = 0;
- wd->cubox.ymin = 0;
- if (font == NULL || disp_hardcursor()) {
- wd->cubox.xmax = 0;
- wd->cubox.ymax = 0;
- wd->cursunder = NULL;
- }
- else {
- wd->cubox.xmax = ofont_GetWidth(font);
- wd->cubox.ymax = ofont_GetHeight(font);
-
- /* Allocate pixel map for saving under cursor */
- wd->cursunder = pmap_Open(wd->cubox.xmax, wd->cubox.ymax);
- if (wd->cursunder == NULL) {
- return(FALSE);
- }
- }
- break;
- }
- case WINM_SHOWCURS:
- if (wd->curshide == 1) { /* first show */
- wd->curshide--;
- win_paintcursor((win_type)indata);
- *((boolean *) outdata) = TRUE; /* Return TRUE for did something */
- }
- else {
- *((boolean *) outdata) = FALSE;
- }
- break;
-
- case WINM_HIDECURS:
- if (wd->curshide == 0) { /* first hide */
- wd->curshide++;
- win_paintcursor((win_type)indata);
- *(boolean *) outdata = TRUE; /* Return TRUE for did something */
- }
- else *(boolean *) outdata = FALSE;
- break;
-
- case WINM_SHADOW:
- /* If the window subclass hasn't painted a shadow
- clear the shadow area.
- */
- ptd = (ptd_struct *)indata;
- if (ptd->emsgdata == NULL) {
- ptd_Clear(ptd, disp_GetAttrBgColor(win_GetShadowAttr(ptd->win)));
- }
- /* no break: pass the message through to WINM_PAINT so it can */
- /* take care of painting the border */
-
- case WINM_DRAWCURSOR: /* draw cursor if in this box */
- case WINM_PAINT:
- {
- boolean dobord; /* flag for whether to call border paint function. */
-
- ptd = (ptd_struct *)indata;
- if (ptd_SetInner(ptd, &inptd, &inbox)) {
- if (wd->current) {
-
- win_GetCursorPixBox(win, &relbox);
-
- if (opbox_clipbox(inptd.relboxp, &relbox)) {
- if (wd->curshide == 0) {
- if (wd->cursunder == NULL) {
- if (!wd->cudrawn) { /* Just draw text cursor */
- ptd_DrawCursor(&inptd, win_GetCursorType(win));
- }
- }
- else { /* If graphics cursor, save under it before drawing it */
- /* Only save under & draw if cursor is not displayed - */
- /* (was painted over or was not drawn) */
- if (!(msg == WINM_DRAWCURSOR && wd->cudrawn)) {
- inptd.relboxp = &relbox;
- ptd_ReadPixmap(&inptd, wd->cursunder, &wd->cubox);
- inptd.relboxp = &inbox; /* restore to other temp. box */
-
- ptd_DrawCursor(&inptd, win_GetCursorType(win));
- }
- }
- wd->cudrawn = TRUE;
- }
- else { /* curshide != 0 */
- /* If graphics cursor, and this is PAINT msg, the char paint will */
- /* already have overwritten it, and this needs to do nothing */
- /* If a DRAWCURSOR msg, this pixmap restore will paint over it */
- if (wd->cursunder == NULL) {
- /* If hardware cursor, this will turn it off. */
- ptd_EraseCursor(&inptd);
- }
- else {
- if (msg == WINM_DRAWCURSOR && wd->cudrawn) {
- inptd.relboxp = &relbox;
- ptd_DrawPixmap(&inptd, wd->cursunder, &wd->cubox);
- inptd.relboxp = &inbox; /* restore to other temp. box */
- }
- }
- wd->cudrawn = FALSE;
- }
- }
- }
- /* If it was clipped, that means some of it hung over into border */
- dobord = !opbox_equal(inptd.relboxp, ptd->relboxp);
- }
- /* If it wasn't in win box at all, it must be in border */
- else {
- dobord = TRUE;
- }
-
- /* Paint border */
- if (dobord) {
- bord_Do(win, (msg == WINM_SHADOW) ? BDM_SHADOW : BDM_DRAW, indata, NULL);
- }
- break;
- }
- case WINM_SHADOWSAVE:
- case WINM_SAVE: /* hide cursor if in this box */
- /* If hardware cursor, this will turn it off. */
- /* If graphics cursor, it will get overwritten or it doesn't need */
- /* to be erased and this does nothing */
- if (wd->current && wd->curshide == 0) {
- ptd = (ptd_struct *)indata;
- if (ptd_SetInner(ptd, &inptd, &inbox)) {
- win_GetCursorPixBox(win, &relbox);
- if (opbox_clipbox(inptd.relboxp, &relbox)) {
- if (wd->cursunder == NULL) {
- ptd_EraseCursor(&inptd);
- }
- wd->cudrawn = FALSE;
- }
- }
- }
- break;
-
- case WINM_SCROLL:
- {
- opcoord nx, ny;
-
- ptd = (ptd_struct *)indata;
- nx = ( (opoint *)(ptd->emsgdata) )->x;
- ny = ( (opoint *)(ptd->emsgdata) )->y;
- if (ptd_SetInner(ptd, &inptd, &inbox)) {
- opbox_copy(&relbox, inptd.relboxp);
-
- if (nx == 0) {
- if (ny == 0) {
- break; /* Do nothing if no scroll called for */
- }
- else if (disp_vtscroll()) { /* Vertical Scroll */
- if (opbox_ScrollVtIn(&relbox, ny)) {
- ptd_ScrollBoxVt(&inptd, ny);
- }
- }
- }
- else {
- if (ny == 0 && disp_hzscroll()) { /* Horizontal Scroll */
- if (opbox_ScrollHzIn(&relbox, nx)) {
- ptd_ScrollBoxHz(&inptd, nx);
- }
- }
- /* else nx and ny not zero - just repaint the whole box */
- }
- /* Call the window's paint function on the remaining box portion */
- inptd.relboxp = &relbox;
- win_Do(win, WINM_PAINT, &inptd, NULL);
- }
- break;
- }
- case WINM_CLEAR:
- ptd = (ptd_struct *)indata;
- if (ptd_SetInner(ptd, &inptd, &inbox)) {
- ptd_Clear(&inptd, *((opixval *)inptd.emsgdata));
- }
- break;
-
- case WINM_GETINPOS: /* return inbox same as win box */
- {
- inposdata_struct *ipd = (inposdata_struct *)outdata;
-
- win_GetPixBox(ipd->win, &ipd->inbox);
- break;
- }
- case WINM_STARTCUR:
- if (wd->current != TRUE) {
- wd->current = TRUE;
- if (wd->curshide == 0) { /* turn cursor on */
- win_paintcursor((win_type)indata);
- }
- *((boolean *) outdata) = TRUE;
- }
- else {
- *((boolean *) outdata) = FALSE;
- }
- break;
-
- case WINM_STOPCUR:
- if (wd->current != FALSE) {
- if (wd->curshide == 0) { /* turn cursor off */
- wd->curshide++;
- win_paintcursor((win_type)indata);
- wd->curshide--;
- }
- wd->current = FALSE;
- *((boolean *) outdata) = TRUE;
- }
- else {
- *((boolean *) outdata) = FALSE;
- }
- break;
-
- case WINM_EXPLODE:
- if (win_GetExplodeFptr(win) != FNULL) {
- return((*win_GetExplodeFptr(win))(objdata, msg, indata, outdata));
- }
- break;
-
- case WINM_SETPOS:
- /* move the window to a new location */
- win_ReallySetPixPosition(win, ((opoint *)indata)->x, ((opoint *)indata)->y);
- break;
-
- case WINM_SETSIZE:
- /* change the size of the window */
- win_ReallySetPixSize(win, (odim) ((opoint *)indata)->x, (odim) ((opoint *)indata)->y);
- break;
-
- case WINM_PUTUNDER:
- /* indata in a win_type, put the window under it (if NULL put it on top) */
- win_ReallyPutUnder(win, (win_type) indata);
- break;
-
- case WINM_UNEMPLOY:
- /* a request to unemploy the window */
- win_ReallyUnEmploy(win);
- break;
-
- case WINM_GOREQ: /* request to be go'ed */
- *((int *)outdata) = win_Go(win);
- break;
-
- case WINM_GO: /* default: quit (we didn't ask to be called) */
- *((int *)outdata) = -1;
- break;
-
- case WINM_PAINTREQ:
- /* Paint a window (or employ it if it is unemployed) */
- /* this is passed a bit flag via indata that tells
- whether the border is to be painted or not.
- indata can also be NULL which means paint the whole thing
- */
-
- if (!win_IsEmployed(win)) {
- if (indata == NULL || (*((unsigned *) indata) != WPD_SENTER)) {
- win_Employ(win);
- }
- }
- else {
- if (indata == NULL || (*((unsigned *) indata) & WPD_BORDER)) {
- bord_Paint(win);
- }
- else {
- win_Paint(win);
- }
- }
- break;
-
- case WINM_GETFLDPOS:
- /* get location of control within the window */
- /* outdata is a (ocbox *) */
- /* you should preset the ocbox before calling this message */
- break;
-
- case WINM_SETFLDPOS:
- /* pass control to location closest to curpos */
- /* indata is a (winscp_struct *) */
- break;
-
- case WINM_ISAVE:
- case WINM_SCROLLREQ:
- case WINM_ICONREQ:
- case WINM_CHILDCLOSE:
- break; /* These messages are supported in a subclass or not at all */
-
- default:
- /* pass other messages to bob superclass */
- return(bob_DoRaw(&(wd->cd), msg, indata, outdata));
- }
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static void OWLPRIV win_paintcursor(win)
- win_type win;
- {
- opbox cursbox;
-
- win_GetCursorPixBox(win, &cursbox);
- if (win_clipbox(win, &cursbox)) {
- win_ExposePixBox(win, &cursbox, WINM_DRAWCURSOR, NULL);
- }
- }
- /* -------------------------------------------------------------------------- */
-
-