home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
src
/
runtime
/
rmswin.ri
< prev
next >
Wrap
Text File
|
2002-01-18
|
108KB
|
4,371 lines
/*
* rmswin.ri - Microsoft Windows-specific graphics interface code.
*
* Todo:
* geticonpos
* seticonimage
* free_mutable
* freecolor
*
* Untested:
* toggle_fgbg
* rebind
* geticonic
* getimstr
* getfntnam
* dumpimage
* getpointername
*
* Blown off:
* 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)
int winInitialized = 0;
int BORDHEIGHT;
int BORDWIDTH;
/*
* check for double-byte character set versions of Windows
*/
CPINFO cpinfo;
int MAXBYTESPERCHAR;
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_DOT},
{"longdashed", PS_DASH},
{"solid", PS_SOLID},
{"striped", PS_DOT}
};
HINSTANCE mswinInstance;
int ncmdShow;
int FoundIt, FoundNew;
HWND NewWin;
char *lookingfor;
struct WNDlist {
HWND w;
struct WNDlist *next;
} * wlhead;
struct WNDlist *wlinsert(HWND w)
{
struct WNDlist *x = malloc(sizeof (struct WNDlist));
x->w = w;
x->next = wlhead;
wlhead = x;
}
int wlsearch(HWND w)
{
struct WNDlist *x;
for(x=wlhead;x;x=x->next) if (x->w == w) return 1;
return 0;
}
void wlfree()
{
struct WNDlist *x = wlhead;
while (wlhead) {
x = wlhead->next;
free(wlhead);
wlhead = x;
}
}
BOOL_CALLBACK myenumproc(HWND w, LPARAM l)
{
wlinsert(w);
return 1;
}
BOOL_CALLBACK myenumproc2(HWND w, LPARAM l)
{
if (!wlsearch(w)) {
FoundNew++;
NewWin = w;
}
return 1;
}
char * strcasestr(char *haystack, char *needle)
{
int len = strlen(needle);
while (*haystack) {
if (strncasecmp(haystack, needle, len) == 0) return haystack;
haystack++;
}
return 0;
}
BOOL_CALLBACK myenumproc3(HWND w, LPARAM l)
{
char s[64], s2[64];
GetWindowText(w, s2, 63);
/*
* Conditions to find a window:
* 1) wasn't in the list of windows already present when we launched.
* 2) either contains the argv[0] program name, or
* was first window to appear after we called WinExec().
*/
if (!wlsearch(w)) {
FoundNew++;
if ((strcasestr(s2, lookingfor) != NULL) || (NewWin && (NewWin == w))) {
FoundIt++;
}
}
return 1;
}
char *lookcmdname(char *buf, char *s)
{
char *t = buf;
while (*s) {
*t++ = *s;
if (*s == '\\') t = buf;
s++;
}
*t++ = '\0';
s = buf;
while (*s) {
if (*s == '.') *s = '\0';
s++;
}
return buf;
}
int mswinsystem(char *s)
{
int i, rv, j, background = 0;
char s2[256], s3[256];
char **argv;
int argc;
DWORD d = GetVersion();
int lo, hi, major, minor, iswin31;
lo = LOWORD(d);
hi = HIWORD(d);
major = lo & 0xFF;
minor = (lo & 0xFF00)>>8,
iswin31 = ((major == 3) && (minor <= 11));
strncpy(s2, s, 255);
s2[255] = '\0';
strncpy(s3, s, 255);
s3[255] = '\0';
for(i=0;s3[i];i++){
if (s3[i] == ' ' || s3[i] == '\t') {
s3[i] = '\0';
break;
}
}
for(i=strlen(s2)-1; i > 0 && (s2[i] == ' ' || s2[i] == '\t'); i--);
/*
* if it is a "background task", launch using WinExec.
*/
if (i>0 && s2[i] == '&') {
s2[i] = '\0';
while (s2[--i] == ' ') s2[i] = '\0';
i = WinExec(s2, SW_SHOW);
if ( i >= 32 ) return 0;
return -1;
}
/*
* if we've got a reasonable operating system, launch using spawnvp
* and wait for _P_WAIT. At the moment, this gives no indication of
* actually working; the program is launched but we don't wait for it.
*/
if (!iswin31) {
argc = CmdParamToArgv(s, &argv);
rv = _spawnvp(_P_WAIT, s3, argv);
free(argv);
return rv;
}
/*
* this remaining code is a colossal kludge to support waiting for
* a launched application to terminate under Win32s, which ignores
* the _P_WAIT flag to the spawn* functions.
*/
for(i=0;s2[i];i++){
if (s2[i] == ' ' || s2[i] == '\t' || s2[i] == '.') {
s2[i] = '\0';
break;
}
}
wlfree();
lookingfor = NULL;
EnumWindows(MakeProcInstance(myenumproc, mswinInstance), 0L);
i = WinExec(s, SW_SHOW);
if ( i >= 32 ) {
/*
* Wait for the task to finish. First wait up to two seconds
* for at least one new window to show up.
*/
lookcmdname(s3, s2);
lookingfor = s3;
FoundNew = 0;
for(j=0; j<10; j++) {
EnumWindows(MakeProcInstance(myenumproc2, mswinInstance), 0L);
if (FoundNew) break;
Sleep(200);
}
if (FoundNew != 1) NewWin = NULL;
/*
* Now wait as long as we found a new window with our
* argv[0] in its title present.
*/
for(;;) {
FoundIt = 0;
EnumWindows(MakeProcInstance(myenumproc3, mswinInstance), 0L);
if(!FoundIt) break;
Sleep(10);
pollevent();
}
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;
HBITMAP oldpix, oldpix2;
HFONT oldfont;
if (! winInitialized++) {
BORDWIDTH = FRAMEWIDTH * 2;
BORDHEIGHT = TITLEHEIGHT + FRAMEHEIGHT * 2 - 1;
GetCPInfo(CP_ACP, &cpinfo);
MAXBYTESPERCHAR = cpinfo.MaxCharSize;
}
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);
if (ws->posx < 0) ws->posx = 0;
if (ws->posy < 0) ws->posy = 0;
/*
* create the window
*/
ws->iconwin = CreateWindow( "iconx", ws->windowlabel, WS_OVERLAPPEDWINDOW,
ws->posx, 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");
}
oldfont = SelectObject(hdc, wc->font->font);
GetTextMetrics(hdc, &metrics);
wc->font->charwidth = dc_maxcharwidth(hdc);
SelectObject(hdc, oldfont);
ReleaseDC(ws->iconwin, hdc);
wc->font->ascent = metrics.tmAscent;
wc->font->descent = metrics.tmDescent;
/* wc->font->charwidth = metrics.tmMaxCharWidth; buggy */
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;
/*
* set the generic window's true default sizes
*/
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);
}
if (!ws->pix) {
hdc = GetDC(ws->iconwin);
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);
oldpix = SelectObject(hdc2, ws->pix);
hdc3 = CreateCompatibleDC(hdc);
oldpix2 = 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);
SelectObject(hdc2, oldpix);
SelectObject(hdc3, oldpix2);
DeleteDC(hdc2);
DeleteDC(hdc3);
DeleteObject(ws->initialPix);
ws->initialPix = (HBITMAP) NULL;
}
else {
/*
* initialize the image with the background color
*/
RECT rec;
hdc = GetDC(ws->iconwin);
hdc2 = CreateCompatibleDC(hdc);
oldpix = SelectObject(hdc2, ws->pix);
rec.left = rec.top = 0;
rec.right = ws->width;
rec.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, &rec, brush);
FillRect(hdc2, &rec, brush);
DeleteObject(brush);
SelectObject(hdc2, oldpix);
ReleaseDC(ws->iconwin, hdc);
DeleteDC(hdc2);
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;
}
}
}
if (ws->win)
UpdateWindow(ws->win);
return (FILE *)w;
}
int handle_config(wbp w, UINT msg, WPARAM wp, LPARAM lp)
{
int neww, newh;
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));
neww = LOWORD(lp);
newh = HIWORD(lp);
/*
* if it was not a resize, drop it
*/
if ((ws->width == neww) && (ws->height == newh)) {
return 1;
}
ws->width = neww;
ws->height = newh;
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;
}
/*
* handle window controls (child windows), at the moment these are
* buttons and scrollbars. wp is which child (base 1).
* Buttons come in as undiluted messages.
* Scrollbars come in with msg = new value of scrollbar
*/
void handle_child(wbp wb, UINT msg, WPARAM wp, LPARAM lp)
{
DWORD dw;
LONG t;
WORD x, y;
wsp ws = wb->window;
char *s;
int len;
struct descrip d;
int flags = 0;
if (LOWORD(wp) > ws->nChildren) return;
s = ws->child[LOWORD(wp) - 1].id;
len = strlen(s);
d = nulldesc;
StrLoc(d) = alcstr(s, len);
StrLen(d) = len;
switch (HIWORD(wp)) {
case BN_CLICKED: {
dw = GetMessagePos();
x = LOWORD(dw);
y = HIWORD(dw);
break;
}
case EN_SETFOCUS: case EN_KILLFOCUS: case EN_CHANGE: case EN_UPDATE:
case EN_ERRSPACE: case EN_MAXTEXT: case EN_HSCROLL: case EN_VSCROLL: {
return;
}
default: { /* scrollbar */
x = y = msg;
}
}
t = GetMessageTime();
qevent(ws, &d, x, y, t, flags);
if (ws->focusChild)
SetFocus(ws->focusChild);
else if (ws->win)
SetFocus(ws->win);
else
SetFocus(ws->iconwin);
}
void handle_menu(wbp wb, UINT msg, WPARAM wp, LPARAM lp)
{
wsp ws = wb->window;
DWORD dw;
LONG t;
WORD x, y;
struct descrip d;
char *s = ws->menuMap[wp];
int len = strlen(s);
int flags = 0;
d = nulldesc;
StrLoc(d) = alcstr(s, len);
StrLen(d) = len;
dw = GetMessagePos();
x = LOWORD(dw);
y = HIWORD(dw);
t = GetMessageTime();
qevent(ws, &d, x, y, t, flags);
}
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;
if (msg == WM_CHAR || msg == WM_SYSCHAR) {
StrLen(d) = 1;
StrLoc(d) = (char *)&allchars[wp & 0xFF];
}
else { /* WM_KEYDOWN or WM_SYSKEYDOWN */
MakeInt(wp, &d);
}
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;
else eventcode = MOUSEMOVED;
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(); /* why might someone comment this out? */
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;
int n, i, imin, imax;
/*
* 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) {
extern void closelogfile();
wfreersc();
closelogfile();
}
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 {
HBITMAP oldpix;
hdc2 = CreateCompatibleDC(hdc);
oldpix = 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);
SelectObject(hdc2, oldpix);
DeleteDC(hdc2);
}
EndPaint(hwnd, &ps);
return 0;
case WM_MOUSEMOVE:
if (ws->curcursor)
SetCursor(ws->curcursor);
if ((ws->inputmask & PointerMotionMask) ||
((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_KEYDOWN:
switch (wp) { /* VK defn's from <winuser.h> */
case VK_F1: case VK_F2: case VK_F3: case VK_F4:
case VK_F5: case VK_F6: case VK_F7: case VK_F8:
case VK_F9: case VK_F10: case VK_F11: case VK_F12:
case VK_HOME: case VK_END: case VK_PRIOR: case VK_NEXT:
case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN:
case VK_INSERT: case VK_SELECT: case VK_PRINT:
case VK_EXECUTE: case VK_SNAPSHOT: case VK_HELP: case VK_SEPARATOR:
case VK_CLEAR: case VK_PAUSE: case VK_SCROLL:
handle_keypress(wb, msg, wp, lp, 0);
return 0;
case VK_DELETE:
handle_keypress(wb, WM_CHAR, '\177', lp, 0);
return 0;
}
break;
case WM_SYSKEYDOWN:
switch (wp) {
case VK_F1: case VK_F2: case VK_F3: /* alt-F4 terminates */
case VK_F5: case VK_F6: case VK_F7: case VK_F8:
case VK_F9: case VK_F10: case VK_F11: case VK_F12:
case VK_HOME: case VK_END: case VK_PRIOR: case VK_NEXT:
case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN:
case VK_INSERT: case VK_DELETE: case VK_SELECT: case VK_PRINT:
case VK_EXECUTE: case VK_SNAPSHOT: case VK_HELP: case VK_SEPARATOR:
case VK_CLEAR: case VK_PAUSE:
handle_keypress(wb, msg, wp, lp, 1);
return 0;
}
break;
case WM_CHAR:
handle_keypress(wb, msg, wp, lp, 0);
return 0;
case WM_SYSCHAR:
handle_keypress(wb, msg, wp, lp, 1);
/*
* Unless there is a menu bar installed,
* Alt-A .. Alt-Z, and Alt-0 .. Alt-9 are eaten by Icon;
* others are passed on to Windows for things like Alt-Esc.
*/
if (isalnum(wp) && !(ws->menuMap)) return 0;
break;
case WM_HSCROLL:
case WM_VSCROLL:
for(n=0; n < ws->nChildren && ws->child[n].win != (HWND)LOWORD(lp); n++){
}
if (n == ws->nChildren) break;
i = GetScrollPos(ws->child[n].win, SB_CTL);
GetScrollRange(ws->child[n].win, SB_CTL, &imin, &imax);
switch (LOWORD(wp)) {
case SB_PAGEDOWN :
break;
case SB_LINEDOWN :
if (i < imax) {
SetScrollPos(ws->child[n].win, SB_CTL,
GetScrollPos(ws->child[n].win, SB_CTL) + 1, TRUE);
}
break;
case SB_PAGEUP :
break;
case SB_LINEUP :
if (i > imin) {
SetScrollPos(ws->child[n].win, SB_CTL,
GetScrollPos(ws->child[n].win, SB_CTL) - 1, TRUE);
}
break;
case SB_TOP :
SetScrollPos(ws->child[n].win, SB_CTL, imin, TRUE);
break;
case SB_BOTTOM :
SetScrollPos(ws->child[n].win, SB_CTL, imax, TRUE);
break;
case SB_THUMBPOSITION :
SetScrollPos(ws->child[n].win, SB_CTL, HIWORD(wp), TRUE);
break;
case SB_THUMBTRACK :
SetScrollPos(ws->child[n].win, SB_CTL, HIWORD(wp), TRUE);
break;
case SB_ENDSCROLL: /* noop */
break;
default : /* potentially a problem here */
break;
}
i = GetScrollPos(ws->child[n].win, SB_CTL);
handle_child(wb, i, n+1, -1);
break;
case WM_COMMAND:
if (LOWORD(lp) == 0)
handle_menu(wb, msg, wp, lp);
else
handle_child(wb, msg, wp, lp);
break;
case WM_SIZE:
handle_config(wb, msg, wp, lp);
break;
case WM_MOVE:
ws->posx = LOWORD(lp) - (BORDWIDTH>>1);
ws->posy = HIWORD(lp) - (BORDHEIGHT - 4);
break;
case WM_ACTIVATE:
if (wp == WA_INACTIVE) {
if (ws->savedcursor) SetCursor(ws->savedcursor);
if (ws->hasCaret) {
HideCaret(ws->iconwin);
DestroyCaret();
ws->hasCaret = 0;
}
}
else { /* ... */
if (ws->savedcursor == NULL)
ws->savedcursor = SetCursor(ws->curcursor);
else (void) SetCursor(ws->curcursor);
if (ISCURSORON(wb)) {
CreateCaret(ws->iconwin, NULL, FWIDTH(wb), FHEIGHT(wb));
SetCaretPos(ws->x, ws->y - ASCENT(wb));
SetCaretBlinkTime(500);
ShowCaret(ws->iconwin);
ws->hasCaret = 1;
}
}
break;
case WM_GETMINMAXINFO: {
MINMAXINFO *mmi = (MINMAXINFO *)lp;
if (! ISRESIZABLE(wb)) {
mmi->ptMinTrackSize.x = mmi->ptMaxTrackSize.x =
ws->width + BORDWIDTH;
mmi->ptMinTrackSize.y = mmi->ptMaxTrackSize.y =
ws->height + BORDHEIGHT;
}
return 0;
}
case WM_KILLFOCUS:
if (ws->hasCaret) {
HideCaret(ws->iconwin);
DestroyCaret();
ws->hasCaret = 0;
}
break;
case WM_SETFOCUS:
if (ws->focusChild)
SetFocus(ws->focusChild);
else if (ISCURSORON(wb)) {
CreateCaret(ws->iconwin, NULL, FWIDTH(wb), FHEIGHT(wb));
SetCaretPos(ws->x, ws->y - ASCENT(wb));
SetCaretBlinkTime(500);
ShowCaret(ws->iconwin);
ws->hasCaret = 1;
}
break;
/* case WM_QUIT is handled prior to the switch*/
case WM_DESTROY:
if (ws->win == hwnd)
ws->win = NULL;
if (ws->iconwin == hwnd)
ws->iconwin = NULL;
if (ws->refcount > 0) {
closelogfile();
PostQuitMessage(0);
return 0;
}
else if (ws->refcount < 0) {
ws->refcount = -ws->refcount;
}
break;
case WM_MCINOTIFY:
mciSendCommand(LOWORD(lp), MCI_CLOSE, 0, (DWORD)NULL);
break;
}
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);
TranslateMessage(&m);
DispatchMessage(&m);
}
return 400;
}
/*
* write some text to both the window and the pixmap
*/
void 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);
}
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
*/
UpdateCursorPos(ws,wc);
return 0;
}
/*
* wgetq - get event from pending queue
*/
int wgetq(wbp w, dptr res)
{
MSG m;
wsp ws;
int first = 0, i = 0, j;
int hascaret = 0;
extern jmp_buf mark_sj;
FILE *f;
if (!w || !(ws = w->window) || !(ws->iconwin)) {
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 == 0) {
CreateCaret(ws->iconwin, NULL, FWIDTH(w), FHEIGHT(w));
SetCaretPos(ws->x, ws->y - ASCENT(w));
SetCaretBlinkTime(500);
ShowCaret(ws->iconwin);
ws->hasCaret = 1;
}
i++;
if (GetMessage(&m, NULL, 0, 0) == 0) longjmp(mark_sj, -1);
TranslateMessage(&m);
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;
stdwin = ws->win = ws->iconwin;
CLRTOBEHIDDEN(ws);
}
else if (!strcmp(s, "maximal")) {
cmd = SW_SHOWMAXIMIZED;
stdwin = ws->win = ws->iconwin;
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(char *family, int size, int flags, int ansi)
{
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,
(ansi && (MAXBYTESPERCHAR==1)) ? ANSI_CHARSET:DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
spacing, family);
}
HFONT mkfont(char *s)
{
int flags, size;
char family[MAXFONTWORD+1];
char *stdfam = NULL;
HFONT hf = 0;
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 New"; /* was "courier" */
flags |= FONTFLAG_MONO + FONTFLAG_SERIF;
}
else if (!strcmp(family, "sans")) {
stdfam = "Arial"; /* was "swiss" */
flags |= FONTFLAG_PROPORTIONAL + FONTFLAG_SANS;
}
else if (!strcmp(family, "serif")) {
stdfam = "Times New Roman";
flags |= FONTFLAG_PROPORTIONAL + FONTFLAG_SERIF;
}
else stdfam = NULL;
if (stdfam) {
/*
* Standard name: first try preferred family, then generalize.
* ICONFONT can be NULL, in which case Windows chooses.
*/
hf = findfont(stdfam, size, flags, 1);
if (hf == NULL)
hf = findfont(getenv("ICONFONT"), size, flags, 1);
}
else {
/*
* Any other name: must match as specified.
*/
hf = findfont(family, size, flags, 0);
}
}
return hf;
}
/*
* Set the window's font by name.
*/
int setfont(w, s)
wbp w;
char **s;
{
wsp ws = w->window;
wcp wc = w->context;
HFONT hf, oldfont;
TEXTMETRIC metrics;
HDC tmpdc;
hf = mkfont(*s);
if (hf != NULL) {
if (wc->font->font)
DeleteObject(wc->font->font);
wc->font->font = hf;
if (wc->font->name)
free(wc->font->name);
wc->font->name = salloc(*s);
tmpdc = GetDC(ws->iconwin);
oldfont = SelectObject(tmpdc, hf);
wc->font->charwidth = dc_maxcharwidth(tmpdc);
if (GetTextMetrics(tmpdc, &metrics) == 0) {
/* gettextmetrics can fail; what should we do about it? */
;
}
SelectObject(tmpdc, oldfont);
ReleaseDC(ws->iconwin, tmpdc);
wc->font->ascent = metrics.tmAscent;
wc->font->descent = metrics.tmDescent;
/* wc->font->charwidth = metrics.tmMaxCharWidth; unreliable due to MS bug */
wc->leading = 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;
}
void 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,
wc->clipy + wc->cliph);
else
wc->cliprgn = NULL;
}
void 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 = (LONG)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 = (LONG)wc->pattern;
wc->bkmode = OPAQUE;
}
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 getdepthDC(HDC dc)
{
return GetDeviceCaps(dc, BITSPIXEL) * GetDeviceCaps(dc, PLANES);
}
int getdepth(wbp w)
{
int i, j;
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) wc->fgname = salloc(val);
else if (strcmp(wc->fgname, val)) {
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 = (LONG)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) wc->bgname = salloc(val);
else if (strcmp(wc->bgname, val)) {
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 Succeeded;
}
/*
* setpointer() - define a mouse pointer shape
*/
int setpointer(w, val)
wbp w;
char *val;
{
HCURSOR c;
char *cval;
if (!strcmp(val,"arrow")) cval = IDC_ARROW;
else if (!strcmp(val,"cross")) cval = IDC_CROSS;
else if (!strcmp(val,"ibeam")) cval = IDC_IBEAM;
else if (!strcmp(val,"uparrow")) cval = IDC_UPARROW;
else if (!strcmp(val,"wait")) cval = IDC_WAIT;
else if (!strcmp(val,"starting")) cval = IDC_APPSTARTING;
else if (!strcmp(val,"icon")) cval = IDC_ICON;
else if (!strcmp(val,"size")) cval = IDC_SIZE;
else if (!strcmp(val,"sizenesw")) cval = IDC_SIZENESW;
else if (!strcmp(val,"sizens")) cval = IDC_SIZENS;
else if (!strcmp(val,"sizenwse")) cval = IDC_SIZENWSE;
else if (!strcmp(val,"sizewe")) cval = IDC_SIZEWE;
else if (!strcmp(val,"no")) cval = IDC_NO;
else {
return Failed;
}
c = LoadCursor(NULL, cval);
if (c == NULL) {
return Failed;
}
w->window->curcursor = c;
if (w->window->cursorname) free(w->window->cursorname);
w->window->cursorname = salloc(val);
if (! w->window->savedcursor)
w->window->savedcursor = SetCursor(c);
else (void) SetCursor(c);
/* should restore savedcursor when pointer 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)
{
if (strcmp(val, "MS Windows"))
return Failed;
return Succeeded;
}
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;
}
void 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;
}
void getfg(w, answer)
wbp w;
char *answer;
{
strcpy(answer, w->context->fgname);
}
void getbg(w, answer)
wbp w;
char *answer;
{
strcpy(answer, w->context->bgname);
}
void 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, "unknown");
}
void getfntnam(w, answer)
wbp w;
char *answer;
{
strcpy(answer, w->context->font->name);
}
void getpointername(w, answer)
wbp w;
char *answer;
{
char *s;
wsp ws = w->window;
strcpy(answer, w->window->cursorname);
}
void getdisplay(wbp w, char *answer)
{
strcpy(answer, "MS Windows");
}
void 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, "unknown");
}
void geticonic(w, answer)
wbp w;
char *answer;
{
getcanvas(w, answer);
}
void 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
*/
void 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);
if (stdwin) SelectObject(stddc, oldbrush);
SelectObject(pixdc, oldbrush2);
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;
{
int lpad, rpad, tpad, bpad;
RECT r;
HDC srcdc, srcpixdc;
HBRUSH hb;
wsp ws1 = w->window;
HBITMAP oldpix;
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);
}
oldpix = 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 {
/*
* Check for source partially offscreen, but copy first and
* fill later in case the source and destination overlap.
*/
lpad = rpad = tpad = bpad = 0;
if (x < 0) { /* source extends past left edge */
lpad = -x;
width -= lpad;
x2 += lpad;
x = 0;
}
if (x + width > ws1->pixwidth) { /* source extends past right edge */
rpad = x + width - ws1->pixwidth;
width -= rpad;
}
if (y < 0) { /* source extends above top edge */
tpad = -y;
height -= tpad;
y2 += tpad;
y = 0;
}
if (y + height > ws1->pixheight) { /* source extends below bottom */
bpad = y + height - ws1->pixheight;
height -= bpad;
}
if (stdwin)
BitBlt(stddc, x2, y2, width, height, srcpixdc, x, y, SRCCOPY);
BitBlt(pixdc, x2, y2, width, height, srcpixdc, x, y, SRCCOPY);
if (lpad > 0) {
r.left = x2-lpad;
r.top = y2-tpad;
r.right = r.left + lpad;
r.bottom = r.top + tpad+height+bpad;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
}
if (rpad > 0) {
r.left = x2+width;
r.top = y2-tpad;
r.right = r.left + rpad;
r.bottom = r.top + tpad+height+bpad;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
}
if (tpad > 0) {
r.left = x2;
r.top = y2-tpad;
r.right = r.left + width;
r.bottom = r.top + tpad;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
}
if (bpad > 0) {
r.left = x2;
r.top = y2+height;
r.right = r.left + width;
r.bottom = r.top + bpad;
if (stdwin)
FillRect(stddc, &r, hb);
FillRect(pixdc, &r, hb);
}
}
/*
* free resources
*/
SelectObject(srcpixdc, oldpix);
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;
SysColor palfg, palbg;
STDLOCALS(w);
palfg = PALCLR(wc->fg);
palbg = PALCLR(wc->bg);
/*
* 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, palfg);
}
else if (ch != TCH1) { /* if zeroes aren't transparent */
SetPixel(pixdc, ix, iy, palbg);
}
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, palbg);
/*
* 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;
{
HDC tempdc;
HBITMAP temppix;
register int c;
register unsigned int ix;
int v, anytransparent=0;
unsigned int iy, tmpw;
SysColor clrlist[256], xc, palbg;
char tmp[24];
BITMAPINFO *bmi;
BITMAPINFOHEADER *bmih = &(bmi->bmiHeader);
HBITMAP oldpix = 0;
STDLOCALS(w);
bmi = malloc(sizeof(BITMAPINFO) + 256 * sizeof(SysColor));
if (bmi == NULL) {
FREE_STDLOCALS(w);
return -1;
}
bmih = &(bmi->bmiHeader);
palbg = PALCLR(wc->bg);
if (on_icon) {
free(bmi);
FREE_STDLOCALS(w);
return -1;
}
bmih->biClrImportant = 0;
/*
* Build arrays of colors in SysColor and RGBQUAD format for use by
* either SetPixel or DIB. Decide which to use based on whether
* there are any transparent pixels
*/
for (c = 0; c < 256; c++) {
if (e[c].transpt) anytransparent++;
if (e[c].used && e[c].valid) {
bmih->biClrImportant++;
clrlist[c] = mscolor(w, e[c].clr.red, e[c].clr.green, e[c].clr.blue);
bmi->bmiColors[c].rgbBlue = BLUE(clrlist[c]);
bmi->bmiColors[c].rgbRed = RED(clrlist[c]);
bmi->bmiColors[c].rgbGreen = GREEN(clrlist[c]);
if (alc_rgb(w, clrlist[c]) == Failed) {
free(bmi);
FREE_STDLOCALS(w);
return -1;
}
clrlist[c] = PALCLR(clrlist[c]);
}
else {
bmi->bmiColors[c].rgbBlue = BLUE(wc->bg);
bmi->bmiColors[c].rgbRed = RED(wc->bg);
bmi->bmiColors[c].rgbGreen = GREEN(wc->bg);
}
}
/*
* if transparent characters are not present, blast out a DIB.
*/
if (anytransparent == 0) {
char *buf = malloc(height * (width+4)), *buf2;
buf2 = buf;
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = -height;
bmih->biPlanes = 1;
bmih->biBitCount = 8;
bmih->biCompression = BI_RGB;
bmih->biSizeImage = 0;
bmih->biXPelsPerMeter = 0;
bmih->biYPelsPerMeter = 0;
bmih->biClrUsed = 256;
ix = 0;
while (len--) {
*buf++ = *s++;
if (++ix >= width) {
while(ix % 4) {
buf++;
ix++;
}
ix = 0;
}
}
temppix=CreateDIBitmap(pixdc, bmih, CBM_INIT, buf2, bmi, DIB_RGB_COLORS);
free(buf2);
tempdc = CreateCompatibleDC(stddc);
oldpix = SelectObject(tempdc, temppix);
BitBlt(pixdc, x, y, width, height, tempdc, 0, 0, SRCCOPY);
SelectObject(tempdc, oldpix);
DeleteDC(tempdc);
DeleteObject(temppix);
}
else {
/*
* The image contains some transparent pixels.
* Read the image string and set the pixel values.
* Note that SetPixelV() fails under Win32s; so we don't use it.
*/
ix = x;
iy = y;
tmpw = x + width;
while (len--) {
c = *s++;
v = e[c].valid;
if (v) { /* put char if valid */
xc = SetPixel(pixdc, ix, iy, clrlist[c]);
}
if (v || e[c].transpt) { /* advance if valid or transparent */
if (++ix >= tmpw) {
ix = x; /* reset for new row */
iy++;
}
}
}
if (ix > 0) /* pad final row if incomplete */
while (ix < width)
SetPixel(pixdc, x+ix++, y+iy, palbg);
}
free(bmi);
/*
* Copy it from the pixmap onto 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, *lp;
int i, ncolors, x, y, wd = xx + width, ht = yy + height, nclist;
STDLOCALS(w);
clist = malloc(DMAXCOLORS * sizeof (SysColor));
nclist = DMAXCOLORS;
/*
* 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++;
if (ncolors >= nclist) {
nclist = nclist * 1.5;
clist = realloc(clist, nclist * sizeof (SysColor));
}
while (clist + i != lp) {
clist[i] = clist[i-1];
i--;
}
clist[i] = px;
}
}
}
}
/*
* if ncolors is greater than DMAXCOLORS, then fail rather than
* overwriting the paltbl.
*/
if (ncolors > DMAXCOLORS) {
free(clist);
return 0;
}
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);
free(clist);
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(clist);
FREE_STDLOCALS(w);
return 1;
}
int readimage(w, filename, x, y, status)
wbp w;
char *filename;
int x, y, *status;
{
HBITMAP p, oldpix;
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);
oldpix = 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);
SelectObject(srcpixdc, oldpix);
ReleaseDC(ws->iconwin, srcdc);
DeleteDC(srcpixdc);
/*
* Make sure previous ops on p are complete, then free it.
*/
DeleteObject(p);
FREE_STDLOCALS(w);
return Succeeded;
}
}
/*
* 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, imem)
wbp w;
struct imgmem *imem;
{
COLORREF *p;
wsp ws = w->window;
int i, j, x2, y2;
HDC stddc = GetDC(ws->iconwin), pixdc = CreateCompatibleDC(stddc);
HBITMAP oldpix;
if (palette) SelectPalette(pixdc, palette, FALSE);
oldpix = SelectObject(pixdc, ws->pix);
/* this looks like a bug for Win16 for images > 100x100 or so... */
imem->crp = malloc( imem->width * imem->height * sizeof(COLORREF));
if (imem->crp == NULL) return Failed;
p = imem->crp;
x2 = imem->x + imem->width;
y2 = imem->y + imem->height;
for(i = imem->y; i < y2; i++)
for(j = imem->x; j < x2; j++) {
if ((*p++ = GetPixel(pixdc, j, i)) == (COLORREF)-1L) {
free(imem->crp);
SelectObject(pixdc, oldpix);
FREE_STDLOCALS(w);
return Failed;
}
}
SelectObject(pixdc, oldpix);
FREE_STDLOCALS(w);
return Succeeded;
}
int getpixel_term(w, imem)
wbp w;
struct imgmem *imem;
{
free(imem->crp);
return Succeeded;
}
/*
* Return pixel (x,y) from a window
*/
int getpixel(wbp w, int x, int y, long *rv, char *s, struct imgmem *imem)
{
COLORREF cr = imem->crp[(y-imem->y) * imem->width + (x-imem->x)];
*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;
HDIB dib;
HDC destdc;
HBITMAP dumppix, oldpix;
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);
oldpix = SelectObject(destdc, dumppix);
BitBlt(destdc, 0, 0, width, height, pixdc, x, y, SRCCOPY);
}
else dumppix = ws->pix;
dib = BitmapToDIB(dumppix, palette);
if (dumppix != ws->pix) {
SelectObject(destdc, oldpix);
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)
{
HDC hdc;
HDIB dib;
HBITMAP bmap;
HPALETTE p2;
PALETTEENTRY pe;
LPBITMAPINFO lpbmi;
int j;
int ii,jj, kk;
int xx[256];
unsigned char * pd;
char *j2;
dib = LoadDIB(filename);
if (dib != NULL) {
LPSTR pdib;
p2 = CreateDIBPalette(dib);
j2 = GlobalLock(dib);
j = DIBNumColors(j2);
jj = DIBWidth(j2);
kk = DIBHeight(j2);
GlobalUnlock(dib);
if (!palette) {
LOGPALETTE logpal[4]; /* (1, + space for an extra palette entry) */
hdc = GetDC(w->window->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 (!palette) {
return NULL;
}
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");
}
else {
/* this window is not on a device that supports palettes */
}
ReleaseDC(w->window->iconwin, hdc);
}
if (palette) {
if (ResizePalette(palette, numColors + j) == 0) {
return NULL;
}
for (ii = 0; ii < j; ii++) {
if (GetPaletteEntries(p2, ii, 1, &pe) == 0) {
return NULL;
}
SetPaletteEntries(palette, numColors++, 1, &pe);
}
}
bmap = DIBToBitmap(dib, palette);
pdib = GlobalLock(dib);
*width = DIBWidth(pdib);
*height = DIBHeight(pdib);
GlobalUnlock(dib);
DestroyDIB(dib);
DeleteObject(p2);
*status = 0;
return bmap;
}
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;
}
void 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;
}
}
void 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 + 1;
bottom = arc->y + arc->height + 1;
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;
XPoint tmp[2];
STDLOCALS(wb);
hp = CreatePenIndirect(&(wc->pen));
if (stdwin) oldpen = SelectObject(stddc, hp);
oldpen2 = SelectObject(pixdc, hp);
tmp[0] = points[npoints-1];
tmp[1] = points[npoints-2];
if (ws->win) {
SetBkMode(stddc, wc->bkmode);
Polyline(stddc, points, npoints);
Polyline(stddc, tmp, 2);
}
SetBkMode(pixdc, wc->bkmode);
Polyline(pixdc, points, npoints);
Polyline(pixdc, tmp, 2);
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)
{
register XPoint *p, *endp;
SysColor palfg;
STDLOCALS(wb);
endp = points + npoints;
palfg = PALCLR(wc->fg);
if (stdwin) {
for(p = points; p < endp; p++) {
SetPixel(stddc, p->x, p->y, palfg);
SetPixel(pixdc, p->x, p->y, palfg);
}
}
else {
for(p = points; p < endp; p++) {
SetPixel(pixdc, p->x, p->y, palfg);
}
}
FREE_STDLOCALS(wb);
return;
}
/*
* drawsegments() -
*/
void drawsegments(wbinding *wb, XSegment *segs, int nsegs)
{
int i, 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;
}
int allowresize(w, on)
wbp w;
int on;
{
if (on)
SETRESIZABLE(w);
else
CLRRESIZABLE(w);
return Succeeded;
}
int getselection(wbp w, char *buf)
{
return Failed;
}
int setselection(wbp w, char *val)
{
return Failed;
}
/*
* 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);
SetTextColor(pixdc, PALCLR(wc->fg));
if (stdwin) SetTextColor(stddc, PALCLR(wc->fg));
SetBkColor(pixdc, PALCLR(wc->bg));
if (stdwin) SetBkColor(stddc, PALCLR(wc->bg));
if (stdwin) SetBkMode(stddc, wc->bkmode);
SetBkMode(pixdc, wc->bkmode);
for (i = 0; i < narcs; i++, arc++) {
if (arc->angle2 >= 2 * Pi) {
/*
* from SDK reference: Ellipse() draws up to but not including
* the right and bottom coordinates. Add +1 to compensate.
*/
if (stdwin)
Ellipse(stddc, arc->x, arc->y,
arc->x + arc->width + 1, arc->y + arc->height + 1);
Ellipse(pixdc, arc->x, arc->y,
arc->x + arc->width + 1, arc->y + arc->height + 1);
}
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 + 1, arc->y + arc->height + 1,
pts[1].x, pts[1].y, pts[2].x, pts[2].y);
}
Pie(pixdc, arc->x, arc->y,
arc->x + arc->width + 1, arc->y + arc->height + 1,
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;
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);
SetTextColor(pixdc, PALCLR(wc->fg));
if (stdwin) SetTextColor(stddc, PALCLR(wc->fg));
SetBkColor(pixdc, PALCLR(wc->bg));
if (stdwin) SetBkColor(stddc, PALCLR(wc->bg));
if (stdwin) SetBkMode(stddc, wc->bkmode);
SetBkMode(pixdc, wc->bkmode);
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, oldpen);
SelectObject(pixdc, oldpen2);
DeleteObject(hp);
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++) {
/*
* from SDK reference: Rectangle() draws up to but not including
* the right and bottom coordinates. Add +1 to compensate.
*/
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);
if (stdwin) SetBkMode(stddc, wc->bkmode);
SetBkMode(pixdc, wc->bkmode);
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,
((MAXBYTESPERCHAR==1)?ANSI_CHARSET:DEFAULT_CHARSET),
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
getenv("ICONFONT"));
wc->font->charwidth = 8; /* looks like a bug */
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;
if (wc2->cliprgn)
wc->cliprgn = CreateRectRgn(wc->clipx,wc->clipy,
wc->clipx+wc->clipw,
wc->clipy+wc->cliph);
wc->dx = wc2->dx;
wc->dy = wc2->dy;
wc->bits = wc2->bits;
/*
* clone needs to make a copy of the pattern
* if (wc2->pattern) {
* wc->pattern = copy+somehow(wc2->pattern);
* if (wc2->patternname)
* wc->patternname = salloc(wc2->patternname);
* }
*/
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,
((MAXBYTESPERCHAR==1)?ANSI_CHARSET:DEFAULT_CHARSET),
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN,
getenv("ICONFONT"));
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;
ws->cursorname = salloc("arrow");
ws->curcursor = LoadCursor(NULL, IDC_ARROW);
GRFX_LINK(ws, wstates);
return ws;
}
/*
* free a window state
*/
int free_window(ws)
wsp ws;
{
int i;
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->windowlabel) free(ws->windowlabel);
if (ws->iconlabel) free(ws->iconlabel);
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;
/* need to enumerate and specifically free each string */
if (ws->menuMap) {
for(i=0;i<ws->nmMapElems;i++) free(ws->menuMap[i]);
free(ws->menuMap);
ws->menuMap = 0;
}
free(ws->cursorname);
if (ws->child) {
for(i=0;i<ws->nChildren;i++) {
free(ws->child[i].id);
if (ws->child[i].font) DeleteObject(ws->child[i].font);
}
free(ws->child);
}
ws->child = 0;
GRFX_UNLINK(ws, wstates);
}
return 0;
}
/*
* free a window context
*/
void 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->patternname)
free(wc->patternname);
wc->patternname = 0;
if (wc->fgname) free(wc->fgname);
wc->fgname = 0;
if (wc->bgname) free(wc->bgname);
wc->bgname = 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;
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);
strncpy(wc->patternname, name, len);
wc->patternname[len] = '\0';
/*
* 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 = reversebits(~(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 = (LONG)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, k;
HBITMAP p;
char data[MAXXOBJS];
char *buf = data;
wcp wc = w->context;
if (width != nbits)
return Failed;
if (width == 8) {
for(i = 0; i < nbits; i++) {
v = bits[i];
*buf++ = reversebits(~v);
}
}
else if (width == 4) {
for(k=0; k < 2; k++) /* do twice to get 8 rows */
for(i = 0; i < nbits; i++) {
v = widenbits(bits[i]);
*buf++ = reversebits(~v);
}
}
else return Failed;
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 = (LONG)p;
}
return Succeeded;
}
int widenbits(int c)
{
int rv = c;
if (c & 1) rv |= 16;
if (c & 2) rv |= 32;
if (c & 4) rv |= 64;
if (c & 8) rv |= 128;
return rv;
}
int reversebits(int c)
{
int rv = 0;
if (c & 1) rv |= 128;
if (c & 2) rv |= 64;
if (c & 4) rv |= 32;
if (c & 8) rv |= 16;
if (c & 16) rv |= 8;
if (c & 32) rv |= 4;
if (c & 64) rv |= 2;
if (c & 128) rv |= 1;
return rv;
}
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, ht, SWP_NOZORDER);
}
else if (status == 2) {
SetWindowPos(ws->win, ws->win, 0, 0,
wid, ht, SWP_NOMOVE|SWP_NOZORDER);
}
else if (status == 1)
SetWindowPos(ws->win, ws->win,
posx,
posy,
0, 0, SWP_NOSIZE|SWP_NOZORDER);
}
else if (ws->iconwin) {
if (status == 3) {
SetWindowPos(ws->iconwin, ws->iconwin,
posx,
posy,
wid, ht, SWP_NOZORDER);
}
else if (status == 2) {
SetWindowPos(ws->iconwin, ws->iconwin, 0, 0,
wid, ht, SWP_NOMOVE|SWP_NOZORDER);
}
else if (status == 1)
SetWindowPos(ws->iconwin, ws->iconwin,
posx,
posy,
0, 0, SWP_NOSIZE|SWP_NOZORDER);
}
return Succeeded;
}
DWORD playMIDIfile(HWND hWndNotify, LPSTR s)
{
UINT wDeviceID;
DWORD dwReturn;
MCI_OPEN_PARMS mciOpenParms;
MCI_PLAY_PARMS mciPlayParms;
MCI_STATUS_PARMS mciStatusParms;
MCI_SEQ_SET_PARMS mciSeqSetParms;
mciOpenParms.lpstrDeviceType = "sequencer";
mciOpenParms.lpstrElementName = s;
if (dwReturn = mciSendCommand((UINT)NULL, MCI_OPEN,
MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID) &mciOpenParms)) {
return dwReturn;
}
wDeviceID = mciOpenParms.wDeviceID;
/* attempt to select the MIDI mapper */
mciSeqSetParms.dwPort = MIDI_MAPPER;
if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SEQ_SET_PORT,
(DWORD)(LPVOID) &mciSeqSetParms)) {
/* could not select the MIDI mapper; play anyway */
}
mciPlayParms.dwCallback = (DWORD) hWndNotify;
if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY,
(DWORD)(LPVOID) &mciPlayParms)) {
mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
return dwReturn;
}
return 0L;
}
int playmedia(wbp w, char *s)
{
if (strstr(s, ".wav") || strstr(s, ".WAV")) {
sndPlaySound((LPSTR) s, SND_ASYNC);
return Succeeded;
}
else if (strstr(s, ".mid") || strstr(s, ".MID") ||
strstr(s, ".rmi") || strstr(s, ".RMI")) {
if (playMIDIfile(w->window->win, (LPSTR) s) == 0)
return Succeeded;
}
/*
* Interpret as an MCI command string
*/
else {
if (mciSendString(s, NULL, 0, 0L)) return Failed;
return Succeeded;
}
}
/*
* UpdateCursorPos
*/
void UpdateCursorPos(wsp ws, wcp wc)
{
if (ISCURSORONW(ws)) {
if (ws->hasCaret) {
}
CreateCaret(ws->iconwin, NULL, FWIDTHC(wc), FHEIGHTC(wc));
SetCaretBlinkTime(500);
SetCaretPos(ws->x, ws->y - ASCENTC(wc));
ShowCaret(ws->iconwin);
ws->hasCaret = 1;
}
}
int resizePixmap(wbp w, int width, int height)
{
HDC hdc, hdc2, hdc3;
HBITMAP newpix, oldpix, oldpix2;
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);
oldpix = SelectObject(hdc2, ws->pix);
}
hdc3 = CreateCompatibleDC(hdc);
oldpix2 = 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);
SelectObject(hdc3, oldpix2);
DeleteDC(hdc3);
if (ws->pix) {
SelectObject(hdc2, oldpix);
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 */;
}
}
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;
HBITMAP oldpix;
HDC hdc2 = CreateCompatibleDC(hdc);
if (numColors > 0) {
SelectPalette(hdc2, palette, FALSE);
RealizePalette(hdc2);
}
/* ws->initialPix = */ ws->theOldPix = SelectObject(hdc2, ws->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;
}
else {
ws->inputmask &= ~PointerMotionMask;
}
return Succeeded;
}
int dc_maxcharwidth(HDC dc)
{
int i, m = -1, x;
char s[2];
s[1] = '\0';
for (i=0; i<256; i++) {
s[0] = i;
x = dc_textwidth(dc, s, 1);
if (x > m) m = x;
}
return m;
}
/*
* 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 sysScrollWidth()
{
return GetSystemMetrics(SM_CXVSCROLL);
}
int sysFontHeight(wbp w)
{
TEXTMETRIC tm;
int rv;
wsp ws = w->window;
HDC dc = GetDC(ws->iconwin);
HFONT oldfont = SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
GetTextMetrics(dc, &tm);
SelectObject(dc, oldfont);
ReleaseDC(ws->iconwin, dc);
return tm.tmHeight + tm.tmExternalLeading;
}
int sysTextWidth(wbp w, char *s, int n)
{
int rv;
wsp ws = w->window;
HDC dc = GetDC(ws->iconwin);
HFONT oldfont;
oldfont = SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
rv = dc_textwidth(dc, s, n);
SelectObject(dc, oldfont);
ReleaseDC(ws->iconwin, dc);
return rv;
}
int textWidth(wbp w, char *s, int n)
{
int rv;
wsp ws = w->window;
HDC stddc = GetDC(ws->iconwin);
HFONT oldfont = SelectObject(stddc, w->context->font->font);
rv = dc_textwidth(stddc, s, n);
SelectObject(stddc, oldfont);
ReleaseDC(ws->iconwin, stddc);
return rv;
}
void 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()
{
wbp w;
extern struct palentry *palsetup_palette;
while (wbndngs != NULL) {
w = wbndngs;
wbndngs = wbndngs->next;
free(w);
}
while (wstates != NULL) {
wstates->refcount = 1;
free_window(wstates);
}
while (wcntxts != NULL) {
wcntxts->refcount = 1;
free_context(wcntxts);
}
if (palette) {
DeleteObject(palette);
palette = 0;
}
if (palsetup_palette) {
free(palsetup_palette);
palsetup_palette = 0;
}
if (scp) {
free(scp);
scp = 0;
}
if (wlhead)
wlfree();
mciSendCommand(MCI_ALL_DEVICE_ID, MCI_CLOSE, 0, (DWORD)NULL);
}
/*
* Native Windows UI facilities
*/
void makebutton(wsp ws, childcontrol *cc, char *s)
{
cc->type = CHILD_BUTTON;
cc->font = 0;
cc->id = salloc(s);
cc->win = CreateWindow("button", cc->id,
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
0, 0, 0, 0, ws->iconwin, (HMENU)ws->nChildren, mswinInstance,
NULL);
}
void makescrollbar(wsp ws, childcontrol *cc, char *s, int i1, int i2)
{
cc->type = CHILD_SCROLLBAR;
cc->id = salloc(s);
cc->font = 0;
cc->win = CreateWindow("scrollbar", cc->id,
WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0,
ws->iconwin, (HMENU)ws->nChildren, mswinInstance, NULL);
SetScrollRange(cc->win, SB_CTL, i1, i2, FALSE);
}
int nativemenubar(wbp w, int total, int argc, dptr argv, int warg, dptr d)
{
wsp ws;
tended struct b_list *hp;
HMENU tempMenu, tempMenu2 = NULL;
tended char *s, *s2;
int r, i;
ws = w->window;
if (ws->nmMapElems)
tempMenu2 = ws->menuBar;
ws->menuBar = CreateMenu();
ws->nmMapElems = total;
total = 0;
while (warg < argc){
/*
* each argument must be a list of strings
*/
hp = (struct b_list *)BlkLoc(argv[warg]);
r = hp->size;
/*
* Construct a Windows menu corresponding to the Icon list
*/
tempMenu = CreateMenu();
for(i=0; i < r; i++) {
c_get(hp, d);
if (!is:string(*d)) return Error;
if (!cnv:C_string(*d, s)) return Error;
s = strdup(s);
if (i == 0) s2=s;
else
AppendMenu(tempMenu, MF_STRING, total, s);
ws->menuMap[total++] = s;
c_put(&(argv[warg]), d);
}
AppendMenu(ws->menuBar, MF_POPUP, (unsigned int)tempMenu, s2);
warg++;
}
/*
* Insert the menu into the window
*/
if (ws->win) SetMenu(ws->win, ws->menuBar);
if (tempMenu2) {
int i, n = GetMenuItemCount(tempMenu2);
for (i=0; i < n; i++) {
DestroyMenu(GetSubMenu(tempMenu2, i));
}
DestroyMenu(tempMenu2);
}
return Succeeded;
}
void makeeditregion(wbp w, childcontrol *cc, char *s)
{
wsp ws = w->window;
cc->type = CHILD_EDIT;
cc->id = salloc(s);
cc->win = CreateWindow("edit", NULL,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
WS_BORDER | ES_LEFT | ES_MULTILINE |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
0, 0, 0, 0, ws->iconwin,
(HMENU) ws->nChildren, mswinInstance, NULL);
setchildfont(cc, w->context->font->name);
}
void cleareditregion(childcontrol *cc)
{
SendMessage(cc->win, WM_CLEAR, 0, 0);
}
void copyeditregion(childcontrol *cc)
{
SendMessage(cc->win, WM_COPY, 0, 0);
}
void cuteditregion(childcontrol *cc)
{
SendMessage(cc->win, WM_CUT, 0, 0);
}
void pasteeditregion(childcontrol *cc)
{
SendMessage(cc->win, WM_PASTE, 0, 0);
}
int undoeditregion(childcontrol *cc)
{
if (!SendMessage(cc->win, WM_UNDO, 0, 0)) return Failed;
return Succeeded;
}
int modifiededitregion(childcontrol *cc)
{
if (!SendMessage(cc->win, EM_GETMODIFY, 0, 0)) return Failed;
return Succeeded;
}
int setmodifiededitregion(childcontrol *cc, int i)
{
SendMessage(cc->win, EM_SETMODIFY, i, 0);
return Succeeded;
}
void geteditregion(childcontrol *cc, dptr d)
{
int y = GetWindowTextLength(cc->win);
char *s2 = alcstr(NULL, y + 1);
GetWindowText(cc->win, s2, y+1);
StrLoc(*d) = s2;
StrLen(*d) = y;
}
void seteditregion(childcontrol *cc, char *s2)
{
SetWindowText(cc->win, s2);
}
void movechild(childcontrol *cc,
C_integer x, C_integer y, C_integer width, C_integer height)
{
MoveWindow(cc->win, x, y, width, height, TRUE);
}
int setchildfont(childcontrol *cc, char *fontname)
{
HFONT hf;
RECT rect;
if (hf = mkfont(fontname)) {
SendMessage(cc->win, WM_SETFONT, (WPARAM)hf, 0);
if (cc->font) DeleteObject(cc->font);
cc->font = hf;
GetClientRect(cc->win, &rect);
InvalidateRect(cc->win, &rect, TRUE);
return Succeeded;
}
return Failed;
}
void setfocusonchild(wsp ws, childcontrol *cc, int width, int height)
{
if (width || height) {
SetFocus(cc->win);
ws->focusChild = cc->win;
}
else ws->focusChild = 0;
}
void setchildselection(wsp ws, childcontrol *cc, int x, int y)
{
int iLine = SendMessage(cc->win, EM_LINEFROMCHAR, x-1,0);
int topLine = SendMessage(cc->win, EM_GETFIRSTVISIBLELINE, 0, 0);
if (topLine != iLine) {
SendMessage(cc->win, EM_LINESCROLL, 0, iLine-topLine);
}
SendMessage(cc->win, EM_SETSEL, x - 1, y - 1);
SetFocus(cc->win);
ws->focusChild = cc->win;
}
CHOOSEFONT cf;
LOGFONT lf;
int nativefontdialog(wbp w, char *buf, int flags, int fheight)
{
strcpy(lf.lfFaceName, buf);
lf.lfHeight = fheight;
lf.lfWidth = 0;
lf.lfEscapement = 0;
if (!strcmp(lf.lfFaceName, "mono") || !strcmp(lf.lfFaceName, "fixed")){
strcpy(lf.lfFaceName, "Lucida Sans Typewriter");
flags |= FONTFLAG_MONO + FONTFLAG_SANS;
}
else if (!strcmp(lf.lfFaceName, "typewriter")) {
strcpy(lf.lfFaceName, "courier");
flags |= FONTFLAG_MONO + FONTFLAG_SERIF;
}
else if (!strcmp(lf.lfFaceName, "sans")) {
strcpy(lf.lfFaceName, "swiss");
flags |= FONTFLAG_PROPORTIONAL + FONTFLAG_SANS;
}
else if (!strcmp(lf.lfFaceName, "serif")) {
strcpy(lf.lfFaceName, "roman");
flags |= FONTFLAG_PROPORTIONAL + FONTFLAG_SERIF;
}
if (flags & FONTFLAG_BOLD) lf.lfWeight = FW_BOLD;
else
lf.lfWeight = FW_DONTCARE;
if (flags & FONTFLAG_ITALIC) lf.lfItalic = 1;
lf.lfUnderline = lf.lfStrikeOut = 0;
lf.lfCharSet =
((MAXBYTESPERCHAR==1)?ANSI_CHARSET:DEFAULT_CHARSET);
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
if (FONTFLAG_PROPORTIONAL)
lf.lfPitchAndFamily = VARIABLE_PITCH;
else if (FONTFLAG_MONO)
lf.lfPitchAndFamily = FIXED_PITCH;
else
lf.lfPitchAndFamily = DEFAULT_PITCH;
if (!strcmp(lf.lfFaceName, "swiss")) lf.lfPitchAndFamily |= FF_SWISS;
else if (!strcmp(lf.lfFaceName, "roman"))
lf.lfPitchAndFamily |= FF_ROMAN;
else
lf.lfPitchAndFamily |= FF_DONTCARE;
memset(&cf, 0, sizeof(CHOOSEFONT));
cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = w->window->iconwin;
cf.lpLogFont = &lf;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;
cf.rgbColors = RGB(0,0,0);
cf.nFontType = SCREEN_FONTTYPE;
if (ChooseFont(&cf) == 0) return Failed;
sprintf(buf, "%s,%d%s%s", lf.lfFaceName,
((lf.lfHeight > 0) ? lf.lfHeight : -lf.lfHeight),
(lf.lfItalic ? ",italic" : ""),
((lf.lfWeight > 500) ? ",bold" : ""));
return Succeeded;
}
/*
* common dialog functions
*/
COLORREF aclrCust[16];
CHOOSECOLOR cc;
char *nativecolordialog(wbp w, long r, long g, long b, char *buf)
{
aclrCust[0] = RGB(255,255,255);
aclrCust[1] = RGB(239,239,239);
aclrCust[2] = RGB(223,223,223);
aclrCust[3] = RGB(207,207,207);
aclrCust[4] = RGB(191,191,191);
aclrCust[5] = RGB(175,175,175);
aclrCust[6] = RGB(159,159,159);
aclrCust[7] = RGB(143,143,143);
aclrCust[8] = RGB(127,127,127);
aclrCust[9] = RGB(111,111,111);
aclrCust[10] = RGB(95,95,95);
aclrCust[11] = RGB(79,79,79);
aclrCust[12] = RGB(63,63,63);
aclrCust[13] = RGB(47,47,47);
aclrCust[14] = RGB(31,31,31);
aclrCust[15] = RGB(15,15,15);
memset(&cc, 0, sizeof(CHOOSECOLOR));
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = w->window->iconwin;
cc.lpCustColors = aclrCust;
cc.rgbResult = mscolor(w, r, g, b);
cc.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColor(&cc) == 0) {
return NULL;
}
sprintf(buf, "%d,%d,%d", (RED(cc.rgbResult)<<8) | 0xFF,
(GREEN(cc.rgbResult) << 8) | 0xFF,
(BLUE(cc.rgbResult) << 8) | 0xFF);
return buf;
}
char *nativeselectdialog(wbp w, struct b_list *L, char *s)
{
int i, j, okflag=0, yesnoflag=0, cancelflag=0, retryflag=0, otherflag=0;
tended struct b_list *hp = L;
tended char *s1 = NULL;
tended struct descrip d, d2;
char s3[8];
wsp ws = w->window;
int lsize;
if (hp == NULL) {
okflag = 1;
}
else {
BlkLoc(d2) = (union block *)hp;
d2.dword = D_List;
lsize = hp->size;
for(i=0; i < lsize; i++) {
c_get(hp, &d);
if (!cnv:C_string(d, s1)) return NULL;
for(j=0; j<8; j++) {
s3[j] = tolower(s1[j]);
if (s3[j] == '\0') break;
}
if (!strcmp(s3, "ok")) okflag = 1;
else if (!strcmp(s3, "okay")) okflag = 1;
else if (!strcmp(s3, "no")) yesnoflag = MB_YESNO;
else if (!strcmp(s3, "yes")) yesnoflag = MB_YESNO;
else if (!strcmp(s3, "cancel")) cancelflag++;
else if (!strcmp(s3, "retry")) retryflag = MB_RETRYCANCEL;
else { otherflag++; return NULL; }
c_put(&d2, &d);
}
}
/*
* validate flags
*/
if (okflag && yesnoflag) return NULL;
if (okflag && retryflag) return NULL;
if (yesnoflag && retryflag) return NULL;
if (retryflag && !cancelflag) return NULL;
if (cancelflag) {
if (okflag) {
okflag = MB_OKCANCEL;
}
else if (yesnoflag) yesnoflag = MB_YESNOCANCEL;
}
else if (okflag) okflag = MB_OK;
j = MessageBox((ws->focusChild ? ws->focusChild :
(ws->win ? ws->win : ws->iconwin)),
s, " ",
okflag | yesnoflag | retryflag
| (strchr(s, '!') ? MB_ICONEXCLAMATION :
(strchr(s, '?') ? MB_ICONQUESTION : MB_ICONASTERISK)));
switch (j) {
case IDOK: return "Okay";
case IDCANCEL: return "Cancel";
case IDYES: return "Yes";
case IDNO: return "No";
case IDRETRY: return "Retry";
default: return NULL;
}
}
OPENFILENAME ofn;
char *nativeopendialog(wbp w, char *s1, char *s2, char *s3, int i, int j)
{
char buf[128], buf2[64];
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = w->window->iconwin;
ofn.lpstrFilter = s3;
ofn.nFilterIndex = j;
strcpy(buf, s2);
ofn.lpstrFile = buf;
ofn.nMaxFile = sizeof(buf);
ofn.lpstrTitle = s1;
ofn.lpstrFileTitle = buf2;
ofn.nMaxFileTitle = sizeof(buf2);
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST;
if (GetOpenFileName(&ofn) == 0) return NULL;
return ofn.lpstrFile;
}
char *nativesavedialog(wbp w, char *s1, char *s2, char *s3, int i, int j)
{
char buf[128], buf2[64];
/*
* Use the standard dialog to obtain a filename.
*/
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = w->window->iconwin;
ofn.lpstrFilter = s3;
ofn.nFilterIndex = j;
strcpy(buf, s2);
ofn.lpstrFile = buf;
ofn.nMaxFile = sizeof(buf);
ofn.lpstrTitle = s1;
ofn.lpstrFileTitle = buf2;
ofn.nMaxFileTitle = sizeof(buf2);
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST;
if (GetSaveFileName(&ofn) == 0) return NULL;
return ofn.lpstrFile;
}
/*
* flush a window - noop under Windows
*/
void wflush(w)
wbp w;
{
}
#else /* Graphics */
static char aaa;
#endif /* Graphics */