home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v92.tgz
/
v92.tar
/
v92
/
src
/
runtime
/
rmswin.ri
< prev
next >
Wrap
Text File
|
1996-03-22
|
71KB
|
3,015 lines
/*
* rmswin.ri - Microsoft Windows-specific graphics interface code.
*
* Todo:
* geticonpos
* seticonimage
* free_mutable
* freecolor
* UpdateCursorPos
*
* Untested:
* toggle_fgbg
* rebind
* setpointer
* getlinestyle
* geticonic
* getimstr
* getfntnam
* setgamma
* dumpimage
*
* Blown off:
* getpointername
* setcursor
* getvisual
* getdefault
*/
#ifdef Graphics
void wfreersc();
int alc_rgb(wbp w, SysColor rgb);
int numRealized;
#ifndef min
#define min(x,y) (((x) < (y))?(x):(y))
#define max(x,y) (((x) > (y))?(x):(y))
#endif /* min */
#define PALCLR(c) (c | 0x2000000L)
#define BORDHEIGHT 26
#define BORDWIDTH 6
wclrp scp;
HPALETTE palette;
int numColors = 0;
char *szAppName = "Icon";
/*
* pattern symbols
*/
stringint siPatternSyms[] = {
{0, 16},
{ "black", 0},
{ "checkers", 12},
{ "darkgray", 2},
{ "diagonal", 8},
{ "grains", 13},
{ "gray", 3},
{ "grid", 10},
{ "horizontal",9},
{ "lightgray", 4},
{ "scales", 14},
{ "trellis", 11},
{ "vertical", 7},
{ "verydark", 1},
{ "verylight", 5},
{ "waves", 15},
{ "white", 6},
};
/*
* draw ops
*/
stringint drawops[] = {
{ 0, 16},
{"and", R2_MASKPEN},
{"andInverted", R2_MASKPENNOT},
{"andReverse", R2_MASKNOTPEN},
{"clear", R2_BLACK},
{"copy", R2_COPYPEN},
{"copyInverted", R2_NOTCOPYPEN},
{"equiv", R2_NOTXORPEN},
{"invert", R2_NOT},
{"nand", R2_NOTMASKPEN},
{"noop", R2_NOP},
{"nor", R2_NOTMERGEPEN},
{"or", R2_MERGEPEN},
{"orInverted", R2_MERGEPENNOT},
{"orReverse", R2_MERGENOTPEN},
{"set", R2_WHITE},
{"xor", R2_XORPEN},
};
/*
* line types
*/
stringint siLineTypes[] = {
{0, 6},
{"dashdotted", PS_DASHDOT},
{"dashdotdotted", PS_DASHDOTDOT},
{"dashed", PS_DASH},
{"dotted", PS_DOT},
{"solid", PS_SOLID},
{"striped", PS_DASH}
};
#define NUMSYSCURSORSYMS 5
#define NUMCURSORSYMS 0
HINSTANCE mswinInstance;
int ncmdShow;
int mswinsystem(char *s)
{
int i = WinExec(s, SW_SHOW);
Sleep(1000);
if ( i > 32 ) return 0; else return -1;
}
/*
* wopen
*/
FILE *wopen(char *name, struct b_list *lp, dptr attr, int n, int *err_idx)
{
wbp w;
wsp ws;
wcp wc;
struct imgdata *imd;
char answer[256];
int i, r;
tended struct b_list *tlp;
tended struct descrip attrrslt;
HDC hdc, hdc2, hdc3;
TEXTMETRIC metrics;
LOGPALETTE logpal[4]; /* really 1 + space for an extra palette entry */
HBRUSH brush;
tlp = lp;
/*
* allocate a binding, a window state, and a context
*/
Protect(w = alc_wbinding(), return NULL);
Protect(w->window = alc_winstate(), { free_binding(w); return NULL; });
Protect(w->context = alc_context(w), { free_binding(w); return NULL; });
ws = w->window;
ws->listp.dword = D_List;
BlkLoc(ws->listp) = (union block *)lp;
ws->width = ws->height = 0;
wc = w->context;
/*
* process the passed in attributes - by calling wattrib
*/
for(i = 0; i < n; i++)
switch (wattrib(w, StrLoc(attr[i]), StrLen(attr[i]), &attrrslt,
answer)) {
case Failed:
wclose(w);
return NULL;
case Error:
/* think of something to do here */
break;
}
/*
* set the title, defaulting to the "filename" supplied to open()
*/
if (ws->windowlabel == NULL) ws->windowlabel = salloc(name);
if (ws->iconlabel == NULL) ws->iconlabel = salloc(name);
ws->iconwin = CreateWindow( "iconx", ws->windowlabel, WS_OVERLAPPEDWINDOW,
ws->posx < 0 ? 0 : ws->posx,
ws->posy < 0 ? 0 : ws->posy,
ws->width == 0 ? 400 : ws->width + BORDWIDTH,
ws->height == 0 ? 400: ws->height + BORDHEIGHT,
NULL, NULL, mswinInstance, NULL);
hdc = GetDC(ws->iconwin);
if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) && (numColors == 0)){
/* This window is on a device that supports palettes */
numColors = 2;
logpal[0].palNumEntries = 2;
logpal[0].palVersion = 0x300;
logpal[0].palPalEntry[0].peFlags = 0;
logpal[0].palPalEntry[0].peRed = 0;
logpal[0].palPalEntry[0].peGreen = 0;
logpal[0].palPalEntry[0].peBlue = 0;
logpal[0].palPalEntry[1].peFlags = 0;
logpal[0].palPalEntry[1].peRed = 255;
logpal[0].palPalEntry[1].peGreen = 255;
logpal[0].palPalEntry[1].peBlue = 255;
palette = CreatePalette(logpal);
if ((scp = malloc(2 * sizeof (struct wcolor))) == NULL) return NULL;
scp[0].c = RGB(0,0,0);
scp[0].type = SHARED;
strcpy(scp[0].name, "black");
scp[1].c = RGB(255,255,255);
scp[1].type = SHARED;
strcpy(scp[1].name, "white");
}
SelectObject(hdc, wc->font->font);
GetTextMetrics(hdc, &metrics);
wc->font->ascent = metrics.tmAscent;
wc->font->descent = metrics.tmDescent;
wc->font->charwidth = metrics.tmMaxCharWidth;
wc->font->height = metrics.tmHeight;
wc->leading = metrics.tmHeight;
ws->x = 0;
ws->y = ASCENT(w);
ws->y += w->context->dy;
ws->x += w->context->dx;
if (!ws->width || !ws->height) {
if (!ws->width) ws->width = FWIDTH(w) * 80;
if (!ws->height) ws->height = FHEIGHT(w) * 12;
SetWindowPos(ws->iconwin, ws->iconwin, ws->posx, ws->posy,
ws->width + BORDWIDTH, ws->height + BORDHEIGHT,
SWP_NOZORDER);
}
ws->pix = CreateCompatibleBitmap(hdc, ws->width, ws->height);
ReleaseDC(ws->iconwin, hdc);
if (alc_rgb(w, wc->fg) == Failed) {
return 0;
}
if (alc_rgb(w, wc->bg) == Failed) {
return 0;
}
ws->pixwidth = ws->width;
ws->pixheight = ws->height;
if (!ISTOBEHIDDEN(ws)) {
ws->win = ws->iconwin;
ShowWindow(ws->win, ncmdShow);
}
else ws->win = 0;
if (ws->initialPix) {
hdc = GetDC(ws->iconwin);
hdc2 = CreateCompatibleDC(hdc);
SelectObject(hdc2, ws->pix);
hdc3 = CreateCompatibleDC(hdc);
SelectObject(hdc3, ws->initialPix);
BitBlt(hdc2, 0, 0, ws->width, ws->height, hdc3, 0, 0, SRCCOPY);
if (ws->win)
BitBlt(hdc, 0, 0, ws->width, ws->height, hdc3, 0, 0, SRCCOPY);
DeleteDC(hdc2);
DeleteDC(hdc3);
DeleteObject(ws->initialPix);
ws->initialPix = (HBITMAP) NULL;
}
else {
imd = &ws->initimage;
if (imd->width) {
r = strimage(w, 0, 0, imd->width, imd->height, imd->paltbl,
imd->data, (word)imd->width * (word)imd->height, 0);
free((pointer)imd->paltbl);
free((pointer)imd->data);
imd->width = 0;
if (r < 0)
return 0;
}
else {
RECT r;
hdc = GetDC(ws->iconwin);
hdc2 = CreateCompatibleDC(hdc);
SelectObject(hdc2, ws->pix);
r.left = r.top = 0;
r.right = ws->width;
r.bottom = ws->height;
if (palette) {
SelectPalette(hdc, palette, FALSE);
SelectPalette(hdc2, palette, FALSE);
RealizePalette(hdc);
RealizePalette(hdc2);
}
brush = CreateBrushIndirect(&(wc->bgbrush));
if (ws->win)
FillRect(hdc, &r, brush);
FillRect(hdc2, &r, brush);
DeleteObject(brush);
ReleaseDC(ws->iconwin, hdc);
DeleteDC(hdc2);
}
}
if (ws->win)
UpdateWindow(ws->win);
return (FILE *)w;
}
int handle_config(wbp w, UINT msg, WPARAM wp, LPARAM lp)
{
struct descrip d;
wsp ws = w->window;
if (wp == SIZE_MINIMIZED) {
if (ws->win) {
SetWindowText(ws->win, ws->iconlabel);
ws->win = NULL;
}
return 1;
}
if (ws->win)
SetWindowText(ws->win, ws->windowlabel);
ws->win = ws->iconwin;
/*
* make sure text cursor stays on-screen
*/
ws->x = min(ws->x, LOWORD(lp) - FWIDTH(w));
ws->y = min(ws->y, HIWORD(lp));
/*
* if it was not a resize, drop it
*/
if (ws->width == LOWORD(lp) && ws->height == HIWORD(lp))
return 1;
ws->width = LOWORD(lp);
ws->height = HIWORD(lp);
if (! resizePixmap(w, ws->width, ws->height)) return 0;
if (!ISEXPOSED(w)) {
SETEXPOSED(w);
return 1;
}
MakeInt(RESIZED, &d);
qevent(w->window, &d, ws->width, ws->height, ~(uword)0, 0);
return 1;
}
void handle_keypress(wbp wb, UINT msg, WPARAM wp, LPARAM lp, int meta)
{
wsp ws = wb->window;
DWORD dw;
LONG t;
WORD x, y;
struct descrip d;
int flags = 0;
StrLen(d) = 1;
StrLoc(d) = (char *)&allchars[FromAscii(wp) & 0xFF];
dw = GetMessagePos();
x = LOWORD(dw);
y = HIWORD(dw);
t = GetMessageTime();
if (GetKeyState(VK_CONTROL) < 0) flags |= ControlMask;
if (GetKeyState(VK_SHIFT) < 0) flags |= ShiftMask;
if (meta) flags |= Mod1Mask;
qevent(ws, &d, x, y, t, flags);
}
void handle_mouse(wbp wb, UINT msg, WPARAM wp, LPARAM lp)
{
wsp ws = wb->window;
LONG t;
WORD x, y;
struct descrip d;
long flags = 0, eventcode;
switch(msg) {
case WM_MOUSEMOVE: /* only called if one of these three cases is true */
if (MK_LBUTTON & wp)
eventcode = MOUSELEFTDRAG;
else if (MK_RBUTTON & wp)
eventcode = MOUSERIGHTDRAG;
else if (MK_MBUTTON & wp)
eventcode = MOUSEMIDDRAG;
break;
case WM_LBUTTONDOWN:
eventcode = MOUSELEFT;
break;
case WM_MBUTTONDOWN:
eventcode = MOUSEMID;
break;
case WM_RBUTTONDOWN:
eventcode = MOUSERIGHT;
break;
case WM_LBUTTONUP:
eventcode = MOUSELEFTUP;
break;
case WM_MBUTTONUP:
eventcode = MOUSEMIDUP;
break;
case WM_RBUTTONUP:
eventcode = MOUSERIGHTUP;
break;
}
MakeInt(eventcode, &d);
x = LOWORD(lp);
y = HIWORD(lp);
/* t = GetMessageTime(); */
if (MK_CONTROL & wp) flags |= ControlMask;
if (MK_SHIFT & wp) flags |= ShiftMask;
qevent(ws, &d, x, y, t, flags);
}
LRESULT_CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
HDC hdc, hdc2;
PAINTSTRUCT ps;
RECT rect;
wbp wb = NULL;
wsp ws = NULL;
/*
* find a binding associated with the given window.
*/
for (wb = wbndngs; wb; wb=wb->next) {
ws = wb->window;
if (((ws->win == hwnd) || (ws->iconwin == hwnd) ||
(ws->pix == hwnd) || (ws->initialPix == hwnd))) break;
}
if (msg == WM_QUIT) {
wfreersc();
}
else if (!wb) {
/*
* doesn't look like its for one of our windows, pass it to
* DefWindowProc and hope for the best.
*/
}
else
switch(msg) {
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
if (IsIconic(hwnd)) {
HBRUSH hb = CreateBrushIndirect(&(wb->context->brush));
FrameRect(hdc, &rect, hb);
DeleteObject(hb);
DrawText(hdc, "Iconx", 5, &rect, DT_WORDBREAK);
}
else {
hdc2 = CreateCompatibleDC(hdc);
SelectObject(hdc2, ws->pix);
BitBlt(hdc, rect.left, rect.top,
rect.right - rect.left + 1, rect.bottom - rect.top + 1,
hdc2, rect.left, rect.top, SRCCOPY);
DeleteDC(hdc2);
}
EndPaint(hwnd, &ps);
return 0;
case WM_MOUSEMOVE:
if ( (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON) & wp )
handle_mouse(wb,msg,wp,lp);
return 0;
case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: case WM_MBUTTONDOWN:
case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP:
handle_mouse(wb,msg,wp,lp);
return 0;
case WM_CHAR:
handle_keypress(wb, msg, wp, lp, 0);
return 0;
case WM_SYSCHAR:
handle_keypress(wb, msg, wp, lp, 1);
break;
case WM_SIZE:
handle_config(wb, msg, wp, lp);
break;
case WM_MOVE:
wb->window->posx = LOWORD(lp);
wb->window->posy = HIWORD(lp);
break;
case WM_ACTIVATE:
if (wp == WA_INACTIVE && wb->window->hasCaret) {
HideCaret(wb->window->iconwin);
DestroyCaret();
wb->window->hasCaret = 0;
}
break;
case WM_KILLFOCUS:
if (wb->window->hasCaret) {
HideCaret(wb->window->iconwin);
DestroyCaret();
wb->window->hasCaret = 0;
}
break;
/* case WM_QUIT is handled prior to the switch*/
case WM_DESTROY:
if (wb->window->win == hwnd)
wb->window->win = NULL;
if (wb->window->iconwin == hwnd)
wb->window->iconwin = NULL;
if (wb->window->refcount > 0) {
PostQuitMessage(0);
return 0;
}
else if (wb->window->refcount < 0) {
wb->window->refcount = -wb->window->refcount;
}
}
return DefWindowProc(hwnd, msg, wp, lp);
}
/*
* wclose - make sure the window goes away - no questions asked
*/
int wclose(wbp w)
{
wsp ws = w->window;
if (pollevent() == -1) return -1;
if (ws->win && ws->refcount > 1) {
/*
* Decrement refcount and negate it to tell the window procedure
* that we closed the window, not the user, so don't terminate.
*/
ws->refcount--;
ws->refcount = -ws->refcount;
DestroyWindow(ws->win);
while (ws->win)
if (pollevent() == -1) return -1;
}
else {
free_binding(w);
}
return 1;
}
int pollevent()
{
wbp w;
MSG m;
extern jmp_buf mark_sj;
/* some while PeekMessage loops here, maybe one per window ? */
while (PeekMessage(&m, NULL, 0, 0, PM_NOREMOVE)) {
if (GetMessage(&m, NULL, 0, 0) == 0) longjmp(mark_sj, -1);
if (TranslateMessage(&m) == 0) {
DispatchMessage(&m);
}
}
return 400;
}
/*
* write some text to both the window and the pixmap
*/
novalue xdis(w,s,n)
register wbp w;
char *s;
int n;
{
XPoint pt;
HBRUSH hb;
XRectangle rect;
STDLOCALS(w);
STDFONT;
rect.left = ws->x; rect.right = ws->x + dc_textwidth(pixdc, s, n);
rect.top = ws->y - ASCENT(w); rect.bottom = ws->y + DESCENT(w);
/* skip resource allocation if we are offscreen */
if (!(rect.left > ws->width || rect.right < 0 ||
rect.top < 0 || rect.bottom > ws->height)) {
hb = CreateBrushIndirect(&(wc->bgbrush));
if (stdwin) {
/*
* SetBkColor() does not dither consistently with bgbrush;
* erase the background beforehand and use transparent drawing
*/
FillRect(stddc, &rect, hb);
SetBkMode(stddc, TRANSPARENT);
SetTextColor(stddc, PALCLR(wc->fg));
TextOut(stddc, ws->x, ws->y - ASCENT(w), s, n);
}
FillRect(pixdc, &rect, hb);
DeleteObject(hb);
SetBkMode(pixdc, TRANSPARENT);
SetTextColor(pixdc, PALCLR(wc->fg));
TextOut(pixdc, ws->x, ws->y - ASCENT(w), s, n);
#if 0
if (palette) {
UnrealizeObject(palette);
RealizePalette(stddc);
}
#endif
}
ws->x += dc_textwidth(pixdc, s, n);
FREE_STDLOCALS(w);
}
/*
* wputc
*/
int wputc(int ci, wbp w)
{
char c = (char)ci;
wsp ws = w->window;
wcp wc = w->context;
int y_plus_descent;
HBRUSH hb;
switch (c) {
case '\n':
ws->y += LEADING(w);
if (ws->y + DESCENT(w) > ws->height) {
RECT r;
STDLOCALS(w);
ws->y -= LEADING(w);
y_plus_descent = ws->y + DESCENT(w);
BitBlt(pixdc, 0, 0,
ws->width, y_plus_descent,
pixdc, 0, LEADING(w), SRCCOPY);
r.left = 0;
r.top = y_plus_descent - FHEIGHT(w);
r.right = ws->width;
r.bottom = ws->height;
hb = CreateBrushIndirect(&(wc->bgbrush));
FillRect(pixdc, &r, hb);
DeleteObject(hb);
if (stdwin)
BitBlt(stddc, 0, 0, ws->width, ws->height,
pixdc, 0, 0, SRCCOPY);
FREE_STDLOCALS(w);
}
/* intended fall-through */
case '\r':
/*
* set the new x position
*/
ws->x = wc->dx;
break;
case '\t':
xdis(w, " ", 8 - (XTOCOL(w,ws->x) & 7));
break;
/*
* Handle backspaces. This implements cooked mode echo handling.
*/
case '\177':
case '\010': {
int i = 0, pre_x;
/*
* Start with the last character queued up.
*/
i--;
/*
* Trot back to the control-H itself.
*/
while ((i>-EQUEUELEN) && (EVQUESUB(w,i) != c)) {
i--;
}
if (i == -EQUEUELEN) break;
/*
* Go past the control-H.
*/
i--;
/*
* Go back through any number of control-H's from prior lifetimes.
*/
while((i > -EQUEUELEN) && !isprint(EVQUESUB(w,i))) {
i--;
}
if (i == -EQUEUELEN) break;
/*
* OK, here's the character we're actually rubbing out. Back up.
*/
c = EVQUESUB(w,i);
pre_x = ws->x;
ws->x -= TEXTWIDTH(w, &c, 1);
/*
* Physically erase the character from the queue. This results in
* two control-H's present in the queue.
*/
*evquesub(w,i) = '\010';
/*
* Save the backed-up position, and draw spaces through the erased.
*/
i = ws->x;
while(ws->x < pre_x) {
xdis(w, " ",1);
}
ws->x = i;
break;
}
/*
* bell (control-G)
*/
case '\007':
break;
default:
xdis(w, &c, 1);
}
/*
* turn the cursor back on
*/
return 0;
}
/*
* wgetq - get event from pending queue
*/
int wgetq(wbp w, dptr res)
{
MSG m;
wsp ws;
int first = 0;
extern jmp_buf mark_sj;
if (!w || !(ws = w->window) || !(ws->win)) {
return -1;
}
while (1) {
/*
* grab the built up queue
*/
if (!EVQUEEMPTY(ws)) {
EVQUEGET(ws, *res);
if (ws->hasCaret) {
HideCaret(ws->iconwin);
DestroyCaret();
ws->hasCaret = 0;
}
return 1;
}
if (ISCURSORON(w) && !ws->hasCaret && GetActiveWindow() == ws->iconwin) {
CreateCaret(ws->iconwin, NULL, FWIDTH(w), FHEIGHT(w));
SetCaretPos(ws->x, ws->y - ASCENT(w));
SetCaretBlinkTime(500);
ShowCaret(ws->iconwin);
ws->hasCaret = 1;
}
if (GetMessage(&m, NULL, 0, 0) == 0) longjmp(mark_sj, -1);
if (TranslateMessage(&m) == 0) {
DispatchMessage(&m);
}
}
}
/*
* determine the new size of the client
*/
int setheight(w, height)
wbp w;
int height;
{
wsp ws = w->window;
ws->height = height;
return Succeeded;
}
/*
* determine new size of client
*/
int setwidth(w, width)
wbp w;
SHORT width;
{
wsp ws = w->window;
ws->width = width;
return Succeeded;
}
int setgeometry(w, geo)
wbp w;
char *geo;
{
wsp ws = w->window;
int width = 0, height = 0;
int x = 0, y = 0, status;
if ((status = parsegeometry(geo, &x, &y, &width, &height)) == 0)
return Error;
if (status & 1) {
ws->width = width;
ws->height = height;
}
if (status & 2) {
ws->posx = x;
ws->posy = y;
}
return Succeeded;
}
int setcanvas(w,s)
wbp w;
char *s;
{
int cmd;
wsp ws = w->window;
HWND stdwin = ws->win;
if (!strcmp(s, "iconic")) {
cmd = SW_MINIMIZE;
CLRTOBEHIDDEN(ws);
}
else if (!strcmp(s, "normal")) {
cmd = SW_RESTORE;
CLRTOBEHIDDEN(ws);
}
else if (!strcmp(s, "maximal")) {
cmd = SW_SHOWMAXIMIZED;
CLRTOBEHIDDEN(ws);
}
else if (!strcmp(s, "hidden")) {
cmd = SW_HIDE;
SETTOBEHIDDEN(ws);
}
else {
return Error;
}
if (stdwin)
ShowWindow(stdwin, cmd);
return Succeeded;
}
int seticonicstate(w, val)
wbp w;
char *val;
{
int height;
return Failed;
}
int seticonlabel(w, val)
wbp w;
char *val;
{
wsp ws = w->window;
if (ws->iconlabel != NULL) free(ws->iconlabel);
ws->iconlabel = salloc(val);
if (ws->win && IsIconic(ws->win))
SetWindowText(ws->win, ws->iconlabel);
return Succeeded;
}
int seticonpos(w, val)
wbp w;
char *val;
{
return Failed;
}
int setwindowlabel(w, val)
wbp w;
char *val;
{
wsp ws = w->window;
/*
* plug in the new string
*/
if (ws->windowlabel != NULL)
free(ws->windowlabel);
ws->windowlabel = salloc(val);
/*
* if we have to update, do it
*/
if (ws->win && !IsIconic(ws->win))
SetWindowText(ws->win, ws->windowlabel);
return Succeeded;
}
int setcursor(w, on)
wbp w;
int on;
{
wsp ws = w->window;
if (on) {
SETCURSORON(w);
}
else {
CLRCURSORON(w);
}
return Succeeded;
}
HFONT findfont(wbp w, char *family, int size, int flags)
{
int weight;
char slant, spacing;
if (size < 0) size = DEFAULTFONTSIZE;
if (flags & FONTFLAG_MEDIUM)
weight = FW_MEDIUM;
else if ((flags & FONTFLAG_DEMI) && (flags & FONTFLAG_BOLD))
weight = FW_DEMIBOLD;
else if (flags & FONTFLAG_BOLD)
weight = FW_BOLD;
else if (flags & FONTFLAG_DEMI)
weight = FW_SEMIBOLD;
else if (flags & FONTFLAG_LIGHT)
weight = FW_LIGHT;
else
weight = FW_DONTCARE;
if (flags & FONTFLAG_ITALIC)
slant = 1;
else
slant = 0;
if (flags & FONTFLAG_PROPORTIONAL)
spacing = VARIABLE_PITCH;
else if (flags & FONTFLAG_MONO)
spacing = FIXED_PITCH;
else spacing = DEFAULT_PITCH;
return CreateFont(size, 0, 0, 0, weight, slant, 0, 0, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
spacing, family);
}
/*
* Set the window's font by name.
*/
int setfont(w, s)
wbp w;
char **s;
{
int flags, size;
wsp ws = w->window;
wcp wc = w->context;
HFONT hf;
TEXTMETRIC metrics;
HDC tmpdc;
char family[MAXFONTWORD+1];
char *stdfam;
if (parsefont(*s, family, &flags, &size)) {
/*
* This is a legal Icon font spec.
* Check first for special "standard" family names.
*/
if (!strcmp(family, "mono") || !strcmp(family, "fixed")) {
stdfam = "Lucida Sans";
flags |= FONTFLAG_MONO + FONTFLAG_SANS;
}
else if (!strcmp(family, "typewriter")) {
stdfam = "courier";
flags |= FONTFLAG_MONO + FONTFLAG_SERIF;
}
else if (!strcmp(family, "sans")) {
stdfam = "swiss";
flags |= FONTFLAG_PROPORTIONAL + FONTFLAG_SANS;
}
else if (!strcmp(family, "serif")) {
stdfam = "roman";
flags |= FONTFLAG_PROPORTIONAL + FONTFLAG_SERIF;
}
else stdfam = NULL;
if (stdfam) {
/*
* Standard name: first try preferred family, then generalize.
*/
hf = findfont(w, stdfam, size, flags);
if (hf == NULL)
hf = findfont(w, NULL, size, flags);
}
else {
/*
* Any other name: must match as specified.
*/
hf = findfont(w, family, size, flags);
}
if (hf != NULL) {
if (wc->font->font)
DeleteObject(wc->font->font);
wc->font->font = hf;
free(wc->font->name);
wc->font->name = salloc(*s);
tmpdc = GetDC(ws->iconwin);
SelectObject(tmpdc, hf);
GetTextMetrics(tmpdc, &metrics);
ReleaseDC(ws->iconwin, tmpdc);
wc->font->ascent = metrics.tmAscent;
wc->font->descent = metrics.tmDescent;
wc->font->charwidth = metrics.tmMaxCharWidth;
wc->font->height = metrics.tmHeight;
return Succeeded;
}
}
return Failed;
}
/*
* rebind() - bind w's context to that of w2.
*/
int rebind(w, w2)
wbp w, w2;
{
wsp ws = w->window;
/* decrement w->context->refcount? increment w2->context->refcount? */
w->context = w2->context;
return Succeeded;
}
novalue setclip(w)
wbp w;
{
wcp wc = w->context;
if (wc->cliprgn)
DeleteObject(wc->cliprgn);
if (wc->clipw >= 0)
wc->cliprgn = CreateRectRgn(wc->clipx, wc->clipy,
wc->clipx + wc->clipw - 1,
wc->clipy + wc->cliph - 1);
else
wc->cliprgn = NULL;
}
novalue unsetclip(w)
wbp w;
{
wcp wc = w->context;
if (wc->cliprgn)
DeleteObject(wc->cliprgn);
wc->cliprgn = NULL;
}
int lowerWindow(wbp w)
{
wsp ws = w->window;
if (ws->win)
SetWindowPos(ws->win, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
return Succeeded;
}
int raiseWindow(wbp w)
{
wsp ws = w->window;
if (ws->win)
SetWindowPos(ws->win, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
return Succeeded;
}
int nativecolor(w, s, r, g, b)
wbp w;
char *s;
long *r, *g, *b;
{
return 0; /* no new colors beyond those of Icon */
}
/*
* convert an Icon linear color into an MS Windows color value
*/
SysColor mscolor(wbp w, long r, long g, long b)
{
SysColor x;
double invgamma = 1.0 / w->context->gamma;
long int red, green, blue;
red = 65535L * pow(r / 65535.0, invgamma);
green = 65535L * pow(g / 65535.0, invgamma);
blue = 65535L * pow(b / 65535.0, invgamma);
return RGB(red >> 8, green >> 8, blue >> 8);
}
/*
* Set the context's fill style by name.
*/
int setfillstyle(w, s)
wbp w;
char *s;
{
wcp wc = w->context;
if (!strcmp(s, "solid")) {
wc->brush.lbStyle = wc->fillstyle = BS_SOLID;
wc->brush.lbColor = PALCLR(wc->fg);
}
else {
if (!strcmp(s, "masked")
|| !strcmp(s, "stippled") || !strcmp(s, "patterned")) {
wc->brush.lbStyle = wc->fillstyle = BS_PATTERN;
wc->brush.lbColor = PALCLR(wc->fg);
wc->brush.lbHatch = wc->pattern;
wc->bkmode = TRANSPARENT;
}
else if (!strcmp(s, "textured")
|| !strcmp(s, "opaquestippled") || !strcmp(s, "opaquepatterned")) {
wc->brush.lbStyle = wc->fillstyle = BS_PATTERN;
wc->brush.lbColor = PALCLR(wc->fg);
wc->brush.lbHatch = wc->pattern;
}
else {
return Error;
}
}
return Succeeded;
}
/*
* Set the context's line style by name.
*/
int setlinestyle(w, s)
wbp w;
char *s;
{
wcp wc = w->context;
SHORT ltype;
if ((ltype = si_s2i(siLineTypes, s)) < 0)
return Error;
wc->pen.lopnStyle = ltype;
resetfg(w);
if(!strcmp(s, "striped")) wc->bkmode = OPAQUE;
else wc->bkmode = TRANSPARENT;
return Succeeded;
}
/*
* Set the context's line width
*/
int setlinewidth(wbp w, LONG linewid)
{
wcp wc = w->context;
wc->pen.lopnWidth.x = wc->pen.lopnWidth.y =
wc->bgpen.lopnWidth.x = wc->bgpen.lopnWidth.y = linewid;
return Succeeded;
}
/*
* Set the foreground to draw in a mutable color
*/
int isetfg(wbp w, int i)
{
char tmp[20];
wcp wc = w->context;
if (-i > numColors) return Failed;
wc->fg = (0x01000000L | -i);
sprintf(tmp, "%ld", -i);
if (wc->fgname != NULL) free(wc->fgname);
wc->fgname = salloc(tmp);
wc->pen.lopnColor = wc->fg;
wc->brush.lbStyle = BS_SOLID;
wc->brush.lbColor = wc->fg;
return Succeeded;
}
/*
* Set the context's background color by color cell.
*/
int isetbg(w, i)
wbp w;
int i;
{
char tmp[20];
wcp wc = w->context;
if (-i > numColors) return Failed;
wc->bg = (0x01000000L | -i);
sprintf(tmp, "%ld", -i);
if (wc->bgname != NULL) free(wc->bgname);
wc->bgname = salloc(tmp);
wc->bgpen.lopnColor = wc->bg;
wc->bgbrush.lbStyle = BS_SOLID;
wc->bgbrush.lbColor = wc->bg;
return ISXORREVERSE(w) ? resetfg(w) : Succeeded;
}
int getdepth(wbp w)
{
int i, j, k;
STDLOCALS(w);
i = GetDeviceCaps(pixdc, BITSPIXEL);
j = GetDeviceCaps(pixdc, PLANES);
FREE_STDLOCALS(w);
return i * j;
}
int devicecaps(wbp w, int i)
{
int rv;
STDLOCALS(w);
rv = GetDeviceCaps(pixdc, i);
FREE_STDLOCALS(w);
return rv;
}
/*
* Reset the context's foreground color to whatever it is supposed to be.
*/
int resetfg(w)
wbp w;
{
return setfg(w, w->context->fgname);
}
int alc_rgb(wbp w, SysColor rgb)
{
int i;
wsp ws = w->window;
HDC hdc;
PALETTEENTRY pe;
LOGPALETTE lp;
if (palette) {
for (i=0; i < numColors; i++) {
if (rgb == scp[i].c && scp[i].type == SHARED) break;
}
if (i == numColors) {
numColors++;
if (ResizePalette(palette, numColors) == 0) {
numColors--;
return Failed;
}
scp = realloc(scp, numColors * sizeof(struct wcolor));
if (scp == NULL) { numColors--; return Failed; }
scp[numColors - 1].c = rgb;
scp[numColors - 1].type = SHARED;
sprintf(scp[numColors - 1].name, "%d,%d,%d",
RED(rgb), GREEN(rgb), BLUE(rgb));
lp.palNumEntries = 1;
lp.palVersion = 0x300;
lp.palPalEntry[0].peFlags = 0;
lp.palPalEntry[0].peRed = RED(rgb);
lp.palPalEntry[0].peGreen = GREEN(rgb);
lp.palPalEntry[0].peBlue = BLUE(rgb);
SetPaletteEntries(palette, numColors - 1, 1, lp.palPalEntry);
hdc = GetDC(ws->iconwin);
SelectPalette(hdc, palette, FALSE);
RealizePalette(hdc);
ReleaseDC(ws->iconwin, hdc);
}
}
return Succeeded;
}
/*
* Set the context's foreground color
*/
int setfg(wbp w, char *val)
{
long r, g, b;
wcp wc = w->context;
if (parsecolor(w, val, &r, &g, &b) == Succeeded) {
wc->fg = mscolor(w, r, g, b);
if (alc_rgb(w, wc->fg) == Failed) return Failed;
if (!wc->fgname || strcmp(wc->fgname, val)) {
if (wc->fgname)
free(wc->fgname);
wc->fgname = salloc(val);
}
wc->brush.lbColor =
PALCLR(ISXORREVERSE(w) ? ((wc->fg ^ wc->bg) & 0x00FFFFFF) : wc->fg);
wc->pen.lopnColor = wc->brush.lbColor;
wc->brush.lbStyle = wc->fillstyle;
if (wc->fillstyle == BS_PATTERN)
wc->brush.lbHatch = wc->pattern;
return Succeeded;
}
return Failed;
}
/*
* Set the window context's background color
*/
int setbg(wbp w, char *val)
{
long r, g, b;
wcp wc = w->context;
if (parsecolor(w, val, &r, &g, &b) == Succeeded) {
wc->bg = mscolor(w, r, g, b);
if (alc_rgb(w, wc->bg) == Failed) return Failed;
if (wc->bgname != NULL) free(wc->bgname);
wc->bgname = salloc(val);
wc->bgpen.lopnColor = PALCLR(wc->bg);
wc->bgbrush.lbStyle = BS_SOLID;
wc->bgbrush.lbColor = PALCLR(wc->bg);
return ISXORREVERSE(w) ? resetfg(w) : Succeeded;
}
return Failed;
}
/*
* Set the gamma correction factor.
*/
int setgamma(w, gamma)
wbp w;
double gamma;
{
wcp wc = w->context;
wc->gamma = gamma;
setfg(w, wc->fgname);
setbg(w, wc->bgname);
return 1;
}
/*
* setpointer() - define a mouse pointer shape
*/
int setpointer(w, val)
wbp w;
char *val;
{
HCURSOR c;
if (!strcmp(val,"arrow")) val = IDC_ARROW;
else if (!strcmp(val,"cross")) val = IDC_CROSS;
else if (!strcmp(val,"ibeam")) val = IDC_IBEAM;
else if (!strcmp(val,"uparrow")) val = IDC_UPARROW;
else if (!strcmp(val,"wait")) val = IDC_WAIT;
else return Failed;
c = LoadCursor(mswinInstance, val);
c = SetCursor(c);
/* should save old cursor and restore it when it moves outside our window */
return Succeeded;
}
/*
* setdrawop() - set the drawing operation
*/
int setdrawop(w, val)
wbp w;
char *val;
{
wcp wc = w->context;
if (!strcmp(val,"reverse")) {
if (!ISXORREVERSE(w)) {
SETXORREVERSE(w);
wc->drawop = R2_XORPEN;
resetfg(w);
}
}
else {
if (ISXORREVERSE(w)) {
CLRXORREVERSE(w);
resetfg(w);
}
wc->drawop = si_s2i(drawops,val);
if (wc->drawop == -1) { wc->drawop = R2_COPYPEN; return Error; }
}
return Succeeded;
}
setdisplay(wbp w, char *val)
{
return Failed;
}
setimage(wbp w, char *val)
{
wsp ws = w->window;
int status;
ws->initialPix = loadimage(w, val, &(ws->width), &(ws->height),
0, &status);
if (ws->initialPix == (HBITMAP) NULL) return Failed;
return Succeeded;
}
setleading(w, i)
wbp w;
int i;
{
wcp wc = w->context;
wc->leading = i;
}
novalue toggle_fgbg(w)
wbp w;
{
SysColor tmp;
LOGPEN tpen;
LOGBRUSH tbrush;
wcp wc = w->context;
tmp = wc->fg;
wc->fg = wc->bg;
wc->bg = tmp;
tpen = wc->pen;
wc->pen = wc->bgpen;
wc->bgpen = tpen;
tbrush = wc->brush;
wc->brush = wc->bgbrush;
wc->bgbrush = tbrush;
}
int getvisual(w, answer)
wbp w;
char *answer;
{
return Failed;
}
/*
* getpos() - update the window state's notion of its current position
*/
int getpos(w)
wbp w;
{
return Succeeded;
}
novalue getfg(w, answer)
wbp w;
char *answer;
{
strcpy(answer, w->context->fgname);
}
novalue getbg(w, answer)
wbp w;
char *answer;
{
strcpy(answer, w->context->bgname);
}
novalue getlinestyle(w, answer)
wbp w;
char *answer;
{
wcp wc = w->context;
char *ptr = si_i2s(siLineTypes, wc->pen.lopnStyle);
if (ptr != NULL)
strcpy(answer, ptr);
else
strcpy(answer, "solid");
}
novalue getfntnam(w, answer)
wbp w;
char *answer;
{
strcpy(answer, w->context->font->name);
}
novalue getpointername(w, answer)
wbp w;
char *answer;
{
char *s;
wsp ws = w->window;
strcpy(answer, "???");
}
novalue getdisplay(wbp w, char *answer)
{
strcpy(answer, "local");
}
novalue getdrawop(w, answer)
wbp w;
char *answer;
{
char *s;
if (ISXORREVERSE(w)) s = "reverse";
else s = si_i2s(drawops, w->context->drawop);
if (s) sprintf(answer, "%s", s);
else strcpy(answer, "copy");
}
novalue geticonic(w, answer)
wbp w;
char *answer;
{
getcanvas(w, answer);
}
novalue getcanvas(w, answer)
wbp w;
char *answer;
{
wsp ws = w->window;
if (ws->iconwin) {
if (!IsWindowVisible(ws->iconwin)) sprintf(answer, "hidden");
else if (IsIconic(ws->iconwin)) sprintf(answer, "iconic");
else if (IsZoomed(ws->iconwin)) sprintf(answer, "maximal");
else sprintf(answer,"normal");
}
else sprintf(answer,"hidden");
}
int geticonpos(w, val)
wbp w;
char *val;
{
return Failed;
}
/*
* erase an area
*/
novalue eraseArea(w,x,y,width,height)
wbp w;
int x, y, width, height;
{
HBRUSH hb, oldbrush, oldbrush2;
XRectangle rect;
STDLOCALS(w);
hb = CreateBrushIndirect(&(wc->bgbrush));
if (stdwin) oldbrush = SelectObject(stddc, hb);
oldbrush2 = SelectObject(pixdc, hb);
rect.left = x; rect.right = x + width;
rect.top = y; rect.bottom = y + height;
if (stdwin) FillRect(stddc, &rect, hb);
FillRect(pixdc, &rect, hb);
DeleteObject(hb);
FREE_STDLOCALS(w);
}
/*
* copy an area
*/
int copyArea(w,w2,x,y,width,height,x2,y2)
wbp w, w2;
int x, y, width, height, x2, y2;
{
RECT r;
HDC srcdc, srcpixdc;
HBRUSH hb;
wsp ws1 = w->window;
STDLOCALS(w2);
/*
* setup device contexts for area copy
*/
SetROP2(pixdc, R2_COPYPEN);
hb = CreateBrushIndirect(&(wc->bgbrush));
if (stdwin)
SetROP2(stddc, R2_COPYPEN);
if (w2->window == w->window) {
srcdc = pixdc;
srcpixdc = pixdc;
}
else {
srcdc = GetDC(w->window->iconwin);
srcpixdc = CreateCompatibleDC(srcdc);
SetROP2(srcpixdc, R2_COPYPEN);
}
SelectObject(srcpixdc, w->window->pix);
/*
* copy area, write unavailable areas with bg color
*/
if (x + width < 0 || y + height < 0 || x >= ws1->pixwidth || y >= ws1->pixheight) {
/* source is entirely offscreen, just fill with background */
r.left = x2; r.top = y2; r.right = x2 + width; r.bottom = y2 + height;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
}
else {
if (x < 0) { /* fill pixels to left of source canvas with source bg */
r.left = x2; r.top = y2; r.right = x2 -x; r.bottom = y2 + height;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
x = 0;
}
if (x + width > ws1->pixwidth) { /* fill pixels to right of source */
r.left = x2 + ws1->pixwidth - x; r.top = y2;
r.right = x2 + width ; r.bottom = y2 + height;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
width = ws1->pixwidth - x;
}
if (y < 0) { /* fill pixels above source canvas with source bg */
r.left = x2; r.top = y2; r.right = x2 + width; r.bottom = y2 - y;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
y = 0;
}
if (y + height > ws1->pixheight) { /* fill pixels below source */
r.left = x2; r.top = y2 + ws1->pixheight - y;
r.right = x2 + width; r.bottom = y2 + height;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
height = ws1->pixheight - y;
}
}
if (stdwin)
BitBlt(stddc, x2, y2, width, height, srcpixdc, x, y, SRCCOPY);
BitBlt(pixdc, x2, y2, width, height, srcpixdc, x, y, SRCCOPY);
/*
* free resources
*/
if (w2->window != w->window) {
ReleaseDC(w->window->iconwin, srcdc);
DeleteDC(srcpixdc);
}
DeleteObject(hb);
FREE_STDLOCALS(w2);
return Succeeded;
}
int getdefault(w, prog, opt, answer)
wbp w;
char *prog, *opt, *answer;
{
return Failed;
}
/*
* Draw a bilevel image.
*/
int blimage(w, x, y, width, height, ch, s, len)
wbp w;
int x, y, width, height, ch;
unsigned char *s;
word len;
{
unsigned int m, msk1, c, ix, iy;
long fg, bg;
STDLOCALS(w);
/*
* Read the image string and set the pixel values. Note that
* the hex digits in sequence fill the rows *right to left*.
*/
m = width % 4;
if (m == 0)
msk1 = 8;
else
msk1 = 1 << (m - 1); /* mask for first byte of row */
fg = wc->fg;
bg = wc->bg;
ix = width;
iy = 0;
m = msk1;
while (len--) {
if (isxdigit(c = *s++)) { /* if hexadecimal character */
if (!isdigit(c)) /* fix bottom 4 bits if necessary */
c += 9;
while (m > 0) { /* set (usually) 4 pixel values */
--ix;
if (c & m) {
SetPixel(pixdc, ix, iy, PALCLR(wc->fg));
}
else if (ch != TCH1) { /* if zeroes aren't transparent */
SetPixel(pixdc, ix, iy, PALCLR(wc->bg));
}
m >>= 1;
}
if (ix == 0) { /* if end of row */
ix = width;
iy++;
m = msk1;
}
else
m = 8;
}
}
if (ix > 0) /* pad final row if incomplete */
while (ix < width)
SetPixel(pixdc, ix++, iy, PALCLR(wc->bg));
/*
* Put it on the screen.
*/
if (ws->win)
BitBlt(stddc, x, y, width, height, pixdc, x, y, SRCCOPY);
FREE_STDLOCALS(w);
return Succeeded;
}
/*
* Draw a character-per-pixel image.
*/
int strimage(w, x, y, width, height, e, s, len, on_icon)
wbp w;
int x, y, width, height;
struct palentry *e;
unsigned char *s;
word len;
int on_icon;
{
register int c;
register unsigned int ix;
unsigned int iy, tmpw;
SysColor clrlist[256];
char tmp[24];
STDLOCALS(w);
if (on_icon) {
FREE_STDLOCALS(w);
return -1;
}
/*
* Build an array of colors we need
*/
for (c = 0; c < 256; c++)
if (e[c].used && e[c].valid) {
clrlist[c] = mscolor(w, e[c].clr.red, e[c].clr.green, e[c].clr.blue);
}
/*
* Read the image string and set the pixel values.
*/
ix = x;
iy = y;
tmpw = x + width;
while (len--) {
c = *s++;
if (e[c].valid) { /* put char if valid */
SetPixel(pixdc, ix, iy, clrlist[c]);
if (++ix >= tmpw) { /* advance */
ix = x; /* reset for new row */
iy++;
#if 0
if (iy & 7 == 0) {
pollevent();
}
#endif
}
}
else if (c == TCH1 || c == TCH2) { /* advance if transparent */
if (++ix >= tmpw) {
ix = x; /* reset for new row */
iy++;
#if 0
if (iy & 7 == 0) {
pollevent();
}
#endif
}
}
}
if (ix > 0) /* pad final row if incomplete */
while (ix < width)
SetPixel(pixdc, x+ix++, y+iy, PALCLR(wc->bg));
/*
* Put it on the screen.
*/
if (on_icon) {
FREE_STDLOCALS(w);
return -1;
}
else {
if (ws->win)
BitBlt(stddc, x, y, width, height, pixdc, x, y, SRCCOPY);
}
FREE_STDLOCALS(w);
return 0;
}
/*
* imqsearch(key,base,nel) - binary search hardwired for images
*
* A binary search routine with arguments similar to qsort(3).
* Returns a pointer to the item matching "key", or NULL if none.
* This is called a LOT, so it is hardwired for speed.
* Based on Bentley, CACM 28,7 (July, 1985), p. 676.
*/
SysColor * imqsearch (SysColor key, SysColor *base, int nel)
{
int l, u, m;
SysColor * a;
l = 0;
u = nel - 1;
while (l <= u) {
m = (l + u) / 2;
a = base + m;
if (*a < key)
l = m + 1;
else if (*a > key)
u = m - 1;
else
return a;
}
while (a>base && key < *a) a--;
while (a<base+nel && key > *a) a++;
return a;
}
/*
* getimstr -- get an image as a string.
*
* Stores the specified subimage in data, one pixel per byte, and sets
* entries in paltbl corresponding to the pixel values that were used.
*/
int getimstr(w, xx, yy, width, height, paltbl, data)
wbp w;
int xx, yy, width, height;
struct palentry paltbl[DMAXCOLORS];
unsigned char *data;
{
SysColor px, lastpx, clist[DMAXCOLORS], *lp;
int i, ncolors, x, y, wd = xx + width, ht = yy + height;
STDLOCALS(w);
/*
* Make a sorted list of the pixel values of the colors that are in
* use. Search this list for every pixel and store the resulting
* list index as the color index.
*/
ncolors = 1;
clist[0] = lastpx = GetPixel(pixdc, xx, yy);
for (y = yy; y < ht; y++) {
#if 0
/* want to do pollevent here, but can't inside a STDLOCALS declaration */
if (y & 1) { /* how often to process window events? */
pollevent();
}
#endif
for (x = xx; x < wd; x++) {
px = GetPixel(pixdc, x, y);
if (px != lastpx) {
lastpx = px;
lp = imqsearch(px, clist, ncolors);
if (*lp != px) {
i = ncolors++;
while (clist + i != lp) {
clist[i] = clist[i-1];
i--;
}
clist[i] = px;
}
}
}
}
lastpx = GetPixel(pixdc, xx, yy) + 1;
for (y = yy; y < height; y++) {
#if 0
/* want to do pollevent here, but can't inside a STDLOCALS declaration */
if (y & 1 == 0) {
pollevent();
}
#endif
for (x = xx; x < width; x++) {
px = GetPixel(pixdc, x, y);
if (px != lastpx) {
lastpx = px;
lp = imqsearch(px, clist, ncolors);
if (*lp == px)
i = lp - clist;
else {
FREE_STDLOCALS(w);
return 0;
}
}
*data++ = i;
if (!paltbl[i].used) {
paltbl[i].used = 1;
paltbl[i].clr.red = RED(px) * 257;
paltbl[i].clr.green = GREEN(px) * 257;
paltbl[i].clr.blue = BLUE(px) * 257;
paltbl[i].valid = 1;
}
}
}
FREE_STDLOCALS(w);
return 1;
}
int readimage(w, filename, x, y, status)
wbp w;
char *filename;
int x, y, *status;
{
HBITMAP p;
unsigned int width, height;
HDC srcdc, srcpixdc;
if (!x && !y)
p = loadimage(w, filename, &width, &height, 1, status);
else
p = loadimage(w, filename, &width, &height, 0, status);
if (p == (HBITMAP) NULL) {
return Failed;
}
{
STDLOCALS(w);
srcdc = GetDC(ws->iconwin);
srcpixdc = CreateCompatibleDC(srcdc);
SelectObject(srcpixdc, p);
BitBlt(pixdc, x, y, width, height, srcpixdc, 0, 0, SRCCOPY);
if (stdwin)
BitBlt(stddc, x, y, width, height, srcpixdc, 0, 0, SRCCOPY);
ReleaseDC(ws->iconwin, srcdc);
DeleteDC(srcpixdc);
/*
* Make sure previous ops on p are complete, then free it.
*/
DeleteObject(p);
FREE_STDLOCALS(w);
return Succeeded;
}
}
COLORREF *crp;
long crpx, crpy, crpw, crph;
/*
* Initialize client for producing pixels from a window, or in this case,
* only create a device context once, not once per getpixel.
*/
int getpixel_init(w, x, y, width, height)
wbp w;
int x, y, width, height;
{
COLORREF *p;
wsp ws = w->window;
int i, j, x2, y2;
HDC stddc = GetDC(ws->iconwin), pixdc = CreateCompatibleDC(stddc);
if (palette) SelectPalette(pixdc, palette, FALSE);
SelectObject(pixdc, ws->pix);
if (crp) free(crp);
/* this looks like a bug for Win16 for images > 100x100 or so... */
crp = malloc( width * height * sizeof(COLORREF));
p = crp;
crpx = x;
crpy = y;
crpw = width;
crph = height;
x2 = x + width;
y2 = y + height;
for(i=y;i<y2;i++)
for(j=x;j<x2;j++) {
if ((*p++ = GetPixel(pixdc, j, i)) == (COLORREF)-1L) {
FREE_STDLOCALS(w);
return Failed;
}
}
FREE_STDLOCALS(w);
return Succeeded;
}
/*
* Return pixel (x,y) from a window
*/
int getpixel(wbp w, int x, int y, long *rv, char *s)
{
COLORREF cr = crp[(y-crpy) * crpw + (x-crpx)];
*rv = 1;
sprintf(s, "%ld,%ld,%ld",
(long)RED(cr)*257L, (long)GREEN(cr)*257L, (long)BLUE(cr)*257L);
return Succeeded;
}
int query_pointer(w, pp)
wbp w;
XPoint *pp;
{
wsp ws = w->window;
RECT r;
if (ws->win) {
GetCursorPos(pp);
GetWindowRect(ws->win, &r);
pp->x -= r.left;
pp->y -= r.top;
return Succeeded;
}
return Failed;
}
int query_rootpointer(pp)
XPoint *pp;
{
GetCursorPos(pp);
return Succeeded;
}
int seticonimage(w, dp)
wbp w;
dptr dp;
{
wsp ws = w->window;
return Succeeded;
}
/*
* dumpimage -- write an image to a disk file. Return 0 on failure.
*/
int dumpimage(wbp w, char *filename, unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
int result = 0;
FILE *fp;
HDIB dib;
HDC destdc;
HBITMAP dumppix;
STDLOCALS(w);
if (strcmp(".bmp", filename + strlen(filename) - 4) &&
strcmp(".BMP", filename + strlen(filename) - 4)) {
FREE_STDLOCALS(w);
return NoCvt;
}
/*
* extract the desired rectangle from the source bitmap
*/
if (x || y || width != ws->pixwidth || height != ws->pixheight) {
dumppix = CreateCompatibleBitmap(stddc, width, height);
destdc = CreateCompatibleDC(stddc);
SelectObject(destdc, dumppix);
BitBlt(destdc, 0, 0, width, height, pixdc, x, y, SRCCOPY);
}
else dumppix = ws->pix;
dib = BitmapToDIB(dumppix, NULL);
if (dumppix != ws->pix) {
DeleteDC(destdc);
DeleteObject(dumppix);
}
if (dib == NULL) result = Failed;
else {
if (result = SaveDIB(dib, filename)) { /* != 0 implies error */
result = Failed;
}
else result = Succeeded;
DestroyDIB(dib);
}
FREE_STDLOCALS(w);
return result;
}
/*
* loadimage
*/
HBITMAP loadimage(wbp w, char *filename, unsigned int *width,
unsigned int *height, int atorigin, int *status)
{
HDIB dib;
HBITMAP bm;
dib = LoadDIB(filename);
if (dib != NULL) {
LPSTR pdib;
bm = DIBToBitmap(dib, 0);
pdib = GlobalLock(dib);
*width = DIBWidth(pdib);
*height = DIBHeight(pdib);
GlobalUnlock(dib);
DestroyDIB(dib);
*status = 0;
return bm;
}
return NULL;
}
char *get_mutable_name(wbp w, int mute_index)
{
char *tmp;
PALETTEENTRY pe;
if (-mute_index > numColors || scp[-mute_index].type != MUTABLE) {
return NULL;
}
if (GetPaletteEntries(palette, -mute_index, 1, &pe) == 0) {
return NULL;
}
tmp = scp[-mute_index].name;
sprintf(tmp, "%d", mute_index);
sprintf(tmp + strlen(tmp) + 1, "%d,%d,%d",
(pe.peRed << 8) | 0xff, (pe.peGreen << 8) | 0xff, (pe.peBlue << 8) | 0xff);
return tmp + strlen(tmp) + 1;
}
int set_mutable(wbp w, int i, char *s)
{
long r, g, b;
UINT rv;
PALETTEENTRY pe;
if (palette == 0) return Failed;
{
STDLOCALS(w);
if (parsecolor(w, s, &r, &g, &b) != Succeeded) {
FREE_STDLOCALS(w);
return Failed; /* invalid color specification */
}
pe.peRed = r >> 8;
pe.peGreen = g >> 8;
pe.peBlue = b >> 8;
pe.peFlags = PC_RESERVED;
raiseWindow(w); /* mutable won't mutate if window isn't active */
#if 1
AnimatePalette(palette, -i, 1, &pe);
rv = SetPaletteEntries(palette, -i, 1, &pe);
#endif
UnrealizeObject(palette);
RealizePalette(stddc);
AnimatePalette(palette, -i, 1, &pe);
FREE_STDLOCALS(w);
}
return Succeeded;
}
novalue free_mutable(wbp w, int mute_index)
{
}
/*
* Allocate a mutable color
*/
int mutable_color(wbp w, dptr argv, int argc, int *retval)
{
long r, g, b;
tended char *str;
LOGPALETTE lp;
{
STDLOCALS(w);
if (!stddc || ((GetDeviceCaps(stddc, RASTERCAPS) & RC_PALETTE) == 0)) {
FREE_STDLOCALS(w);
return Failed;
}
numColors++;
scp = realloc(scp, numColors * sizeof(struct wcolor));
if (scp == NULL) {
FREE_STDLOCALS(w);
return Failed;
}
scp[numColors-1].c = -(numColors-1);
sprintf(scp[numColors-1].name, "%d:", -(numColors-1));
scp[numColors-1].type = MUTABLE;
if (ResizePalette(palette, numColors) == 0) {
FREE_STDLOCALS(w);
return Failed;
}
if (argc > 0) { /* set the color */
if (argc != 1) {
FREE_STDLOCALS(w);
return Error;
}
/*
* old-style check for C integer
*/
else if (argv[0].dword == D_Integer) {/* check for color cell */
if (IntVal(argv[0]) >= 0) {
FREE_STDLOCALS(w);
return Failed; /* must be negative */
}
if (GetPaletteEntries(palette, -IntVal(argv[0]),
1, lp.palPalEntry) == 0) {
FREE_STDLOCALS(w);
return Error;
}
/* convert to linear color? */
}
else {
if (!cnv:C_string(argv[0],str)) {
FREE_STDLOCALS(w);
ReturnErrVal(103,argv[0], Error);
}
if (parsecolor(w, str, &r, &g, &b) != Succeeded) {
/* reduce logical palette size and count */
FREE_STDLOCALS(w);
numColors--;
ResizePalette(palette, numColors);
return Failed; /* invalid color specification */
}
lp.palPalEntry[0].peRed = r >> 8;
lp.palPalEntry[0].peGreen = g >> 8;
lp.palPalEntry[0].peBlue = b >> 8;
}
lp.palNumEntries = 1;
lp.palVersion = 0x300;
lp.palPalEntry[0].peFlags = PC_RESERVED;
SetPaletteEntries(palette, numColors - 1, 1, lp.palPalEntry);
UnrealizeObject(palette);
RealizePalette(stddc);
}
*retval = -(numColors - 1);
FREE_STDLOCALS(w);
return Succeeded;
}
}
novalue freecolor(wbp w, char *s)
{
}
/*
* drawarcs() - assumes x and y are already fixed up for the bitmap
*/
void drawarcs(wbp wb, XArc *arcs, int narcs)
{
register XArc *arc = arcs;
int i, halfwidth, halfheight, x1, y1, x2, y2, right, bottom;
double a1_a2;
HPEN hp, oldpen, oldpen2;
STDLOCALS(wb);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
for (i = 0; i < narcs; i++, arc++) {
halfwidth = arc->width >> 1;
halfheight = arc->height >> 1;
arc->angle1 = -arc->angle1 - arc->angle2;
a1_a2 = arc->angle1 + arc->angle2;
x1 = arc->x + halfwidth + (int)(halfwidth * cos(arc->angle1));
y1 = arc->y + halfheight - (int)(halfheight * sin(arc->angle1));
x2 = arc->x + halfwidth + (int)(halfwidth * cos(a1_a2));
y2 = arc->y + halfheight - (int)(halfheight * sin(a1_a2));
right = arc->x + arc->width;
bottom = arc->y + arc->height;
if (ws->win)
Arc(stddc, arc->x, arc->y, right, bottom, x1, y1, x2, y2);
Arc(pixdc, arc->x, arc->y, right, bottom, x1, y1, x2, y2);
}
if (stdwin) SelectObject(stddc, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
FREE_STDLOCALS(wb);
return;
}
/*
* drawlines - Support routine for DrawLine
*/
void drawlines(wbinding *wb, XPoint *points, int npoints)
{
int i, diff, bheight;
HPEN hp, oldpen, oldpen2;
STDLOCALS(wb);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
if (ws->win) {
SetBkMode(stddc, wc->bkmode);
Polyline(stddc, points, npoints);
}
SetBkMode(pixdc, wc->bkmode);
Polyline(pixdc, points, npoints);
if (stdwin) SelectObject(stddc, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
FREE_STDLOCALS(wb);
return;
}
/*
* drawpoints() -
* Parameters - the window binding for output, an array of points (assumed
* to be fixed up for bitmap) and the number of points
*/
void drawpoints(wbinding *wb, XPoint *points, int npoints)
{
int i, diff, bheight;
XPoint *p;
STDLOCALS(wb);
if (stdwin) {
for(i = 0, p = points; i < npoints; i++, p++) {
SetPixel(stddc, p->x, p->y, PALCLR(wc->fg));
SetPixel(pixdc, p->x, p->y, PALCLR(wc->fg));
}
}
else {
for(i = 0, p = points; i < npoints; i++, p++) {
SetPixel(pixdc, p->x, p->y, PALCLR(wc->fg));
}
}
FREE_STDLOCALS(wb);
return;
}
/*
* drawsegments() -
*/
void drawsegments(wbinding *wb, XSegment *segs, int nsegs)
{
int i, diff, bheight;
XPoint ps[2];
HPEN hp, oldpen, oldpen2;
STDLOCALS(wb);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
if (stdwin) {
SetBkMode(stddc, wc->bkmode);
for (i = 0; i < nsegs; i++) {
Polyline(stddc, (POINT *)(segs+i), 2);
}
}
SetBkMode(pixdc, wc->bkmode);
for (i = 0; i < nsegs; i++) {
Polyline(pixdc, (POINT *)(segs+i), 2);
}
if (stdwin) SelectObject(stddc, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
FREE_STDLOCALS(wb);
return;
}
/*
* drawstrng()
*/
void drawstrng(wbinding *wb, int x, int y, char *s, int slen)
{
STDLOCALS(wb);
STDFONT;
if (stdwin) {
SetBkMode(stddc, TRANSPARENT);
if (wc->fg != RGB(0, 0, 0)) SetTextColor(stddc, PALCLR(wc->fg));
if (wc->bg != RGB(255, 255, 255)) SetBkColor(stddc, PALCLR(wc->bg));
TextOut(stddc, x, y - ASCENT(wb), s, slen);
}
SetBkMode(pixdc, TRANSPARENT);
if (wc->fg != RGB(0, 0, 0)) SetTextColor(pixdc, PALCLR(wc->fg));
if (wc->bg != RGB(255, 255, 255)) SetBkColor(pixdc, PALCLR(wc->bg));
TextOut(pixdc, x, y - ASCENT(wb), s, slen);
FREE_STDLOCALS(wb);
return;
}
/*
* fillarcs
*/
void fillarcs(wbp wb, XArc *arcs, int narcs)
{
register XArc *arc = arcs;
int i, diff, bheight;
HBRUSH hb, oldbrush, oldbrush2;
POINT pts[3];
HPEN hp, oldpen, oldpen2;
STDLOCALS(wb);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
hb = CreateBrushIndirect(&(wc->brush));
if (stdwin) oldbrush = SelectObject(stddc, hb);
oldbrush2 = SelectObject(pixdc, hb);
for (i = 0; i < narcs; i++, arc++) {
if (arc->angle2 >= 2 * Pi) {
if (stdwin)
Ellipse(stddc, arc->x, arc->y,
arc->x + arc->width, arc->y + arc->height);
Ellipse(pixdc, arc->x, arc->y,
arc->x + arc->width, arc->y + arc->height);
}
else {
arc->angle1 = -arc->angle1 - arc->angle2;
pts[0].x = arc->x + (arc->width>>1);
pts[0].y = arc->y + (arc->height>>1);
pts[1].x = arc->x + (arc->width>>1) + (int)(((arc->width + 1)>>1) * cos(arc->angle1));
pts[1].y = arc->y + (arc->height>>1) - (int)(((arc->height )>>1) * sin(arc->angle1));
pts[2].x = arc->x + (arc->width>> 1) + (int)(((arc->width + 1)>>1) * cos(arc->angle1+arc->angle2));
pts[2].y = arc->y + (arc->height>>1) - (int)(((arc->height )>>1) * sin(arc->angle1+arc->angle2));
if (stdwin) {
Pie(stddc, arc->x, arc->y,
arc->x + arc->width, arc->y + arc->height,
pts[1].x, pts[1].y, pts[2].x, pts[2].y);
}
Pie(pixdc, arc->x, arc->y,
arc->x + arc->width, arc->y + arc->height,
pts[1].x, pts[1].y, pts[2].x, pts[2].y);
}
}
if (stdwin) SelectObject(stddc, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
if (stdwin) SelectObject(stddc, oldbrush);
SelectObject(pixdc, oldbrush2);
DeleteObject(hb);
FREE_STDLOCALS(wb);
return;
}
/*
* fillrectangles
*/
void fillrectangles(wbp wb, XRectangle *recs, int nrecs)
{
int i, diff, bheight;
HBRUSH hb, oldbrush, oldbrush2;
STDLOCALS(wb);
hb = CreateBrushIndirect(&(wc->brush));
if (stdwin) oldbrush = SelectObject(stddc, hb);
oldbrush2 = SelectObject(pixdc, hb);
for (i = 0; i < nrecs; i++) {
recs[i].right += recs[i].left;
recs[i].bottom += recs[i].top;
if (stdwin) FillRect(stddc, (recs+i), hb);
FillRect(pixdc, (recs+i), hb);
}
if (stdwin) SelectObject(stddc, oldbrush);
SelectObject(pixdc, oldbrush2);
DeleteObject(hb);
FREE_STDLOCALS(wb);
return;
}
/*
* drawrectangles - draw nrecs # of rectangles in array recs to binding w
*/
void drawrectangles(wbp w, XRectangle *recs, int nrecs)
{
register XRectangle *r;
LOGBRUSH lb;
HBRUSH hb, oldbrush, oldbrush2;
HPEN hp, oldpen, oldpen2;
STDLOCALS(w);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
lb.lbStyle = BS_NULL;
hb = CreateBrushIndirect(&lb);
if (stdwin) oldbrush = SelectObject(stddc, hb);
oldbrush2 = SelectObject(pixdc, hb);
for (r = recs; r < recs + nrecs; r++) {
r->right += r->left + 1;
r->bottom += r->top + 1;
if (stdwin) Rectangle(stddc, r->left, r->top, r->right, r->bottom);
Rectangle(pixdc, r->left, r->top, r->right, r->bottom);
}
if (stdwin) SelectObject(stddc, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
if (stdwin) SelectObject(stddc, oldbrush);
SelectObject(pixdc, oldbrush2);
DeleteObject(hb);
FREE_STDLOCALS(w);
return;
}
/*
* fillpolygon
*/
void fillpolygon(wbp w, XPoint *pts, int npts)
{
HBRUSH hb, oldbrush;
HPEN hp, oldpen, oldpen2;
STDLOCALS(w);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
hb = CreateBrushIndirect(&(wc->brush));
if (stdwin) {
oldbrush = SelectObject(stddc, hb);
Polygon(stddc, pts, npts);
SelectObject(stddc, oldbrush);
}
oldbrush = SelectObject(pixdc, hb);
Polygon(pixdc, pts, npts);
SelectObject(pixdc, oldbrush);
DeleteObject(hb);
if (stdwin) SelectObject(stddc, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
FREE_STDLOCALS(w);
}
LONG NumWindows = 0;
/*
* allocate a context. Can't be called until w has a display and window.
*/
wcp alc_context(w)
wbp w;
{
int i;
wcp wc;
GRFX_ALLOC(wc, _wcontext);
wc->bkmode = OPAQUE; /* at present, only used in line drawing */
wc->fg = RGB(0,0,0);
wc->bg = RGB(255,255,255);
wc->fgname = salloc("black");
wc->bgname = salloc("white");
wc->pen.lopnStyle = PS_SOLID;
wc->pen.lopnWidth.x = wc->pen.lopnWidth.y = 1;
wc->pen.lopnColor = PALCLR(wc->fg);
wc->bgpen.lopnStyle = PS_SOLID;
wc->bgpen.lopnWidth.x = wc->bgpen.lopnWidth.y = 1;
wc->bgpen.lopnColor = PALCLR(wc->bg);
wc->fillstyle = BS_SOLID;
wc->brush.lbStyle = BS_SOLID;
wc->brush.lbColor = PALCLR(wc->fg);
wc->bgbrush.lbStyle = BS_SOLID;
wc->bgbrush.lbColor = PALCLR(wc->bg);
wc->gamma = GammaCorrection;
wc->drawop = R2_COPYPEN;
wc->font = (wfp)alloc(sizeof (struct _wfont));
wc->font->name = salloc("fixed");
wc->font->font = CreateFont(16,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, NULL);
wc->font->charwidth = 8;
wc->leading = 16;
GRFX_LINK(wc, wcntxts);
return wc;
}
/*
* allocate a context, cloning attributes from an existing context
*/
wcp clone_context(w)
wbp w;
{
wcp wc, wc2 = w->context;
wsp ws = w->window;
wbinding tmp;
int i;
GRFX_ALLOC(wc, _wcontext);
tmp.window = ws;
tmp.context = wc;
/*
* copy over some stuff
*/
wc->clipx = wc2->clipx;
wc->clipy = wc2->clipy;
wc->clipw = wc2->clipw;
wc->cliph = wc2->cliph;
wc->dx = wc2->dx;
wc->dy = wc2->dy;
if (wc2->patternname)
wc->patternname = salloc(wc2->patternname);
/* clone needs to make a copy of the pattern */
wc->bkmode = wc2->bkmode;
wc->fg = wc2->fg;
wc->bg = wc2->bg;
wc->fgname = salloc(wc2->fgname);
wc->bgname = salloc(wc2->bgname);
wc->pen = wc2->pen;
if (ISXORREVERSEW(wc)) {
wc->brush.lbColor = PALCLR((wc->fg ^ wc->bg) & 0x00FFFFFF);
}
else {
wc->brush.lbColor = PALCLR(wc->fg);
}
wc->bgpen = wc2->bgpen;
wc->fillstyle = wc2->fillstyle;
wc->brush.lbStyle = wc->fillstyle;
wc->bgbrush.lbStyle = wc->fillstyle;
wc->bgbrush.lbColor = PALCLR(wc->bg);
wc->gamma = wc2->gamma;
wc->drawop = wc2->drawop;
wc->font = (wfp)alloc(sizeof (struct _wfont));
wc->font->name = salloc("fixed");
wc->font->font = CreateFont(13,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, NULL);
wc->leading = wc2->leading;
setfont(&tmp, &(wc2->font->name));
GRFX_LINK(wc, wcntxts);
return wc;
}
/*
* allocate a window state structure
*/
wsp alc_winstate()
{
int i;
wsp ws;
GRFX_ALLOC(ws, _wstate);
ws->bits = 1024; /* echo ON; others OFF */
ws->filep = nulldesc;
ws->listp = nulldesc;
GRFX_LINK(ws, wstates);
return ws;
}
/*
* free a window state
*/
int free_window(ws)
wsp ws;
{
ws->refcount--;
if(ws->refcount == 0) {
if (ws->win) /* && IsWindowVisible(ws->win))*/
DestroyWindow(ws->win);
/* ws->win = 0;*/
if (ws->iconwin && ws->iconwin != ws->win) {
if (IsWindowVisible(ws->iconwin))
DestroyWindow(ws->iconwin);
else DestroyWindow(ws->iconwin);
}
/* ws->iconwin = 0;*/
/* while (ws->win)
if (pollevent() == -1) return -1;
*/
if (ws->pix)
DeleteObject(ws->pix);
ws->pix = 0;
if (ws->iconpix)
DeleteObject(ws->iconpix);
ws->iconpix = 0;
if (ws->initialPix)
DeleteObject(ws->initialPix);
ws->initialPix = 0;
GRFX_UNLINK(ws, wstates);
}
return 0;
}
/*
* free a window context
*/
novalue free_context(wc)
wcp wc;
{
wc->refcount--;
if(wc->refcount == 0) {
if (wc->cliprgn)
DeleteObject(wc->cliprgn);
wc->cliprgn = 0;
if (wc->pattern)
DeleteObject(wc->pattern);
wc->pattern = 0;
if (wc->font) {
if (wc->font->font)
DeleteObject(wc->font->font);
wc->font->font = 0;
if (wc->font->name)
free(wc->font->name);
wc->font->name = 0;
free(wc->font);
}
wc->font = 0;
if (wc->fgname) free(wc->fgname);
wc->fgname = 0;
if (wc->bgname) free(wc->bgname);
wc->bgname = 0;
GRFX_UNLINK(wc, wcntxts);
}
}
int walert(wbp w, int volume)
{
MessageBeep(0);
}
int patbits[] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0xFF,0xEF,0xFF,0xFE,0xFF,0xEF,0xFF,
0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,
0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
0x01,0x00,0x10,0x00,0x01,0x00,0x10,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,
0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,
0x82,0x44,0x28,0x10,0x28,0x44,0x82,0x01,
0x0F,0x0F,0x0F,0x0F,0xF0,0xF0,0xF0,0xF0,
0x1B,0x18,0x81,0xB1,0x36,0x06,0x60,0x63,
0x02,0x02,0x05,0xF8,0x20,0x20,0x50,0x8F,
0x03,0x84,0x48,0x30,0x03,0x84,0x48,0x30,
};
/*
* SetPattern
*/
int SetPattern(w, name, len)
wbp w;
char *name;
int len;
{
int width, nbits;
int i, j;
int symbol;
C_integer v, bits[MAXXOBJS];
HBITMAP p;
char data[MAXXOBJS];
char *buf = data;
wcp wc = w->context;
if (wc->patternname != NULL)
free(wc->patternname);
wc->patternname = malloc(len+1);
mystrncpy(wc->patternname, name, len);
/*
* If the pattern starts with a number it is a width , bits encoding
*/
if ((len > 0) && isdigit(name[0])) {
nbits = MAXXOBJS;
switch (parsepattern(name, len, &width, &nbits, bits)) {
case Failed:
return Failed;
case Error:
ReturnErrNum(145, Error);
}
if (w->window->iconwin == NULL) return Succeeded;
return SetPatternBits(w, width, bits, nbits);
}
/*
* Otherwise, it is a named pattern. Find the symbol id.
*/
if ((symbol = si_s2i(siPatternSyms, wc->patternname)) >= 0) {
if (w->window->iconwin == NULL) return Succeeded;
for(i = 0; i < 8; i++) {
v = ~(patbits[symbol * 8 + i]);
*buf++ = v;
}
p = CreateBitmapFromData(data);
if (wc->pattern)
DeleteObject(wc->pattern);
wc->pattern = p;
if (wc->fillstyle == BS_PATTERN) {
wc->brush.lbStyle = BS_PATTERN;
wc->brush.lbColor = PALCLR(wc->fg);
wc->brush.lbHatch = p;
}
return Succeeded;
}
ReturnErrNum(145, Error);
}
/*
* Create an 8x8 bitmap from some data
*/
HBITMAP CreateBitmapFromData(char *data)
{
WORD *wBits = alloc(8 * sizeof(WORD));
HBITMAP rv;
int i;
static BITMAP bitmap = { 0, 8, 8, 2, 1, 1};
for (i = 0; i < 8; i++)
wBits[i] = data[i];
bitmap.bmBits = (LPSTR) wBits;
rv = CreateBitmapIndirect(&bitmap);
free(wBits);
return rv;
}
int SetPatternBits(w, width, bits, nbits)
wbp w;
int width;
C_integer *bits;
int nbits;
{
C_integer v;
int i, j;
HBITMAP p;
char data[MAXXOBJS];
char *buf = data;
wcp wc = w->context;
if (width != 8 || nbits != 8)
return Failed;
for(i = 0; i < nbits; i++) {
v = bits[i];
for(j=0; j<width; j+=8) {
*buf++ = v;
v >>= 8;
}
}
p = CreateBitmapFromData(data);
if (wc->pattern)
DeleteObject(wc->pattern);
wc->pattern = p;
if (wc->fillstyle == BS_PATTERN) {
wc->brush.lbStyle = BS_PATTERN;
wc->brush.lbColor = PALCLR(wc->fg);
wc->brush.lbHatch = p;
}
return Succeeded;
}
int pixmap_init(w)
wbp w;
{
wsp ws = w->window;
resizePixmap(w, ws->width, ws->height);
return Succeeded;
}
int do_config(w, status)
wbp w;
int status;
{
wsp ws = w->window;
int wid = ws->width, ht = ws->height;
int posx = ws->posx, posy = ws->posy;
if (! resizePixmap(w, wid, ht))
return Failed;
if (ws->win) {
pollevent();
if (status == 3) {
SetWindowPos(ws->win, ws->win, posx, posy,
wid + BORDWIDTH, ht + BORDHEIGHT, SWP_NOZORDER);
}
else if (status == 2)
SetWindowPos(ws->win, ws->win, 0, 0,
wid + BORDWIDTH, ht + BORDHEIGHT, SWP_NOMOVE|SWP_NOZORDER);
else if (status == 1)
SetWindowPos(ws->win, ws->win, posx, posy, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}
return Succeeded;
}
/*
* UpdateCursorPos
*/
void UpdateCursorPos(wsp ws, wcp wc)
{
}
int resizePixmap(wbp w, int width, int height)
{
HDC hdc, hdc2, hdc3;
HBITMAP newpix;
HBRUSH hb;
LOGBRUSH lb;
XRectangle rect;
wsp ws = w->window;
int x = ws->pixwidth, y = ws->pixheight;
if (ISEXPOSED(w)) {
if (ws->pixwidth >= width && ws->pixheight >= height) {
return 1;
}
ws->pixheight = max(ws->pixheight, height);
ws->pixwidth = max(ws->pixwidth, width);
}
else {
ws->pixwidth = width;
ws->pixheight = height;
}
hdc = GetDC(ws->iconwin);
newpix = CreateCompatibleBitmap (hdc, ws->pixwidth, ws->pixheight);
if (ws->pix) {
hdc2 = CreateCompatibleDC(hdc);
SelectObject(hdc2, ws->pix);
}
hdc3 = CreateCompatibleDC(hdc);
SelectObject(hdc3, newpix);
if (palette) {
SelectPalette(hdc, palette, FALSE);
if (ws->pix) SelectPalette(hdc2, palette, FALSE);
SelectPalette(hdc3, palette, FALSE);
RealizePalette(hdc);
if (ws->pix) RealizePalette(hdc2);
RealizePalette(hdc3);
}
lb.lbStyle = BS_SOLID;
lb.lbColor = PALCLR(w->context->bg);
hb = CreateBrushIndirect(&lb);
/*
* initialize the new pixmap, including areas not in the old pixmap.
*/
rect.left = 0; rect.right = ws->pixwidth;
rect.top = 0; rect.bottom = ws->pixheight;
FillRect(hdc3, &rect, hb);
if (ws->win)
FillRect(hdc, &rect, hb);
if (ws->pix) BitBlt(hdc3, 0, 0, x - 2, y - 1, hdc2, 0, 0, SRCCOPY);
if (ws->win)
BitBlt(hdc, 0, 0, ws->pixwidth, ws->pixheight, hdc3, 0, 0, SRCCOPY);
DeleteDC(hdc3);
if (ws->pix) DeleteDC(hdc2);
ReleaseDC(ws->iconwin, hdc);
if (ws->pix) DeleteObject(ws->pix);
DeleteObject(hb);
ws->pix = newpix;
return 1;
}
/*
* CreateWinDC - create a device context for drawing on the window
* In addition, select objects specified by flags.
*/
HDC CreateWinDC(wbp w)
{
wsp ws = w->window;
wcp wc = w->context;
HDC hdc = GetDC(ws->iconwin);
if (numColors > 0) {
SelectPalette(hdc, palette, FALSE);
/* UnrealizeObject(palette); */
RealizePalette(hdc);
if (numRealized < numColors) {
numRealized = numColors;
if (RealizePalette(hdc) == 0) /* noop */;
/* return NULL; */
}
}
SetROP2(hdc, wc->drawop);
if (wc->clipw >= 0){
SelectClipRgn(hdc, wc->cliprgn);
}
return hdc;
}
HDC CreatePixDC(wbp w, HDC hdc)
{
wsp ws = w->window;
wcp wc = w->context;
HDC hdc2 = CreateCompatibleDC(hdc);
if (numColors > 0) {
SelectPalette(hdc2, palette, FALSE);
RealizePalette(hdc2);
}
SelectObject(hdc2, w->window->pix);
SetROP2(hdc2, wc->drawop);
if (wc->clipw >= 0){
SelectClipRgn(hdc2, wc->cliprgn);
}
return hdc2;
}
int setinputmask(wbp w, char *val)
{
wsp ws = w->window;
if (strchr(val,'m')) {
/* ws->inputmask |= PointerMotionMask;
if (ws->win)
XSelectInput(ws->display->display, ws->win, ws->inputmask); */
}
else {
/* ws->inputmask &= ~PointerMotionMask;
if (ws->win)
XSelectInput(ws->display->display, ws->win, ws->inputmask); */
}
return Succeeded;
}
/*
* compute a text width for a current device context (typically pixdc)
*/
int dc_textwidth(HDC dc, char *s, int n)
{
SIZE sz;
/*
* GetTextExtentPoint32(dc, s, n, &sz) gives incorrect behavior
* under Win32s
*/
GetTextExtentPoint(dc, s, n, &sz);
return (int)sz.cx;
}
int textWidth(wbp w, char *s, int n)
{
int rv;
wsp ws = w->window;
HDC stddc = GetDC(ws->iconwin);
SelectObject(stddc, w->context->font->font);
rv = dc_textwidth(stddc, s, n);
ReleaseDC(ws->iconwin, stddc);
return rv;
}
novalue warpPointer(w, x, y)
wbp w;
int x, y;
{
wsp ws = w->window;
SetCursorPos(ws->posx + x, ws->posy + y);
}
/*
* free all Windows resources allocated by this instantiation of iconx
*/
void wfreersc()
{
while (wstates != NULL) {
wstates->refcount = 1;
free_window(wstates);
}
while (wcntxts != NULL) {
wcntxts->refcount = 1;
free_context(wcntxts);
}
if (palette) {
DeleteObject(palette);
palette = 0;
}
}
#else /* Graphics */
static char aaa;
#endif /* Graphics */