|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 12190 (0x2f9e)
Types: TextFile
Notes: UNIX file
Names: »wmgr.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »hr/src/smgr/wmgr.c«
#include <stdio.h>
#include <errno.h>
#include "smgr.h"
extern char *malloc();
extern int *screen_addr();
extern LAYER *newlayer();
extern BITMAP display;
extern LAYER *DM_rearmost, *DM_frontmost;
extern WSTRUCT *wtbl[];
extern POINT SM_Mouse_Pos;
extern UPDATE update[];
extern bool R_point_in();
extern RECT R_inset();
extern POINT gkToGlobal();
extern int memfail();
static uint mse_buttons;
static int SM_Mouse_Track;
char *font_names[] = { "/usr/hr/fonts/gallant.r.10",
"/usr/hr/fonts/gacha.b.8",
"/usr/hr/fonts/cmr.b.8",
"/usr/hr/fonts/sail.r.6",
"/usr/hr/fonts/gacha.b.7",
"/usr/hr/fonts/gacha.r.7" };
POINT font_size[] = { {960, 575}, {720, 475}, {800, 475},
{480, 275}, {720, 450}, {640, 450} };
void SM_Reset()
{
register int i;
#ifdef TRACE
peteprint("SM_Reset: entry\n");
#endif
display.base = SEG0;
display.rect.origin.x = XMIN;
display.rect.origin.y = YMIN;
display.rect.corner.x = XMAX;
display.rect.corner.y = YMAX;
display.width = DIS_WIDTH;
/* initialize the window manager table to NULL's */
for (i = 0; i < MAX_WINDOWS; i++)
wtbl[i] = (WSTRUCT *) NULL;
SM_Mouse_Track = 0; /* no mouse tracking */
DM_frontmost = DM_rearmost = (LAYER*)NULL;
SM_Mouse_Pos.x = 0;
SM_Mouse_Pos.y = 0;
mse_buttons = 0;
background(display.rect);
return;
}
/* SM_Create : create a window at location 'r' of type 't'. */
/* assume : global 'gk' available for use */
/* return : window id or negative error code */
void SM_Create()
{
register RECT r;
WSTRUCT *wp;
register int wid;
char type;
WIN_CREATE c;
#ifdef TRACE
peteprint("SM_Create: entry\n");
#endif
getdata(msgSender, sizeof(c), msgPtr, &c);
msgCmd = WM_REPLY;
r = c.wc_dims;
type = (char )c.wc_type;
/* is the desired size within reason ? */
if (( r.origin.x < XMIN || r.origin.y < YMIN ) ||
( r.corner.x > XMAX || r.corner.y > YMAX ) ||
( r.corner.x <= r.origin.x || r.corner.y <= r.origin.y ) )
{
msgData0 = -1;
sendmsg(&msg);
return;
}
/* would this window obscure any non-obscurable window ? */
for ( wid=0; wid < MAX_WINDOWS; wid++ )
if ( wp = wtbl[wid] )
if ( wp->wn_Type & WT_NOOBS )
if ( R_intersect( r, wp->wn_Layer->rect ) )
{
msgData0 = -2;
sendmsg(&msg);
return;
}
/* is this window already occupied ? */
if ( wtbl[msgWid] != (WSTRUCT *)NULL )
{
msgData0 = -3;
sendmsg(&msg);
return; /* none available */
}
wid = msgWid;
gkWid = wid;
gkLorigin.x = 0;
gkLorigin.y = 0;
gkCursor.x = 0;
gkCursor.y = 0;
gkCascnt = 0;
gkCrect = r;
gkPsize.x = r.corner.x - r.origin.x;
gkPsize.y = r.corner.y - r.origin.y;
gkWmgr = msgSender;
gkEvmask = DEF_EVMASK;
gkFlags = WT_FULLY_VIS;
gkType = (unsigned int )type;
/* PTB */
gk.wn_ascii = c.wc_ascii;
SM_RstGraph();
SM_RstPoint();
gkLayer = newlayer(r);
if ( gkLayer == (LAYER*)NULL )
{
msgData0 = -4;
sendmsg(&msg);
return;
}
gkLayer->base = screen_addr(r.origin.x, r.origin.y);
gkLayer->width = 1024;
wp = (WSTRUCT *) malloc(sizeof(WSTRUCT));
if ( wp == (WSTRUCT *)NULL)
memfail();
wtbl[wid] = wp;
*wtbl[gkWid] = gk;
outline(gkWid);
gkCrect = R_inset(gkCrect, 7, 7);
*wtbl[gkWid] = gk;
msgReceiver = gkWmgr;
msgWid = gkWid;
sendmsg(&msg);
return;
}
void SM_Delete()
{
int wmgr;
#ifdef TRACE
peteprint("SM_Delete: entry with wid = %d\n", msgWid);
#endif
/* delete the layer */
wmgr = gkWmgr;
dellayer(gkLayer);
free(wtbl[msgWid]);
/* clean up the window manager section. */
wtbl[msgWid] = (WSTRUCT *)NULL;
perform_update();
msgCmd = WM_ACK;
msgReceiver = wmgr;
sendmsg(&msg);
}
void SM_WReset() {}
void SM_WhoTopAt()
{
msgCmd = WM_REPLY;
msgWid = who_top_at(msgPt);
sendmsg(&msg);
}
void SM_Front()
{
#ifdef TRACE
peteprint("DM_pop: entry with wid = %d\n", msgWid);
#endif
upfront(gkLayer);
}
void SM_Back()
{
#ifdef TRACE
peteprint("DM_Back: entry for wind = %d\n", msgWid);
#endif
pushback(gkLayer);
}
void SM_WhoFront()
{
msgCmd = WM_REPLY;
msgWid = lp2id(DM_frontmost);
sendmsg( &msg );
}
void SM_GetXClip()
{
msgCmd = WM_REPLY;
msgWid = gkWid;
msgData1 = gkToLogicalX(gkCrect.origin.x);
msgData2 = gkToLogicalX(gkCrect.corner.x);
sendmsg( &msg );
}
void SM_GetYClip()
{
msgCmd = WM_REPLY;
msgWid = gkWid;
msgData1 = gkToLogicalY(gkCrect.origin.y);
msgData2 = gkToLogicalY(gkCrect.corner.y);
sendmsg( &msg );
}
void SM_SetXClip()
{
register int i;
i = msgData2 - msgData1;
if ( i > gkPsize.x )
return;
gkCrect.origin.x = gkToGlobalX(msgData1);
gkCrect.corner.x = gkToGlobalX(msgData2);
}
void SM_SetYClip()
{
register int i;
i = msgData2 - msgData1;
if ( i > gkPsize.y )
return;
gkCrect.origin.y = gkToGlobalY(msgData1);
gkCrect.corner.y = gkToGlobalY(msgData2);
}
void SM_ClrClip()
{
register BLTSTRUCT blt;
blt.src = &gkBitMap;
blt.dst = &gkBitMap;
blt.dr = gkCrect;
blt.sp = gkCrect.origin;
blt.op = L_TRUE;
blt.pat = texture[ msgBytL0 ? gkBpat : gkFpat ];
lblt(&blt, 1, 1);
}
void SM_SetPhy()
{
register RECT r;
register LAYER *lp;
if ( gkType & WT_NORELOC )
{
msgCmd = WM_NACK;
msgReceiver = DESKTOP;
sendmsg(&msg);
return;
}
r.origin = msgPt;
r.corner.x = r.origin.x + gkPsize.x;
r.corner.y = r.origin.y + gkPsize.y;
/* make certain that you don't stomp on a un-obscurable */
for ( lp = DM_frontmost; lp; lp = lp->front )
if ( lp != gkLayer )
if ( wtbl[lp2id(lp)]->wn_Type & WT_NOOBS)
if ( R_intersect(r, lp->rect) )
{
msgCmd = WM_NACK;
msgReceiver = DESKTOP;
sendmsg( &msg );
return;
}
new_dimensions(r);
msgCmd = WM_ACK;
msgReceiver = DESKTOP;
sendmsg ( &msg);
}
void SM_GetPhy()
{
msgCmd = WM_REPLY;
msgPtr = &(wtbl[gkWid]->wn_Layer->rect);
sendmsg( &msg );
}
void SM_SetLog()
{
gkLorigin.x = msgData1;
gkLorigin.y = msgData2;
}
void SM_GetLog()
{
msgCmd = WM_REPLY;
msgData1 = gkLorigin.x;
msgData2 = gkLorigin.y;
sendmsg( &msg );
}
void SM_SetSize()
{
register RECT r;
register LAYER *lp;
int newfont;
int orow, ocol; /* old row and column of cursor */
GETPTR f;
/* NO SUCH WINDOWS */
/*
if ( gkType & WT_NOSIZE )
{
msgCmd = WM_NACK;
msgReceiver = DESKTOP;
msgWid = gkWid;
msgPt = gkLayer->rect.corner;
sendmsg(&msg);
return;
}
*/
r.origin = gkLayer->rect.origin;
r.corner.x = r.origin.x + msgPt.x;
r.corner.y = r.origin.y + msgPt.y;
if ( gkWmgr == 3 ) /* text mgr */
{
if ( gkFlags & WT_CURSOR_ON )
{
f.gch = ' ';
f.gfid = gkFfid;
ocol = ((gk.wn_Curpos.x-7) / FM_getch(&f));
orow = ((gk.wn_Curpos.y-7) / f.gleading);
msgData1 = 0;
SM_DrawCurs();
gkFlags |= WT_2_CURSOR_WON;
}
newfont = get_font(r);
r.corner.x = r.origin.x + font_size[newfont].x + 14;
r.corner.y = r.origin.y + font_size[newfont].y + 14;
}
/* make certain that you don't stomp on a un-obscurable */
/*
for ( lp = DM_frontmost; lp; lp = lp->front )
if ( lp != gkLayer )
if ( wtbl[lp2id(lp)]->wn_Type & WT_NOOBS)
if ( R_intersect(r, lp->rect) )
{
msgCmd = WM_NACK;
msgReceiver = DESKTOP;
msgWid = gkWid;
msgPt = gkLayer->rect.corner;
sendmsg( &msg );
return;
}
*/
if ( gkWmgr == 3 ) /* text */
{
newfont = FM_open( font_names[newfont] );
if ( newfont != gkFfid )
{
FM_close(gkFfid);
gkFfid = newfont;
}
else
FM_close(newfont);
f.gch = ' ';
f.gfid = newfont;
msgData2 = FM_getch(&f);
msgData0 = f.gascent;
msgData1 = f.gdescent;
SM_DefCurs();
}
new_dimensions(r);
msgReceiver = gkWmgr;
msgWid = gkWid;
msgCmd = WM_SIZECHANGE;
msgPt = gkPsize;
sendmsg( &msg );
if ( gkWmgr == 3 ) /* text */
{
if ( gkFlags & WT_2_CURSOR_WON )
{
f.gch = ' ';
f.gfid = gkFfid;
msgData2 = FM_getch(&f);
gkDp.x = (ocol * msgData2) + 7;
gkDp.y = (orow * f.gleading)+ f.gascent + 7;
gkDp = gkToGlobal(gkDp);
msgData1 = 1;
SM_DrawCurs();
msgData1 = 0;
SM_DrawCurs();
msgData1 = 1;
SM_DrawCurs();
gkFlags &= ~WT_2_CURSOR_WON;
}
msgCmd = WM_NEWFONT;
msgBytL0 = gkFfid;
msgBytH1 = f.gascent;
msgBytL1 = f.gdescent;
msgBytH2 = FM_getch(&f);
msgBytL2 = f.gleading;
sendmsg( &msg );
}
msgReceiver = DESKTOP;
msgCmd = WM_ACK;
msgWid = gkWid;
msgPt = gkLayer->rect.corner;
sendmsg( &msg );
*wtbl[msgWid] = gk;
}
int get_font(r)
RECT r; /* target rectangle size */
{
int t[6];
int input_height, input_width;
int font_to_try;
int closest;
int i,j;
input_height = r.corner.y - r.origin.y;
input_width = r.corner.x - r.origin.x;
for ( i = 0; i < 6; i++ )
{
t[i] = input_height - font_size[i].y;
t[i] += input_width - font_size[i].x;
if ( t[i] < 0 )
t[i] = ~t[i]; /* make a positive number */
}
pick_a_font:
closest = 0x7FFF;
for ( i = 0; i < 6; i++ )
if ( t[i] < closest )
{
closest = t[i];
font_to_try = i;
}
if ( ((r.origin.x + font_size[font_to_try].x + 14) > 1024 )
|| ((r.origin.y + font_size[font_to_try].y + 14) > 1024 ) )
{
t[font_to_try] = 0x7FFF;
goto pick_a_font;
}
return(font_to_try);
}
void SM_SetEvmask()
{
gkEvmask = msgData1;
}
void SM_GetEvmask()
{
msgCmd = WM_REPLY;
msgWid = gkWid;
msgData1 = gkEvmask;
sendmsg( &msg );
}
void SM_RstEvmask()
{
gkEvmask = DEF_EVMASK;
}
void SM_OpenFont()
{
char *fname,*p;
register int i,j;
i = msgBytL0 + 1; /* font-name length + 1 for NULL */
fname = malloc(i);
msgCmd = WM_REPLY;
if ( !(fname) )
msgData1 = -9;
else
{
p = fname;
for ( j = 0; j < i; j++)
*p++ = (char)NULL;
getdata(msgSender, i-1, msgPtr, fname);
i = FM_open(fname);
free(fname);
msgData1 = i;
}
sendmsg( &msg );
}
void SM_CloseFont()
{
FM_close(msgData1);
}
void SM_GetFontParam()
{
extern FONT_HEADER *FM_GetInfo();
msgCmd = WM_REPLY;
msgPtr = FM_GetInfo( msgData1 );
sendmsg( &msg );
}
void SM_SetMPat(){}
void SM_GetMPat()
{}
void SM_GetMouse()
{}
void SM_Track()
{
SM_Mouse_Track = 1;
}
void SM_UnTrack()
{
SM_Mouse_Track = 0;
}
void SM_Update()
{
register int i,j;
for ( j = 0; j < MAX_UPBUF; j++ )
update[j].wmgr = update[j].wid = -1;
j = 0;
for ( i = 0; i < MAX_LRBUF; i++ )
if ( gkLayer->reg[i].flag == L_VISIBLE )
{
update[j].wmgr = gkWmgr;
update[j].wid = gkWid;
update[j].r = gkLayer->reg[i].bm.rect;
j++;
}
perform_update();
}
void SM_Updall()
{
register int i,j;
register LAYER *lp;
for ( j = 0; j < MAX_UPBUF; j++ )
update[j].wmgr = update[j].wid = -1;
j = 0;
for ( lp = DM_frontmost; lp; lp = lp->back )
for ( i = 0; i < MAX_LRBUF; i++ )
if ( lp->reg[i].flag == L_VISIBLE )
{
update[j].wmgr = wtbl[lp2id(lp)]->wn_Wmgr;
update[j].wid = wtbl[lp2id(lp)]->wn_Wid;
update[j].r = lp->reg[i].bm.rect;
j++;
}
background(display.rect);
perform_update();
}
void SM_Mouse()
{
SM_Mouse_Pos.x = msgData1;
SM_Mouse_Pos.y = msgData2;
if ( SM_Mouse_Track )
{
msgReceiver = DESKTOP;
msgCmd = WM_MMOVE;
msgWid = who_top_at(SM_Mouse_Pos);
msgData1 = SM_Mouse_Pos.x;
msgData2 = SM_Mouse_Pos.y;
sendmsg( &msg );
}
}
void SM_Mmkey()
{
register int toggle;
mse_buttons = msgData2 & 0xE000;
toggle = msgData1 & 0xE000;
SM_Mouse_Pos.x = msgData1 & 0x1FFF;
SM_Mouse_Pos.y = msgData2 & 0x1FFF;
/* these fields of the message to be sent are common */
msgCmd = WM_MTRANS;
msgWid = who_top_at(SM_Mouse_Pos);
msgData1 = toggle;
msgData2 = mse_buttons;
if ( (toggle & SM_DTK) || SM_Mouse_Track )
{
msgReceiver = DESKTOP;
msgData1 |= SM_Mouse_Pos.x;
msgData2 |= SM_Mouse_Pos.y;
sendmsg( &msg );
return;
}
if ( msgWid == NO_WINDOW )
return;
msgReceiver = wtbl[msgWid]->wn_Wmgr;
msgData1 |= SM_Mouse_Pos.x - wtbl[msgWid]->wn_Layer->rect.origin.x -
wtbl[msgWid]->wn_Lorigin.x;
msgData2 |= SM_Mouse_Pos.y - wtbl[msgWid]->wn_Layer->rect.origin.y -
wtbl[msgWid]->wn_Lorigin.y;
if ( (toggle & SM_WMK) && (gkEvmask & WMK_ENABLE) )
sendmsg( &msg );
if ( (toggle & SM_APK) && ( gkEvmask & APK_ENABLE) )
sendmsg( &msg );
return;
}