xref: /plan9-contrib/sys/src/cmd/gs/src/gspmdrv.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /* Copyright (C) 1994 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gspmdrv.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
187dd7cddfSDavid du Colombier /* Presentation Manager driver for Ghostscript */
197dd7cddfSDavid du Colombier /* Written by Russell Lang */
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier /* To display output from os2pm driver: */
227dd7cddfSDavid du Colombier /*   gspmdrv -d id_string */
237dd7cddfSDavid du Colombier /* To display BMP file (used for testing display code) */
247dd7cddfSDavid du Colombier /*   gspmdrv -b filename.bmp */
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier #define INCL_DOS
277dd7cddfSDavid du Colombier #define INCL_WIN
287dd7cddfSDavid du Colombier #define INCL_GPI
297dd7cddfSDavid du Colombier #include <os2.h>
307dd7cddfSDavid du Colombier #include <stdio.h>
317dd7cddfSDavid du Colombier #include <stdlib.h>
327dd7cddfSDavid du Colombier #include <string.h>
337dd7cddfSDavid du Colombier #include <sys/emxload.h>
347dd7cddfSDavid du Colombier #include "gspmdrv.h"
357dd7cddfSDavid du Colombier #include "gdevpm.h"
367dd7cddfSDavid du Colombier 
377dd7cddfSDavid du Colombier #ifndef min
387dd7cddfSDavid du Colombier #define min(x,y)  ( (x) < (y) ? (x) : (y) )
397dd7cddfSDavid du Colombier #endif
407dd7cddfSDavid du Colombier #ifndef max
417dd7cddfSDavid du Colombier #define max(x,y)  ( (x) > (y) ? (x) : (y) )
427dd7cddfSDavid du Colombier #endif
437dd7cddfSDavid du Colombier 
447dd7cddfSDavid du Colombier HEV update_event_sem;
457dd7cddfSDavid du Colombier HMTX bmp_mutex_sem;
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier /* bitmap details */
487dd7cddfSDavid du Colombier typedef struct tagBM {
497dd7cddfSDavid du Colombier     BOOL valid;
507dd7cddfSDavid du Colombier     BOOL old_bmp;		/* bitmap type */
517dd7cddfSDavid du Colombier     PBITMAPINFO2 pbmi;		/* pointer to bitmap info */
527dd7cddfSDavid du Colombier     PBYTE bits;			/* pointer to bitmap bits */
537dd7cddfSDavid du Colombier     int width;
547dd7cddfSDavid du Colombier     int height;
557dd7cddfSDavid du Colombier     int planes;
567dd7cddfSDavid du Colombier     int depth;
577dd7cddfSDavid du Colombier     int palsize;
587dd7cddfSDavid du Colombier     int palimportant;
597dd7cddfSDavid du Colombier     int old_width;
607dd7cddfSDavid du Colombier     int old_height;
617dd7cddfSDavid du Colombier     int old_planes;
627dd7cddfSDavid du Colombier     int old_depth;
637dd7cddfSDavid du Colombier     int old_palsize;
647dd7cddfSDavid du Colombier     int old_palimportant;
657dd7cddfSDavid du Colombier } BMAP;
667dd7cddfSDavid du Colombier 
677dd7cddfSDavid du Colombier typedef struct tagDISPLAY {
687dd7cddfSDavid du Colombier     LONG planes;
697dd7cddfSDavid du Colombier     LONG bitcount;
707dd7cddfSDavid du Colombier     LONG hasPalMan;		/* Palette Manager */
717dd7cddfSDavid du Colombier     BOOL hpal_exists;
727dd7cddfSDavid du Colombier     HPAL hpal;
737dd7cddfSDavid du Colombier } DISPLAY;
747dd7cddfSDavid du Colombier 
757dd7cddfSDavid du Colombier /* options that are saved in INI file */
767dd7cddfSDavid du Colombier typedef struct tagOPTIONS {
777dd7cddfSDavid du Colombier     POINTL img_origin;
787dd7cddfSDavid du Colombier     POINTL img_size;
797dd7cddfSDavid du Colombier     BOOL img_max;
807dd7cddfSDavid du Colombier } OPTIONS;
817dd7cddfSDavid du Colombier 
827dd7cddfSDavid du Colombier #define CW_USEDEFAULT 32768
837dd7cddfSDavid du Colombier 
847dd7cddfSDavid du Colombier 
857dd7cddfSDavid du Colombier BMAP bitmap;
867dd7cddfSDavid du Colombier DISPLAY display;
877dd7cddfSDavid du Colombier OPTIONS option;
887dd7cddfSDavid du Colombier PBYTE bbuffer;			/* for BMP file display */
897dd7cddfSDavid du Colombier POINTL scroll_pos;		/* not used *//* not used */
907dd7cddfSDavid du Colombier ULONG os_version;
917dd7cddfSDavid du Colombier char *section = "Ghostscript Image";
927dd7cddfSDavid du Colombier 
937dd7cddfSDavid du Colombier HAB hab;			/* Anchor Block */
947dd7cddfSDavid du Colombier HWND hwnd_frame;
957dd7cddfSDavid du Colombier HWND hwnd_bmp;
967dd7cddfSDavid du Colombier HWND hwnd_gs;			/* window handle for CMD.EXE that started gs */
977dd7cddfSDavid du Colombier TID update_tid;
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier #define WM_GSUPDATE WM_USER+1
1007dd7cddfSDavid du Colombier #define SB_TOP 20
1017dd7cddfSDavid du Colombier #define SB_BOTTOM 21
1027dd7cddfSDavid du Colombier 
1037dd7cddfSDavid du Colombier 
1047dd7cddfSDavid du Colombier MRESULT EXPENTRY ClientWndProc(HWND, ULONG, MPARAM, MPARAM);
1057dd7cddfSDavid du Colombier MRESULT EXPENTRY AboutDlgProc(HWND, ULONG, MPARAM, MPARAM);
1067dd7cddfSDavid du Colombier APIRET init_window(void);
1077dd7cddfSDavid du Colombier void fix_sysmenu(HWND);
1087dd7cddfSDavid du Colombier APIRET restore_window_position(SWP * pswp);
1097dd7cddfSDavid du Colombier BOOL scan_bitmap(BMAP * pbm);
1107dd7cddfSDavid du Colombier void read_profile(void);
1117dd7cddfSDavid du Colombier void write_profile(void);
1127dd7cddfSDavid du Colombier APIRET init_display(int argc, char *argv[]);
1137dd7cddfSDavid du Colombier APIRET init_bitmap(int argc, char *argv[]);
1147dd7cddfSDavid du Colombier void copy_clipboard(void);
1157dd7cddfSDavid du Colombier HBITMAP make_bitmap(BMAP * pbm, ULONG left, ULONG bottom, ULONG right, ULONG top, ULONG depth);
1167dd7cddfSDavid du Colombier 
1177dd7cddfSDavid du Colombier void
debugbeep(int type)1187dd7cddfSDavid du Colombier debugbeep(int type)
1197dd7cddfSDavid du Colombier {
1207dd7cddfSDavid du Colombier #ifdef DEBUG
1217dd7cddfSDavid du Colombier     int i;
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier /* current debug beeps are: */
1247dd7cddfSDavid du Colombier /* 1. Null handle PS */
1257dd7cddfSDavid du Colombier /* 2. make_bitmap() failed */
1267dd7cddfSDavid du Colombier /* 3. GpiDrawBits() or WinDrawBitmap() failed */
1277dd7cddfSDavid du Colombier /* 4. Null handle PS from WinBeginPaint() */
1287dd7cddfSDavid du Colombier     for (i = 0; i < type; i++) {
1297dd7cddfSDavid du Colombier 	DosBeep(400 + 100 * type, 50);
1307dd7cddfSDavid du Colombier 	DosSleep(50);
1317dd7cddfSDavid du Colombier     }
1327dd7cddfSDavid du Colombier #endif
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier 
1357dd7cddfSDavid du Colombier 
1367dd7cddfSDavid du Colombier /* display message */
1377dd7cddfSDavid du Colombier int
message_box(char * str,int icon)1387dd7cddfSDavid du Colombier message_box(char *str, int icon)
1397dd7cddfSDavid du Colombier {
1407dd7cddfSDavid du Colombier     return WinMessageBox(HWND_DESKTOP, hwnd_frame ? hwnd_frame : HWND_DESKTOP,
1417dd7cddfSDavid du Colombier 			 str, "gspmdrv.exe", 0, icon | MB_MOVEABLE | MB_OK);
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier void
error_message(char * str)1457dd7cddfSDavid du Colombier error_message(char *str)
1467dd7cddfSDavid du Colombier {
1477dd7cddfSDavid du Colombier     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, str, "gspmdrv.exe", 0, MB_MOVEABLE | MB_ICONHAND | MB_OK);
1487dd7cddfSDavid du Colombier     WinPostMsg(hwnd_frame, WM_QUIT, MPFROMLONG(0), MPFROMLONG(0));
1497dd7cddfSDavid du Colombier }
1507dd7cddfSDavid du Colombier 
1517dd7cddfSDavid du Colombier /* Update thread */
1527dd7cddfSDavid du Colombier /* This thread waits for the update event semaphore from gs.exe */
1537dd7cddfSDavid du Colombier /* then generates a WM_PAINT message for the bitmap */
1547dd7cddfSDavid du Colombier /* This thread must NOT call C library functions */
1557dd7cddfSDavid du Colombier VOID APIENTRY
update_func(ULONG unused)1567dd7cddfSDavid du Colombier update_func(ULONG unused)
1577dd7cddfSDavid du Colombier {
1587dd7cddfSDavid du Colombier     APIRET rc;
1597dd7cddfSDavid du Colombier     BOOL flag;
1607dd7cddfSDavid du Colombier     ULONG count;
1617dd7cddfSDavid du Colombier 
1627dd7cddfSDavid du Colombier     unused = unused;		/* to shut up warning */
1637dd7cddfSDavid du Colombier     while (!DosQueryEventSem(update_event_sem, &count)) {
1647dd7cddfSDavid du Colombier 	/* loop while semaphore exists */
1657dd7cddfSDavid du Colombier 	DosWaitEventSem(update_event_sem, SEM_INDEFINITE_WAIT);
1667dd7cddfSDavid du Colombier 	DosResetEventSem(update_event_sem, &count);
1677dd7cddfSDavid du Colombier 	WinPostMsg(hwnd_bmp, WM_GSUPDATE, MPFROMLONG(0), MPFROMLONG(0));
1687dd7cddfSDavid du Colombier     }
1697dd7cddfSDavid du Colombier }
1707dd7cddfSDavid du Colombier 
1717dd7cddfSDavid du Colombier VOID APIENTRY
exit_func(ULONG code)1727dd7cddfSDavid du Colombier exit_func(ULONG code)
1737dd7cddfSDavid du Colombier {
1747dd7cddfSDavid du Colombier     write_profile();
1757dd7cddfSDavid du Colombier     DosCloseEventSem(update_event_sem);
1767dd7cddfSDavid du Colombier     DosCloseMutexSem(bmp_mutex_sem);
1777dd7cddfSDavid du Colombier     DosFreeMem((PVOID) bitmap.pbmi);
1787dd7cddfSDavid du Colombier     DosExitList(EXLST_EXIT, 0);
1797dd7cddfSDavid du Colombier     code = code;		/* to shut up warning */
1807dd7cddfSDavid du Colombier }
1817dd7cddfSDavid du Colombier 
1827dd7cddfSDavid du Colombier void
find_hwnd_gs(char * gsid)1837dd7cddfSDavid du Colombier find_hwnd_gs(char *gsid)
1847dd7cddfSDavid du Colombier {
1857dd7cddfSDavid du Colombier     ULONG ulCount;
1867dd7cddfSDavid du Colombier     ULONG ulLength;
1877dd7cddfSDavid du Colombier     ULONG pBase;
1887dd7cddfSDavid du Colombier     ULONG cbBuf;
1897dd7cddfSDavid du Colombier     PSWBLOCK pswblk;
1907dd7cddfSDavid du Colombier     PSWENTRY pswentry;
1917dd7cddfSDavid du Colombier     SWCNTRL *pswc;
1927dd7cddfSDavid du Colombier     int i;
1937dd7cddfSDavid du Colombier     ULONG pid;
1947dd7cddfSDavid du Colombier     char buf[256];
1957dd7cddfSDavid du Colombier     char *p, *s;
1967dd7cddfSDavid du Colombier     PTIB pptib;
1977dd7cddfSDavid du Colombier     PPIB pppib;
1987dd7cddfSDavid du Colombier 
1997dd7cddfSDavid du Colombier     /* extract gs pid from command line id */
2007dd7cddfSDavid du Colombier     strcpy(buf, gsid);
2017dd7cddfSDavid du Colombier     for (p = buf; *p && *p != '_'; p++);
2027dd7cddfSDavid du Colombier     *p++ = '\0';
2037dd7cddfSDavid du Colombier     s = p;
2047dd7cddfSDavid du Colombier     for (p = buf; *p && *p != '_'; p++);
2057dd7cddfSDavid du Colombier     *p = '\0';
2067dd7cddfSDavid du Colombier     pid = atoi(s);		/* pid is Process ID of CMD.EXE that started gsos2.exe */
2077dd7cddfSDavid du Colombier 
2087dd7cddfSDavid du Colombier     ulCount = WinQuerySwitchList(hab, NULL, 0);		/* get num of items */
2097dd7cddfSDavid du Colombier     cbBuf = (ulCount * sizeof(SWENTRY)) + sizeof(HSWITCH);
2107dd7cddfSDavid du Colombier     pswblk = (PSWBLOCK) malloc(cbBuf + 32768);
2117dd7cddfSDavid du Colombier     ulCount = WinQuerySwitchList(hab, pswblk, cbBuf);	/* get num of items */
2127dd7cddfSDavid du Colombier     for (i = 0; i < ulCount; i++) {
2137dd7cddfSDavid du Colombier 	pswentry = &pswblk->aswentry[i];
2147dd7cddfSDavid du Colombier 	pswc = &pswentry->swctl;
2157dd7cddfSDavid du Colombier 	if (pid == pswc->idProcess)
2167dd7cddfSDavid du Colombier 	    hwnd_gs = pswc->hwnd;	/* save window handle */
2177dd7cddfSDavid du Colombier     }
2187dd7cddfSDavid du Colombier }
2197dd7cddfSDavid du Colombier 
2207dd7cddfSDavid du Colombier 
2217dd7cddfSDavid du Colombier int
main(int argc,char * argv[])2227dd7cddfSDavid du Colombier main(int argc, char *argv[])
2237dd7cddfSDavid du Colombier {
2247dd7cddfSDavid du Colombier     HMQ hand_mq;		/* message queue */
2257dd7cddfSDavid du Colombier     QMSG q_mess;		/* message queue */
2267dd7cddfSDavid du Colombier     APIRET rc = 0;
2277dd7cddfSDavid du Colombier 
2287dd7cddfSDavid du Colombier 
2297dd7cddfSDavid du Colombier     hab = WinInitialize(0);	/* Get the Anchor Block */
2307dd7cddfSDavid du Colombier 
2317dd7cddfSDavid du Colombier     hand_mq = WinCreateMsgQueue(hab, 0);	/* start a queue */
2327dd7cddfSDavid du Colombier 
2337dd7cddfSDavid du Colombier     if (argc < 2) {
2347dd7cddfSDavid du Colombier 	rc = 1;
2357dd7cddfSDavid du Colombier 	error_message("Usage: gspmdrv -d id_string");
2367dd7cddfSDavid du Colombier     }
2377dd7cddfSDavid du Colombier     if (!rc) {
2387dd7cddfSDavid du Colombier 	if (strcmp(argv[1], "-d") == 0) {
2397dd7cddfSDavid du Colombier 	    rc = init_display(argc, argv);
2407dd7cddfSDavid du Colombier 	} else if (strcmp(argv[1], "-b") == 0) {
2417dd7cddfSDavid du Colombier 	    rc = init_bitmap(argc, argv);
2427dd7cddfSDavid du Colombier 	} else {
2437dd7cddfSDavid du Colombier 	    rc = 1;
2447dd7cddfSDavid du Colombier 	    error_message("Usage: gspmdrv -d id_string");
2457dd7cddfSDavid du Colombier 	}
2467dd7cddfSDavid du Colombier     }
2477dd7cddfSDavid du Colombier     if (!rc) {
2487dd7cddfSDavid du Colombier 	rc = DosCreateThread(&update_tid, update_func, 0, 0, 8192);
2497dd7cddfSDavid du Colombier 	if (rc)
2507dd7cddfSDavid du Colombier 	    error_message("Failed to create update thread");
2517dd7cddfSDavid du Colombier     }
2527dd7cddfSDavid du Colombier     if (!rc)
2537dd7cddfSDavid du Colombier 	rc = init_window();
2547dd7cddfSDavid du Colombier 
2557dd7cddfSDavid du Colombier     if (!rc)
2567dd7cddfSDavid du Colombier 	WinShowWindow(hwnd_frame, TRUE);
2577dd7cddfSDavid du Colombier 
2587dd7cddfSDavid du Colombier     if (!rc) {
2597dd7cddfSDavid du Colombier 	/* keep gspmdrv.exe in memory for number of minutes specified in */
2607dd7cddfSDavid du Colombier 	/* environment variable GS_LOAD */
2617dd7cddfSDavid du Colombier 	_emxload_env("GS_LOAD");
2627dd7cddfSDavid du Colombier     }
2637dd7cddfSDavid du Colombier     DosExitList(EXLST_ADD, exit_func);
2647dd7cddfSDavid du Colombier 
2657dd7cddfSDavid du Colombier     /* message loop */
2667dd7cddfSDavid du Colombier     while (!rc && WinGetMsg(hab, &q_mess, 0L, 0, 0))
2677dd7cddfSDavid du Colombier 	WinDispatchMsg(hab, &q_mess);
2687dd7cddfSDavid du Colombier 
2697dd7cddfSDavid du Colombier     /* Shut down the application window and queue */
2707dd7cddfSDavid du Colombier     DosKillThread(update_tid);
2717dd7cddfSDavid du Colombier     WinDestroyWindow(hwnd_frame);
2727dd7cddfSDavid du Colombier     WinDestroyMsgQueue(hand_mq);
2737dd7cddfSDavid du Colombier     WinTerminate(hab);
2747dd7cddfSDavid du Colombier     return rc;
2757dd7cddfSDavid du Colombier }
2767dd7cddfSDavid du Colombier 
2777dd7cddfSDavid du Colombier APIRET
init_window()2787dd7cddfSDavid du Colombier init_window()
2797dd7cddfSDavid du Colombier {
2807dd7cddfSDavid du Colombier     ULONG version[3];
2817dd7cddfSDavid du Colombier     SWP swp;
2827dd7cddfSDavid du Colombier     APIRET rc = 0;
2837dd7cddfSDavid du Colombier     ULONG flFlags;		/* Window frame definition */
2847dd7cddfSDavid du Colombier     unsigned char class[] = "gspmdrvClass";	/* class name */
2857dd7cddfSDavid du Colombier 
2867dd7cddfSDavid du Colombier     if (DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_REVISION, &version, sizeof(version)))
2877dd7cddfSDavid du Colombier 	os_version = 201000;	/* a guess */
2887dd7cddfSDavid du Colombier     else {
2897dd7cddfSDavid du Colombier 	os_version = version[0] * 10000 + version[1] * 100 + version[2];
2907dd7cddfSDavid du Colombier     }
2917dd7cddfSDavid du Colombier 
2927dd7cddfSDavid du Colombier     /* define the frame constants */
2937dd7cddfSDavid du Colombier     flFlags = FCF_TITLEBAR |	/* have a title bar */
2947dd7cddfSDavid du Colombier 	FCF_SIZEBORDER |	/* have a sizeable window */
2957dd7cddfSDavid du Colombier 	FCF_MINMAX |		/* have a min and max button */
2967dd7cddfSDavid du Colombier 	FCF_SYSMENU |		/* include a system menu */
2977dd7cddfSDavid du Colombier 	FCF_VERTSCROLL |	/* vertical scroll bar */
2987dd7cddfSDavid du Colombier 	FCF_HORZSCROLL |	/* horizontal scroll bar */
2997dd7cddfSDavid du Colombier 	FCF_TASKLIST |		/* show it in window list */
3007dd7cddfSDavid du Colombier 	FCF_ICON;		/* Load icon from resources */
3017dd7cddfSDavid du Colombier 
3027dd7cddfSDavid du Colombier     /* save SHELL default size and location */
3037dd7cddfSDavid du Colombier     rc = WinQueryTaskSizePos(hab, 0, &swp);
3047dd7cddfSDavid du Colombier     if (rc)
3057dd7cddfSDavid du Colombier 	return rc;
3067dd7cddfSDavid du Colombier 
3077dd7cddfSDavid du Colombier     read_profile();
3087dd7cddfSDavid du Colombier     if ((option.img_size.x == 0) || (option.img_size.y == 0))
3097dd7cddfSDavid du Colombier 	option.img_size.x = option.img_size.y = CW_USEDEFAULT;
3107dd7cddfSDavid du Colombier 
3117dd7cddfSDavid du Colombier     if (!rc) {
3127dd7cddfSDavid du Colombier 	HPS ps = WinGetPS(HWND_DESKTOP);
3137dd7cddfSDavid du Colombier 	HDC hdc = GpiQueryDevice(ps);
3147dd7cddfSDavid du Colombier 
3157dd7cddfSDavid du Colombier 	DevQueryCaps(hdc, CAPS_COLOR_PLANES, 1, &display.planes);
3167dd7cddfSDavid du Colombier 	DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &display.bitcount);
3177dd7cddfSDavid du Colombier 	DevQueryCaps(hdc, CAPS_ADDITIONAL_GRAPHICS, 1, &display.hasPalMan);
3187dd7cddfSDavid du Colombier 	display.hasPalMan &= CAPS_PALETTE_MANAGER;
3197dd7cddfSDavid du Colombier 	WinReleasePS(ps);
3207dd7cddfSDavid du Colombier     }
3217dd7cddfSDavid du Colombier     if (!rc) {
3227dd7cddfSDavid du Colombier 	if (!WinRegisterClass(	/* register this window class */
3237dd7cddfSDavid du Colombier 				 hab,	/* anchor block */
3247dd7cddfSDavid du Colombier 				 (PSZ) class,	/* class name */
3257dd7cddfSDavid du Colombier 				 (PFNWP) ClientWndProc,		/* window function */
3267dd7cddfSDavid du Colombier 				 CS_SIZEREDRAW |	/* window style */
3277dd7cddfSDavid du Colombier 				 CS_MOVENOTIFY,
3287dd7cddfSDavid du Colombier 				 0))	/* no storage */
3297dd7cddfSDavid du Colombier 	    exit(1);
3307dd7cddfSDavid du Colombier 
3317dd7cddfSDavid du Colombier 	hwnd_frame = WinCreateStdWindow(
3327dd7cddfSDavid du Colombier 					   HWND_DESKTOP,	/* window type */
3337dd7cddfSDavid du Colombier 					   0,	/* frame style is not WS_VISIBLE */
3347dd7cddfSDavid du Colombier 					   &flFlags,	/* definitions */
3357dd7cddfSDavid du Colombier 					   (PSZ) class,		/* client class */
3367dd7cddfSDavid du Colombier 					   (PSZ) "Ghostscript Image",	/* title */
3377dd7cddfSDavid du Colombier 					   WS_VISIBLE,	/* client style */
3387dd7cddfSDavid du Colombier 					   0,	/* resource module */
3397dd7cddfSDavid du Colombier 					   ID_GSPMDRV,	/* resource identifier */
3407dd7cddfSDavid du Colombier 					   &hwnd_bmp);	/* pointer to client */
3417dd7cddfSDavid du Colombier 
3427dd7cddfSDavid du Colombier 	fix_sysmenu(hwnd_frame);
3437dd7cddfSDavid du Colombier     }
3447dd7cddfSDavid du Colombier     rc = restore_window_position(&swp);
3457dd7cddfSDavid du Colombier 
3467dd7cddfSDavid du Colombier     return rc;
3477dd7cddfSDavid du Colombier }
3487dd7cddfSDavid du Colombier 
3497dd7cddfSDavid du Colombier 
3507dd7cddfSDavid du Colombier void
write_profile(void)3517dd7cddfSDavid du Colombier write_profile(void)
3527dd7cddfSDavid du Colombier {
3537dd7cddfSDavid du Colombier     char profile[64];
3547dd7cddfSDavid du Colombier 
3557dd7cddfSDavid du Colombier     sprintf(profile, "%d %d", option.img_origin.x, option.img_origin.y);
3567dd7cddfSDavid du Colombier     PrfWriteProfileString(HINI_USERPROFILE, section, "Origin", profile);
3577dd7cddfSDavid du Colombier     sprintf(profile, "%d %d", option.img_size.x, option.img_size.y);
3587dd7cddfSDavid du Colombier     PrfWriteProfileString(HINI_USERPROFILE, section, "Size", profile);
3597dd7cddfSDavid du Colombier     sprintf(profile, "%d", option.img_max);
3607dd7cddfSDavid du Colombier     PrfWriteProfileString(HINI_USERPROFILE, section, "Maximized", profile);
3617dd7cddfSDavid du Colombier }
3627dd7cddfSDavid du Colombier 
3637dd7cddfSDavid du Colombier void
read_profile(void)3647dd7cddfSDavid du Colombier read_profile(void)
3657dd7cddfSDavid du Colombier {
3667dd7cddfSDavid du Colombier     char profile[64];
3677dd7cddfSDavid du Colombier 
3687dd7cddfSDavid du Colombier     PrfQueryProfileString(HINI_USERPROFILE, section, "Origin", "", profile, sizeof(profile));
3697dd7cddfSDavid du Colombier     if (sscanf(profile, "%d %d", &option.img_origin.x, &option.img_origin.y) != 2) {
3707dd7cddfSDavid du Colombier 	option.img_origin.x = CW_USEDEFAULT;
3717dd7cddfSDavid du Colombier 	option.img_origin.y = CW_USEDEFAULT;
3727dd7cddfSDavid du Colombier     }
3737dd7cddfSDavid du Colombier     PrfQueryProfileString(HINI_USERPROFILE, section, "Size", "", profile, sizeof(profile));
3747dd7cddfSDavid du Colombier     if (sscanf(profile, "%d %d", &option.img_size.x, &option.img_size.y) != 2) {
3757dd7cddfSDavid du Colombier 	option.img_size.x = CW_USEDEFAULT;
3767dd7cddfSDavid du Colombier 	option.img_size.y = CW_USEDEFAULT;
3777dd7cddfSDavid du Colombier     }
3787dd7cddfSDavid du Colombier     PrfQueryProfileString(HINI_USERPROFILE, section, "Maximized", "", profile, sizeof(profile));
3797dd7cddfSDavid du Colombier     if (sscanf(profile, "%d", &option.img_max) != 1)
3807dd7cddfSDavid du Colombier 	option.img_max = 0;
3817dd7cddfSDavid du Colombier }
3827dd7cddfSDavid du Colombier 
3837dd7cddfSDavid du Colombier void
fix_sysmenu(HWND hwnd)3847dd7cddfSDavid du Colombier fix_sysmenu(HWND hwnd)
3857dd7cddfSDavid du Colombier {
3867dd7cddfSDavid du Colombier     MENUITEM mi;
3877dd7cddfSDavid du Colombier     HWND hwndSysMenu;
3887dd7cddfSDavid du Colombier 
3897dd7cddfSDavid du Colombier     if (!WinSendMsg(WinWindowFromID(hwnd, FID_SYSMENU), MM_QUERYITEM,
3907dd7cddfSDavid du Colombier 		    MPFROM2SHORT(SC_SYSMENU, TRUE), MPFROMP(&mi))) {
3917dd7cddfSDavid du Colombier 	message_box("failed getting system menu handle", 0);
3927dd7cddfSDavid du Colombier 	return;
3937dd7cddfSDavid du Colombier     }
3947dd7cddfSDavid du Colombier     hwndSysMenu = mi.hwndSubMenu;
3957dd7cddfSDavid du Colombier     mi.iPosition = MIT_END;
3967dd7cddfSDavid du Colombier     mi.afStyle = MIS_SEPARATOR;
3977dd7cddfSDavid du Colombier     mi.afAttribute = 0;
3987dd7cddfSDavid du Colombier     mi.id = 0;
3997dd7cddfSDavid du Colombier     mi.hwndSubMenu = 0;
4007dd7cddfSDavid du Colombier     mi.hItem = 0;
4017dd7cddfSDavid du Colombier     WinSendMsg(hwndSysMenu, MM_INSERTITEM, MPFROMP(&mi), NULL);
4027dd7cddfSDavid du Colombier     mi.afStyle = MIS_TEXT;
4037dd7cddfSDavid du Colombier     mi.id = IDM_ABOUT;
4047dd7cddfSDavid du Colombier     WinSendMsg(hwndSysMenu, MM_INSERTITEM, MPFROMP(&mi), "About...");
4057dd7cddfSDavid du Colombier     mi.id = IDM_COPY;
4067dd7cddfSDavid du Colombier     WinSendMsg(hwndSysMenu, MM_INSERTITEM, MPFROMP(&mi), "Copy");
4077dd7cddfSDavid du Colombier }
4087dd7cddfSDavid du Colombier 
4097dd7cddfSDavid du Colombier APIRET
restore_window_position(SWP * pswp)4107dd7cddfSDavid du Colombier restore_window_position(SWP * pswp)
4117dd7cddfSDavid du Colombier {
4127dd7cddfSDavid du Colombier     SWP swp;
4137dd7cddfSDavid du Colombier 
4147dd7cddfSDavid du Colombier     swp.fl = SWP_MOVE | SWP_SIZE | SWP_SHOW;
4157dd7cddfSDavid du Colombier 
4167dd7cddfSDavid du Colombier     if (option.img_max) {
4177dd7cddfSDavid du Colombier 	/* Get maximized frame window position and size. */
4187dd7cddfSDavid du Colombier 	if (!WinGetMaxPosition(hwnd_frame, &swp))
4197dd7cddfSDavid du Colombier 	    return 1;
4207dd7cddfSDavid du Colombier 	swp.fl |= SWP_MAXIMIZE;
4217dd7cddfSDavid du Colombier     } else if ((option.img_size.x != CW_USEDEFAULT) &&
4227dd7cddfSDavid du Colombier 	       (option.img_size.y != CW_USEDEFAULT) &&
4237dd7cddfSDavid du Colombier 	       (option.img_origin.y != CW_USEDEFAULT) &&
4247dd7cddfSDavid du Colombier 	       (option.img_origin.y != CW_USEDEFAULT)) {
4257dd7cddfSDavid du Colombier 	LONG cxClientMax;
4267dd7cddfSDavid du Colombier 	LONG cyClientMax;
4277dd7cddfSDavid du Colombier 	LONG cyTitleBar;
4287dd7cddfSDavid du Colombier 	LONG cxSizeBorder;
4297dd7cddfSDavid du Colombier 	LONG cySizeBorder;
4307dd7cddfSDavid du Colombier 
4317dd7cddfSDavid du Colombier 	/* get maximum client window size */
4327dd7cddfSDavid du Colombier 	cxClientMax = WinQuerySysValue(HWND_DESKTOP, SV_CXFULLSCREEN);
4337dd7cddfSDavid du Colombier 	cyClientMax = WinQuerySysValue(HWND_DESKTOP, SV_CYFULLSCREEN);
4347dd7cddfSDavid du Colombier 	cyTitleBar = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
4357dd7cddfSDavid du Colombier 	cxSizeBorder = WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
4367dd7cddfSDavid du Colombier 	cySizeBorder = WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
4377dd7cddfSDavid du Colombier 	cyClientMax += cyTitleBar;
4387dd7cddfSDavid du Colombier 
4397dd7cddfSDavid du Colombier 	/* Make sure x origin is within display boundaries */
4407dd7cddfSDavid du Colombier 	swp.x = option.img_origin.x;
4417dd7cddfSDavid du Colombier 	if (swp.x < -cxSizeBorder)
4427dd7cddfSDavid du Colombier 	    swp.x = 0;
4437dd7cddfSDavid du Colombier 
4447dd7cddfSDavid du Colombier 	/* Make sure window isn't too wide, or negative value */
4457dd7cddfSDavid du Colombier 	swp.cx = option.img_size.x;
4467dd7cddfSDavid du Colombier 	if (swp.cx >= cxClientMax || swp.cx < 0) {
4477dd7cddfSDavid du Colombier 	    swp.cx = cxClientMax;
4487dd7cddfSDavid du Colombier 	    swp.x = 0;
4497dd7cddfSDavid du Colombier 	}
4507dd7cddfSDavid du Colombier 	if ((swp.x + swp.cx) > (cxClientMax + cxSizeBorder))
4517dd7cddfSDavid du Colombier 	    swp.x = cxClientMax + cxSizeBorder - swp.cx;
4527dd7cddfSDavid du Colombier 
4537dd7cddfSDavid du Colombier 	/* Make sure y origin is within display boundaries */
4547dd7cddfSDavid du Colombier 	swp.y = option.img_origin.y;
4557dd7cddfSDavid du Colombier 	if (swp.y < -cySizeBorder)
4567dd7cddfSDavid du Colombier 	    swp.y = 0;
4577dd7cddfSDavid du Colombier 
4587dd7cddfSDavid du Colombier 	/* Make sure window isn't too high, or negative value */
4597dd7cddfSDavid du Colombier 	swp.cy = option.img_size.y;
4607dd7cddfSDavid du Colombier 	if (swp.cy > cyClientMax || swp.cy < 0) {
4617dd7cddfSDavid du Colombier 	    swp.cy = cyClientMax;
4627dd7cddfSDavid du Colombier 	    swp.y = 0;
4637dd7cddfSDavid du Colombier 	}
4647dd7cddfSDavid du Colombier 	if ((swp.y + swp.cy) > (cyClientMax + cySizeBorder))
4657dd7cddfSDavid du Colombier 	    swp.y = cyClientMax + cySizeBorder - swp.cy;
4667dd7cddfSDavid du Colombier     } else {			/* No saved position -- use supplied position */
4677dd7cddfSDavid du Colombier 	swp = *pswp;
4687dd7cddfSDavid du Colombier 	option.img_origin.x = swp.x;
4697dd7cddfSDavid du Colombier 	option.img_origin.y = swp.y;
4707dd7cddfSDavid du Colombier 	option.img_size.x = swp.cx;
4717dd7cddfSDavid du Colombier 	option.img_size.y = swp.cy;
4727dd7cddfSDavid du Colombier 	option.img_max = FALSE;
4737dd7cddfSDavid du Colombier 	swp.fl = SWP_MOVE | SWP_SIZE | SWP_SHOW;
4747dd7cddfSDavid du Colombier     }
4757dd7cddfSDavid du Colombier 
4767dd7cddfSDavid du Colombier     if (hwnd_gs)
4777dd7cddfSDavid du Colombier 	swp.fl |= SWP_ZORDER;
4787dd7cddfSDavid du Colombier     /* Position and size this frame window */
4797dd7cddfSDavid du Colombier     if (!WinSetWindowPos(hwnd_frame, hwnd_gs,
4807dd7cddfSDavid du Colombier 			 swp.x, swp.y, swp.cx, swp.cy, swp.fl))
4817dd7cddfSDavid du Colombier 	return 1;
4827dd7cddfSDavid du Colombier     return 0;
4837dd7cddfSDavid du Colombier }
4847dd7cddfSDavid du Colombier 
4857dd7cddfSDavid du Colombier APIRET
init_display(int argc,char * argv[])4867dd7cddfSDavid du Colombier init_display(int argc, char *argv[])
4877dd7cddfSDavid du Colombier {
4887dd7cddfSDavid du Colombier     char buf[256];
4897dd7cddfSDavid du Colombier     char name[256];
4907dd7cddfSDavid du Colombier     APIRET rc = 0;
4917dd7cddfSDavid du Colombier 
4927dd7cddfSDavid du Colombier     if (argc != 3) {
4937dd7cddfSDavid du Colombier 	rc = 1;
4947dd7cddfSDavid du Colombier 	error_message("Usage: gspmdrv -d id_string");
4957dd7cddfSDavid du Colombier     }
4967dd7cddfSDavid du Colombier     find_hwnd_gs(argv[2]);
4977dd7cddfSDavid du Colombier 
4987dd7cddfSDavid du Colombier     if (!rc) {
4997dd7cddfSDavid du Colombier 	sprintf(name, SHARED_NAME, argv[2]);
5007dd7cddfSDavid du Colombier 	rc = DosGetNamedSharedMem((PVOID *) & bitmap.pbmi, name, PAG_READ | PAG_WRITE);
5017dd7cddfSDavid du Colombier 	if (rc) {
5027dd7cddfSDavid du Colombier 	    sprintf(buf, "Failed to open: bmp shared memory \"%s\" rc = %d", argv[0], rc);
5037dd7cddfSDavid du Colombier 	    error_message(buf);
5047dd7cddfSDavid du Colombier 	}
5057dd7cddfSDavid du Colombier     }
5067dd7cddfSDavid du Colombier     if (!rc) {
5077dd7cddfSDavid du Colombier 	sprintf(name, SYNC_NAME, argv[2]);
5087dd7cddfSDavid du Colombier 	rc = DosOpenEventSem(name, &update_event_sem);
5097dd7cddfSDavid du Colombier 	if (rc) {
5107dd7cddfSDavid du Colombier 	    sprintf(buf, "Failed to open: update event semaphore \"%s\" rc = %d", argv[1], rc);
5117dd7cddfSDavid du Colombier 	    error_message(buf);
5127dd7cddfSDavid du Colombier 	}
5137dd7cddfSDavid du Colombier     }
5147dd7cddfSDavid du Colombier     if (!rc) {
5157dd7cddfSDavid du Colombier 	sprintf(name, MUTEX_NAME, argv[2]);
5167dd7cddfSDavid du Colombier 	rc = DosOpenMutexSem(name, &bmp_mutex_sem);
5177dd7cddfSDavid du Colombier 	if (rc) {
5187dd7cddfSDavid du Colombier 	    sprintf(buf, "Failed to open: bmp mutex semaphore \"%s\" rc = %d", argv[1], rc);
5197dd7cddfSDavid du Colombier 	    error_message(buf);
5207dd7cddfSDavid du Colombier 	}
5217dd7cddfSDavid du Colombier     }
5227dd7cddfSDavid du Colombier     if (!rc) {
5237dd7cddfSDavid du Colombier 	scan_bitmap(&bitmap);
5247dd7cddfSDavid du Colombier 	bitmap.valid = TRUE;
5257dd7cddfSDavid du Colombier     }
5267dd7cddfSDavid du Colombier     return rc;
5277dd7cddfSDavid du Colombier }
5287dd7cddfSDavid du Colombier 
5297dd7cddfSDavid du Colombier 
5307dd7cddfSDavid du Colombier APIRET
init_bitmap(int argc,char * argv[])5317dd7cddfSDavid du Colombier init_bitmap(int argc, char *argv[])
5327dd7cddfSDavid du Colombier {
5337dd7cddfSDavid du Colombier     char buf[256];
5347dd7cddfSDavid du Colombier     APIRET rc = 0;
5357dd7cddfSDavid du Colombier     HFILE hf;
5367dd7cddfSDavid du Colombier     ULONG action, count, length;
5377dd7cddfSDavid du Colombier     PBITMAPFILEHEADER2 pbmfh;
5387dd7cddfSDavid du Colombier 
5397dd7cddfSDavid du Colombier     if (argc != 3)
5407dd7cddfSDavid du Colombier 	return 1;		/* error - no filename */
5417dd7cddfSDavid du Colombier 
5427dd7cddfSDavid du Colombier     /* open bitmap */
5437dd7cddfSDavid du Colombier     if ((rc = DosOpen(argv[2], &hf, &action, 0, FILE_NORMAL, FILE_OPEN,
5447dd7cddfSDavid du Colombier 		      OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE, 0))
5457dd7cddfSDavid du Colombier 	!= (APIRET) 0) {
5467dd7cddfSDavid du Colombier 	sprintf(buf, "Error opening: %s", argv[2]);
5477dd7cddfSDavid du Colombier 	error_message(buf);
5487dd7cddfSDavid du Colombier 	return rc;
5497dd7cddfSDavid du Colombier     }
5507dd7cddfSDavid du Colombier     rc = DosSetFilePtr(hf, 0, FILE_END, &length);
5517dd7cddfSDavid du Colombier     if (rc) {
5527dd7cddfSDavid du Colombier 	sprintf(buf, "failed seeking to EOF: error = %d", rc);
5537dd7cddfSDavid du Colombier 	error_message(buf);
5547dd7cddfSDavid du Colombier 	return rc;
5557dd7cddfSDavid du Colombier     }
5567dd7cddfSDavid du Colombier     rc = DosSetFilePtr(hf, 0, FILE_BEGIN, &count);
5577dd7cddfSDavid du Colombier     if (rc) {
5587dd7cddfSDavid du Colombier 	sprintf(buf, "failed seeking to BOF: error = %d", rc);
5597dd7cddfSDavid du Colombier 	error_message(buf);
5607dd7cddfSDavid du Colombier 	return rc;
5617dd7cddfSDavid du Colombier     };
5627dd7cddfSDavid du Colombier 
5637dd7cddfSDavid du Colombier     /* allocate memory for bitmap */
5647dd7cddfSDavid du Colombier     if ((rc = DosAllocMem((PPVOID) & bbuffer, length, PAG_READ | PAG_WRITE | PAG_COMMIT))
5657dd7cddfSDavid du Colombier 	!= (APIRET) 0) {
5667dd7cddfSDavid du Colombier 	sprintf(buf, "failed allocating memory");
5677dd7cddfSDavid du Colombier 	error_message(buf);
5687dd7cddfSDavid du Colombier 	return rc;
5697dd7cddfSDavid du Colombier     }
5707dd7cddfSDavid du Colombier     rc = DosRead(hf, bbuffer, length, &count);
5717dd7cddfSDavid du Colombier     DosClose(hf);
5727dd7cddfSDavid du Colombier     if (rc) {
5737dd7cddfSDavid du Colombier 	sprintf(buf, "failed reading bitmap, error = %u, count = %u", rc, count);
5747dd7cddfSDavid du Colombier 	error_message(buf);
5757dd7cddfSDavid du Colombier 	return rc;
5767dd7cddfSDavid du Colombier     }
5777dd7cddfSDavid du Colombier     /* extract some info about bitmap */
5787dd7cddfSDavid du Colombier     pbmfh = (PBITMAPFILEHEADER2) bbuffer;
5797dd7cddfSDavid du Colombier     bitmap.pbmi = (PBITMAPINFO2) (&pbmfh->bmp2);
5807dd7cddfSDavid du Colombier 
5817dd7cddfSDavid du Colombier     scan_bitmap(&bitmap);
5827dd7cddfSDavid du Colombier     bitmap.valid = TRUE;
5837dd7cddfSDavid du Colombier 
5847dd7cddfSDavid du Colombier     sprintf(buf, "bitmap width = %d, height = %d", bitmap.width, bitmap.height);
5857dd7cddfSDavid du Colombier     message_box(buf, 0);
5867dd7cddfSDavid du Colombier     return rc;
5877dd7cddfSDavid du Colombier }
5887dd7cddfSDavid du Colombier 
5897dd7cddfSDavid du Colombier #define MAX_PAL_SIZE 256
5907dd7cddfSDavid du Colombier void
make_palette(BMAP * pbm)5917dd7cddfSDavid du Colombier make_palette(BMAP * pbm)
5927dd7cddfSDavid du Colombier {
5937dd7cddfSDavid du Colombier     ULONG tbl[MAX_PAL_SIZE];
5947dd7cddfSDavid du Colombier     PRGB2 palptr = (PRGB2) ((PBYTE) (pbm->pbmi) + pbm->pbmi->cbFix);
5957dd7cddfSDavid du Colombier     RGB *old_palptr = (RGB *) palptr;
5967dd7cddfSDavid du Colombier     int palcount = pbm->palimportant;
5977dd7cddfSDavid du Colombier     int i;
5987dd7cddfSDavid du Colombier     BOOL old_bmp = (pbm->pbmi->cbFix == sizeof(BITMAPINFOHEADER));
5997dd7cddfSDavid du Colombier 
6007dd7cddfSDavid du Colombier     if (old_bmp) {
6017dd7cddfSDavid du Colombier 	for (i = 0; i < palcount; i++) {
6027dd7cddfSDavid du Colombier 	    tbl[i] = (old_palptr->bRed << 16) + (old_palptr->bGreen << 8) + (old_palptr->bBlue);
6037dd7cddfSDavid du Colombier 	    palptr++;
6047dd7cddfSDavid du Colombier 	}
6057dd7cddfSDavid du Colombier     } else {
6067dd7cddfSDavid du Colombier 	for (i = 0; i < palcount; i++) {
6077dd7cddfSDavid du Colombier 	    tbl[i] = (palptr->bRed << 16) + (palptr->bGreen << 8) + (palptr->bBlue);
6087dd7cddfSDavid du Colombier 	    palptr++;
6097dd7cddfSDavid du Colombier 	}
6107dd7cddfSDavid du Colombier     }
6117dd7cddfSDavid du Colombier     if (display.hpal_exists)
6127dd7cddfSDavid du Colombier 	GpiDeletePalette(display.hpal);
6137dd7cddfSDavid du Colombier     display.hpal = GpiCreatePalette(hab, 0L, LCOLF_CONSECRGB, palcount, tbl);
6147dd7cddfSDavid du Colombier     display.hpal_exists = TRUE;
6157dd7cddfSDavid du Colombier }
6167dd7cddfSDavid du Colombier 
6177dd7cddfSDavid du Colombier 
6187dd7cddfSDavid du Colombier 
6197dd7cddfSDavid du Colombier /* scan bitmap */
6207dd7cddfSDavid du Colombier /* update bitmap structure */
6217dd7cddfSDavid du Colombier /* return value is TRUE if bitmap dimension has changed */
6227dd7cddfSDavid du Colombier BOOL
scan_bitmap(BMAP * pbm)6237dd7cddfSDavid du Colombier scan_bitmap(BMAP * pbm)
6247dd7cddfSDavid du Colombier {
6257dd7cddfSDavid du Colombier     PBITMAPINFO2 pbmi = pbm->pbmi;
6267dd7cddfSDavid du Colombier     PBITMAPINFO old_pbmi = (PBITMAPINFO) pbmi;
6277dd7cddfSDavid du Colombier     BOOL old_bmp = (pbmi->cbFix == sizeof(BITMAPINFOHEADER));
6287dd7cddfSDavid du Colombier 
6297dd7cddfSDavid du Colombier     if (old_bmp) {
6307dd7cddfSDavid du Colombier 	/* it is a BITMAPINFO */
6317dd7cddfSDavid du Colombier 	switch (old_pbmi->cBitCount) {
6327dd7cddfSDavid du Colombier 	    case 24:
6337dd7cddfSDavid du Colombier 		pbm->palsize = 0;
6347dd7cddfSDavid du Colombier 		break;
6357dd7cddfSDavid du Colombier 	    case 8:
6367dd7cddfSDavid du Colombier 		pbm->palsize = 256;
6377dd7cddfSDavid du Colombier 		break;
6387dd7cddfSDavid du Colombier 	    case 4:
6397dd7cddfSDavid du Colombier 		pbm->palsize = 16;
6407dd7cddfSDavid du Colombier 		break;
6417dd7cddfSDavid du Colombier 	    case 1:
6427dd7cddfSDavid du Colombier 		pbm->palsize = 2;
6437dd7cddfSDavid du Colombier 		break;
6447dd7cddfSDavid du Colombier 	    default:
6457dd7cddfSDavid du Colombier 		pbm->valid = FALSE;
6467dd7cddfSDavid du Colombier 		error_message("scan_bitmap: wrong number of bits");	/* panic */
6477dd7cddfSDavid du Colombier 		return FALSE;
6487dd7cddfSDavid du Colombier 	}
6497dd7cddfSDavid du Colombier 	pbm->palimportant = pbm->palsize;
6507dd7cddfSDavid du Colombier 	pbm->palsize = pbm->palsize * sizeof(RGB);
6517dd7cddfSDavid du Colombier 	pbm->bits = (PBYTE) old_pbmi + old_pbmi->cbFix + pbm->palsize;
6527dd7cddfSDavid du Colombier 	pbm->width = old_pbmi->cx;
6537dd7cddfSDavid du Colombier 	pbm->height = old_pbmi->cy;
6547dd7cddfSDavid du Colombier 	pbm->planes = old_pbmi->cPlanes;
6557dd7cddfSDavid du Colombier 	pbm->depth = old_pbmi->cBitCount;
6567dd7cddfSDavid du Colombier     } else {
6577dd7cddfSDavid du Colombier 	/* it is a BITMAPINFO2 */
6587dd7cddfSDavid du Colombier 	switch (pbmi->cBitCount) {
6597dd7cddfSDavid du Colombier 	    case 24:
6607dd7cddfSDavid du Colombier 		pbm->palsize = 0;
6617dd7cddfSDavid du Colombier 		break;
6627dd7cddfSDavid du Colombier 	    case 8:
6637dd7cddfSDavid du Colombier 		pbm->palsize = 256;
6647dd7cddfSDavid du Colombier 		break;
6657dd7cddfSDavid du Colombier 	    case 4:
6667dd7cddfSDavid du Colombier 		pbm->palsize = 16;
6677dd7cddfSDavid du Colombier 		break;
6687dd7cddfSDavid du Colombier 	    case 1:
6697dd7cddfSDavid du Colombier 		pbm->palsize = 2;
6707dd7cddfSDavid du Colombier 		break;
6717dd7cddfSDavid du Colombier 	    default:
6727dd7cddfSDavid du Colombier 		pbm->valid = FALSE;
6737dd7cddfSDavid du Colombier 		error_message("scan_bitmap: wrong number of bits");	/* panic */
6747dd7cddfSDavid du Colombier 		return FALSE;
6757dd7cddfSDavid du Colombier 	}
6767dd7cddfSDavid du Colombier 	if ((pbmi->cbFix > (&(pbmi->cclrUsed) - &(pbmi->cbFix)))
6777dd7cddfSDavid du Colombier 	    && (pbmi->cclrUsed != 0) && (pbmi->cBitCount != 24))
6787dd7cddfSDavid du Colombier 	    pbm->palsize = pbmi->cclrUsed;
6797dd7cddfSDavid du Colombier 	pbm->palimportant = pbm->palsize;
6807dd7cddfSDavid du Colombier 	if ((pbmi->cbFix > (&(pbmi->cclrImportant) - &(pbmi->cbFix)))
6817dd7cddfSDavid du Colombier 	    && (pbmi->cclrImportant != 0) && (pbmi->cBitCount != 24))
6827dd7cddfSDavid du Colombier 	    pbm->palimportant = pbmi->cclrImportant;
6837dd7cddfSDavid du Colombier 	pbm->palsize = pbm->palsize * sizeof(RGB2);
6847dd7cddfSDavid du Colombier 	pbm->bits = (PBYTE) pbmi + pbmi->cbFix + pbm->palsize;
6857dd7cddfSDavid du Colombier 	pbm->width = pbmi->cx;
6867dd7cddfSDavid du Colombier 	pbm->height = pbmi->cy;
6877dd7cddfSDavid du Colombier 	pbm->planes = pbmi->cPlanes;
6887dd7cddfSDavid du Colombier 	pbm->depth = pbmi->cBitCount;
6897dd7cddfSDavid du Colombier     }
6907dd7cddfSDavid du Colombier 
6917dd7cddfSDavid du Colombier     if ((pbm->palsize != pbm->old_palsize) || (pbm->palimportant != pbm->old_palimportant)) {
6927dd7cddfSDavid du Colombier 	if ((pbm->depth == 8) && display.hasPalMan)
6937dd7cddfSDavid du Colombier 	    make_palette(pbm);
6947dd7cddfSDavid du Colombier 	pbm->old_palimportant = pbm->palimportant;
6957dd7cddfSDavid du Colombier     }
6967dd7cddfSDavid du Colombier     if ((pbm->width == pbm->old_width) &&
6977dd7cddfSDavid du Colombier 	(pbm->height == pbm->old_height) &&
6987dd7cddfSDavid du Colombier 	(pbm->planes == pbm->old_planes) &&
6997dd7cddfSDavid du Colombier 	(pbm->depth == pbm->old_depth) &&
7007dd7cddfSDavid du Colombier 	(pbm->palsize == pbm->old_palsize) &&
7017dd7cddfSDavid du Colombier 	(pbm->old_bmp == old_bmp))
7027dd7cddfSDavid du Colombier 	return FALSE;
7037dd7cddfSDavid du Colombier 
7047dd7cddfSDavid du Colombier     /* bitmap has changed */
7057dd7cddfSDavid du Colombier     pbm->old_width = pbm->width;
7067dd7cddfSDavid du Colombier     pbm->old_height = pbm->height;
7077dd7cddfSDavid du Colombier     pbm->old_planes = pbm->planes;
7087dd7cddfSDavid du Colombier     pbm->old_depth = pbm->depth;
7097dd7cddfSDavid du Colombier     pbm->old_palsize = pbm->palsize;
7107dd7cddfSDavid du Colombier     pbm->old_bmp = old_bmp;
7117dd7cddfSDavid du Colombier     return TRUE;
7127dd7cddfSDavid du Colombier }
7137dd7cddfSDavid du Colombier 
7147dd7cddfSDavid du Colombier 
7157dd7cddfSDavid du Colombier void
update_scroll_bars(void)7167dd7cddfSDavid du Colombier update_scroll_bars(void)
7177dd7cddfSDavid du Colombier {
7187dd7cddfSDavid du Colombier     /* Cause update of scroll bars etc. */
7197dd7cddfSDavid du Colombier     SWP swp;
7207dd7cddfSDavid du Colombier 
7217dd7cddfSDavid du Colombier     WinQueryWindowPos(hwnd_bmp, &swp);
7227dd7cddfSDavid du Colombier     WinSendMsg(hwnd_bmp, WM_SIZE, MPFROM2SHORT(swp.cx, swp.cy), MPFROM2SHORT(swp.cx, swp.cy));
7237dd7cddfSDavid du Colombier }
7247dd7cddfSDavid du Colombier 
7257dd7cddfSDavid du Colombier 
7267dd7cddfSDavid du Colombier /* copy bitmap to the clipboard */
7277dd7cddfSDavid du Colombier void
copy_clipboard(void)7287dd7cddfSDavid du Colombier copy_clipboard(void)
7297dd7cddfSDavid du Colombier {
7307dd7cddfSDavid du Colombier     HBITMAP hbmp;
7317dd7cddfSDavid du Colombier 
7327dd7cddfSDavid du Colombier     if (!bitmap.valid) {
7337dd7cddfSDavid du Colombier 	message_box("Cannot copy to clipboard:\nNo Bitmap displayed", 0);
7347dd7cddfSDavid du Colombier 	return;
7357dd7cddfSDavid du Colombier     }
7367dd7cddfSDavid du Colombier     if (WinOpenClipbrd(hab)) {
7377dd7cddfSDavid du Colombier 	/* get bmp mutex to stop gs.exe changing bitmap while we copy it */
7387dd7cddfSDavid du Colombier 	DosRequestMutexSem(bmp_mutex_sem, 10000);
7397dd7cddfSDavid du Colombier 	if (scan_bitmap(&bitmap)) {
7407dd7cddfSDavid du Colombier 	    /* bitmap has changed */
7417dd7cddfSDavid du Colombier 	    update_scroll_bars();
7427dd7cddfSDavid du Colombier 	}
7437dd7cddfSDavid du Colombier 	hbmp = make_bitmap(&bitmap, 0, 0, bitmap.width, bitmap.height, bitmap.depth);
7447dd7cddfSDavid du Colombier 	if (hbmp) {
7457dd7cddfSDavid du Colombier 	    WinEmptyClipbrd(hab);
7467dd7cddfSDavid du Colombier 	    WinSetClipbrdData(hab, (ULONG) hbmp, CF_BITMAP, CFI_HANDLE);
7477dd7cddfSDavid du Colombier 	}
7487dd7cddfSDavid du Colombier 	DosReleaseMutexSem(bmp_mutex_sem);
7497dd7cddfSDavid du Colombier 	WinCloseClipbrd(hab);
7507dd7cddfSDavid du Colombier     }
7517dd7cddfSDavid du Colombier }
7527dd7cddfSDavid du Colombier 
7537dd7cddfSDavid du Colombier 
7547dd7cddfSDavid du Colombier HBITMAP
make_bitmap(BMAP * pbm,ULONG left,ULONG bottom,ULONG right,ULONG top,ULONG depth)7557dd7cddfSDavid du Colombier make_bitmap(BMAP * pbm, ULONG left, ULONG bottom, ULONG right, ULONG top, ULONG depth)
7567dd7cddfSDavid du Colombier {
7577dd7cddfSDavid du Colombier     HDC hdc = DEV_ERROR, hdcMem = DEV_ERROR;
7587dd7cddfSDavid du Colombier     HPS hps = GPI_ERROR;
7597dd7cddfSDavid du Colombier     HBITMAP hbmp = GPI_ERROR, hbmr = HBM_ERROR;
7607dd7cddfSDavid du Colombier     SIZEL sizePS;
7617dd7cddfSDavid du Colombier     BITMAPINFOHEADER2 bmih;
7627dd7cddfSDavid du Colombier 
7637dd7cddfSDavid du Colombier     if ((left == right) || (bottom == top))
7647dd7cddfSDavid du Colombier 	return (HBITMAP) NULL;
7657dd7cddfSDavid du Colombier 
7667dd7cddfSDavid du Colombier     if (right > pbm->width)
7677dd7cddfSDavid du Colombier 	right = pbm->width;
7687dd7cddfSDavid du Colombier     if (left > pbm->width)
7697dd7cddfSDavid du Colombier 	left = 0;
7707dd7cddfSDavid du Colombier     if (top > pbm->height)
7717dd7cddfSDavid du Colombier 	top = pbm->height;
7727dd7cddfSDavid du Colombier     if (bottom > pbm->height)
7737dd7cddfSDavid du Colombier 	bottom = 0;
7747dd7cddfSDavid du Colombier 
7757dd7cddfSDavid du Colombier     memset(&bmih, 0, sizeof(bmih));
7767dd7cddfSDavid du Colombier     bmih.cbFix = sizeof(BITMAPINFOHEADER2);
7777dd7cddfSDavid du Colombier     bmih.cx = right - left;
7787dd7cddfSDavid du Colombier     bmih.cy = top - bottom;
7797dd7cddfSDavid du Colombier     bmih.cPlanes = 1;
7807dd7cddfSDavid du Colombier     bmih.cBitCount = depth;
7817dd7cddfSDavid du Colombier 
7827dd7cddfSDavid du Colombier     /* create memory DC compatible with screen */
7837dd7cddfSDavid du Colombier     hdcMem = DevOpenDC(hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE);
7847dd7cddfSDavid du Colombier 
7857dd7cddfSDavid du Colombier     sizePS.cx = right - left;
7867dd7cddfSDavid du Colombier     sizePS.cy = top - bottom;
7877dd7cddfSDavid du Colombier     if (hdcMem != DEV_ERROR)
7887dd7cddfSDavid du Colombier 	hps = GpiCreatePS(hab, hdcMem, &sizePS,
7897dd7cddfSDavid du Colombier 			  PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC);
7907dd7cddfSDavid du Colombier 
7917dd7cddfSDavid du Colombier     if (hps != GPI_ERROR)
7927dd7cddfSDavid du Colombier 	hbmp = GpiCreateBitmap(hps, &bmih, 0L, NULL, NULL);
7937dd7cddfSDavid du Colombier 
7947dd7cddfSDavid du Colombier     if (hbmp != GPI_ERROR)
7957dd7cddfSDavid du Colombier 	hbmr = GpiSetBitmap(hps, hbmp);
7967dd7cddfSDavid du Colombier 
7977dd7cddfSDavid du Colombier 
7987dd7cddfSDavid du Colombier     if (hbmr != HBM_ERROR) {
7997dd7cddfSDavid du Colombier 	LONG rc;
8007dd7cddfSDavid du Colombier 	ERRORID eid;
8017dd7cddfSDavid du Colombier 	POINTL apts[4];
8027dd7cddfSDavid du Colombier 
8037dd7cddfSDavid du Colombier 	/* target is inclusive */
8047dd7cddfSDavid du Colombier 	apts[0].x = 0;
8057dd7cddfSDavid du Colombier 	apts[0].y = 0;
8067dd7cddfSDavid du Colombier 	apts[1].x = right - left - 1;
8077dd7cddfSDavid du Colombier 	apts[1].y = top - bottom - 1;
8087dd7cddfSDavid du Colombier 	/* source is not inclusive of top & right borders */
8097dd7cddfSDavid du Colombier 	apts[2].x = left;
8107dd7cddfSDavid du Colombier 	apts[2].y = bottom;
8117dd7cddfSDavid du Colombier 	apts[3].x = right;
8127dd7cddfSDavid du Colombier 	apts[3].y = top;
8137dd7cddfSDavid du Colombier 
8147dd7cddfSDavid du Colombier 	rc = 0;
8157dd7cddfSDavid du Colombier 	eid = WinGetLastError(hab);
8167dd7cddfSDavid du Colombier 	rc = GpiDrawBits(hps, pbm->bits, pbm->pbmi, 4, apts,
8177dd7cddfSDavid du Colombier 		     (bitmap.depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0);
8187dd7cddfSDavid du Colombier 	if (rc == 0) {
8197dd7cddfSDavid du Colombier 	    char buf[256];
8207dd7cddfSDavid du Colombier 
8217dd7cddfSDavid du Colombier 	    eid = WinGetLastError(hab);
8227dd7cddfSDavid du Colombier 	    sprintf(buf, "make_bitmap: GpiDrawBits rc = %08x, eid = %08x", rc, eid);
8237dd7cddfSDavid du Colombier 	    message_box(buf, 0);
8247dd7cddfSDavid du Colombier 	}
8257dd7cddfSDavid du Colombier     }
8267dd7cddfSDavid du Colombier     if (hbmr != HBM_ERROR)
8277dd7cddfSDavid du Colombier 	GpiSetBitmap(hps, (ULONG) 0);
8287dd7cddfSDavid du Colombier     if (hps != GPI_ERROR)
8297dd7cddfSDavid du Colombier 	GpiDestroyPS(hps);
8307dd7cddfSDavid du Colombier     if (hdcMem != DEV_ERROR)
8317dd7cddfSDavid du Colombier 	DevCloseDC(hdcMem);
8327dd7cddfSDavid du Colombier 
8337dd7cddfSDavid du Colombier     if ((hbmr == HBM_ERROR) || (hdcMem == DEV_ERROR) ||
8347dd7cddfSDavid du Colombier 	(hbmp == GPI_ERROR) || (hps == GPI_ERROR)) {
8357dd7cddfSDavid du Colombier 	if (hbmp != GPI_ERROR)
8367dd7cddfSDavid du Colombier 	    GpiDeleteBitmap(hbmp);
8377dd7cddfSDavid du Colombier 	debugbeep(2);
8387dd7cddfSDavid du Colombier 	return 0;
8397dd7cddfSDavid du Colombier     }
8407dd7cddfSDavid du Colombier     return hbmp;
8417dd7cddfSDavid du Colombier }
8427dd7cddfSDavid du Colombier 
8437dd7cddfSDavid du Colombier MRESULT
paint_bitmap(HPS ps,PRECTL prect,int scrollx,int scrolly)8447dd7cddfSDavid du Colombier paint_bitmap(HPS ps, PRECTL prect, int scrollx, int scrolly)
8457dd7cddfSDavid du Colombier {
8467dd7cddfSDavid du Colombier     POINTL apts[4];
8477dd7cddfSDavid du Colombier     int wx, wy;
8487dd7cddfSDavid du Colombier 
8497dd7cddfSDavid du Colombier     if (WinIsRectEmpty(hab, prect))
8507dd7cddfSDavid du Colombier 	return 0;
8517dd7cddfSDavid du Colombier     if (ps == NULLHANDLE) {
8527dd7cddfSDavid du Colombier 	debugbeep(1);
8537dd7cddfSDavid du Colombier     }
8547dd7cddfSDavid du Colombier     /* source is not inclusive of top & right borders */
8557dd7cddfSDavid du Colombier     wx = prect->xRight - prect->xLeft;	/* update width */
8567dd7cddfSDavid du Colombier     wy = prect->yTop - prect->yBottom;	/* update height */
8577dd7cddfSDavid du Colombier     apts[2].x = prect->xLeft + scrollx;
8587dd7cddfSDavid du Colombier     apts[2].y = prect->yBottom + scrolly;
8597dd7cddfSDavid du Colombier     if (apts[2].x > bitmap.width)
8607dd7cddfSDavid du Colombier 	apts[2].x = bitmap.width;
8617dd7cddfSDavid du Colombier     if (apts[2].x + wx > bitmap.width)
8627dd7cddfSDavid du Colombier 	wx = bitmap.width - apts[2].x;
8637dd7cddfSDavid du Colombier     apts[3].x = apts[2].x + wx;
8647dd7cddfSDavid du Colombier     if (apts[2].y > bitmap.height)
8657dd7cddfSDavid du Colombier 	apts[2].y = bitmap.height;
8667dd7cddfSDavid du Colombier     if (apts[2].y + wy > bitmap.height)
8677dd7cddfSDavid du Colombier 	wy = bitmap.height - apts[2].y;
8687dd7cddfSDavid du Colombier     apts[3].y = apts[2].y + wy;
8697dd7cddfSDavid du Colombier     /* target is inclusive */
8707dd7cddfSDavid du Colombier     apts[0].x = prect->xLeft;
8717dd7cddfSDavid du Colombier     apts[0].y = prect->yBottom;
8727dd7cddfSDavid du Colombier     apts[1].x = prect->xLeft + wx - 1;
8737dd7cddfSDavid du Colombier     apts[1].y = prect->yBottom + wy - 1;
8747dd7cddfSDavid du Colombier 
8757dd7cddfSDavid du Colombier     if ((display.bitcount == 4)	/* standard VGA is buggy */
8767dd7cddfSDavid du Colombier 	||((os_version == 201100) && (display.bitcount == 8) && (bitmap.depth == 1))	/* S3 and ATI GU are buggy */
8777dd7cddfSDavid du Colombier 	) {
8787dd7cddfSDavid du Colombier 	/* slow code to dodge OS/2 bugs */
8797dd7cddfSDavid du Colombier 	/* this code double buffers the bitmap and works on a standard VGA
8807dd7cddfSDavid du Colombier 	 * but didn't work on an ATI Ultra Graphics Pro in 8514 emulation
8817dd7cddfSDavid du Colombier 	 */
8827dd7cddfSDavid du Colombier 	/* This won't work for version 2.11, S3 or ATI GU, 8bit/pixel display, 8bit/pixel bitmap */
8837dd7cddfSDavid du Colombier 	HBITMAP hbmp;
8847dd7cddfSDavid du Colombier 
8857dd7cddfSDavid du Colombier 	/* create a bitmap */
8867dd7cddfSDavid du Colombier 	hbmp = make_bitmap(&bitmap, apts[2].x, apts[2].y, apts[3].x, apts[3].y, bitmap.depth);
8877dd7cddfSDavid du Colombier 	/* Draw it to the display */
8887dd7cddfSDavid du Colombier 	if (hbmp) {
8897dd7cddfSDavid du Colombier 	    WinDrawBitmap(ps, hbmp, NULL, &apts[0], CLR_BLACK, CLR_WHITE, DBM_NORMAL);
8907dd7cddfSDavid du Colombier 	    GpiDeleteBitmap(hbmp);
8917dd7cddfSDavid du Colombier 	}
8927dd7cddfSDavid du Colombier     } else {
8937dd7cddfSDavid du Colombier 	/* fast code which doesn't always work */
8947dd7cddfSDavid du Colombier 	/* This code works on the Trident SVGA and 8514 in 256 color mode,
8957dd7cddfSDavid du Colombier 	 * but GpiDrawBits fails with a SYS3175 on the standard VGA.
8967dd7cddfSDavid du Colombier 	 */
8977dd7cddfSDavid du Colombier 	/* This won't work for version 2.11, S3 or ATI GU, 8bit/pixel display, 1bit/pixel bitmap */
8987dd7cddfSDavid du Colombier 	GpiDrawBits(ps, bitmap.bits, bitmap.pbmi, 4, apts,
8997dd7cddfSDavid du Colombier 		    (bitmap.depth != 1) ? ROP_SRCCOPY : ROP_NOTSRCCOPY, 0);
9007dd7cddfSDavid du Colombier     }
9017dd7cddfSDavid du Colombier 
9027dd7cddfSDavid du Colombier     return 0;
9037dd7cddfSDavid du Colombier }
9047dd7cddfSDavid du Colombier 
9057dd7cddfSDavid du Colombier 
9067dd7cddfSDavid du Colombier /* This is the window function */
9077dd7cddfSDavid du Colombier MRESULT EXPENTRY
ClientWndProc(HWND hwnd,ULONG mess,MPARAM mp1,MPARAM mp2)9087dd7cddfSDavid du Colombier ClientWndProc(HWND hwnd, ULONG mess,
9097dd7cddfSDavid du Colombier 	      MPARAM mp1, MPARAM mp2)
9107dd7cddfSDavid du Colombier {
9117dd7cddfSDavid du Colombier     char buf[256];
9127dd7cddfSDavid du Colombier     static int cxClient, cyClient;
9137dd7cddfSDavid du Colombier     static int cxAdjust, cyAdjust;
9147dd7cddfSDavid du Colombier     static int nHscrollMax, nHscrollPos;
9157dd7cddfSDavid du Colombier     static int nVscrollMax, nVscrollPos;
9167dd7cddfSDavid du Colombier     int nHscrollInc;
9177dd7cddfSDavid du Colombier     int nVscrollInc;
9187dd7cddfSDavid du Colombier     HWND hwndScroll;
9197dd7cddfSDavid du Colombier     HPS hps;
9207dd7cddfSDavid du Colombier     RECTL rect;
9217dd7cddfSDavid du Colombier     ULONG ulclr;
9227dd7cddfSDavid du Colombier 
9237dd7cddfSDavid du Colombier     switch (mess) {
9247dd7cddfSDavid du Colombier 	case WM_CREATE:
9257dd7cddfSDavid du Colombier 	    break;
9267dd7cddfSDavid du Colombier 	case WM_ERASEBACKGROUND:
9277dd7cddfSDavid du Colombier 	    /* by returning TRUE, the Presentation Manager automatically clears
9287dd7cddfSDavid du Colombier 	     * the window each time the window is resized or moved.
9297dd7cddfSDavid du Colombier 	     */
9307dd7cddfSDavid du Colombier 	    return (MRESULT) TRUE;
9317dd7cddfSDavid du Colombier 	case WM_GSUPDATE:
9327dd7cddfSDavid du Colombier 	    if (!WinInvalidateRect(hwnd_bmp, (PRECTL) NULL, TRUE))
9337dd7cddfSDavid du Colombier 		error_message("error invalidating rect");
9347dd7cddfSDavid du Colombier 	    if (!WinUpdateWindow(hwnd_bmp))
9357dd7cddfSDavid du Colombier 		error_message("error updating window");
9367dd7cddfSDavid du Colombier 	    return 0;
9377dd7cddfSDavid du Colombier 	case WM_COMMAND:
9387dd7cddfSDavid du Colombier 	    switch (LONGFROMMP(mp1)) {
9397dd7cddfSDavid du Colombier 		case IDM_ABOUT:
9407dd7cddfSDavid du Colombier 		    WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, 0, IDD_ABOUT, 0);
9417dd7cddfSDavid du Colombier 		    break;
9427dd7cddfSDavid du Colombier 		case IDM_COPY:
9437dd7cddfSDavid du Colombier 		    copy_clipboard();
9447dd7cddfSDavid du Colombier 		    break;
9457dd7cddfSDavid du Colombier 	    }
9467dd7cddfSDavid du Colombier 	    break;
9477dd7cddfSDavid du Colombier 	case WM_REALIZEPALETTE:
9487dd7cddfSDavid du Colombier 	    if ((bitmap.depth == 8) && display.hasPalMan && display.hpal_exists) {
9497dd7cddfSDavid du Colombier 		hps = WinGetPS(hwnd);
9507dd7cddfSDavid du Colombier 		if (hps == NULLHANDLE)
9517dd7cddfSDavid du Colombier 		    debugbeep(1);
9527dd7cddfSDavid du Colombier 		GpiSelectPalette(hps, display.hpal);
9537dd7cddfSDavid du Colombier 		if (WinRealizePalette(hwnd, hps, &ulclr) > 0)
9547dd7cddfSDavid du Colombier 		    WinInvalidateRect(hwnd, NULL, FALSE);
9557dd7cddfSDavid du Colombier 		GpiSelectPalette(hps, (HPAL) NULL);
9567dd7cddfSDavid du Colombier 		WinReleasePS(hps);
9577dd7cddfSDavid du Colombier 		return 0;
9587dd7cddfSDavid du Colombier 	    }
9597dd7cddfSDavid du Colombier 	    break;		/* use default processing */
9607dd7cddfSDavid du Colombier 	case WM_PAINT:
9617dd7cddfSDavid du Colombier 	    /* Refresh the window each time the WM_PAINT message is received */
9627dd7cddfSDavid du Colombier 
9637dd7cddfSDavid du Colombier 	    /* get bmp mutex to stop gs.exe changing bitmap while we paint */
9647dd7cddfSDavid du Colombier 	    DosRequestMutexSem(bmp_mutex_sem, 10000);
9657dd7cddfSDavid du Colombier 	    if (scan_bitmap(&bitmap))
9667dd7cddfSDavid du Colombier 		update_scroll_bars();	/* bitmap has changed */
9677dd7cddfSDavid du Colombier 
9687dd7cddfSDavid du Colombier 	    if (!bitmap.valid) {
9697dd7cddfSDavid du Colombier 		DosReleaseMutexSem(bmp_mutex_sem);
9707dd7cddfSDavid du Colombier 		hps = WinBeginPaint(hwnd, (ULONG) 0, &rect);
9717dd7cddfSDavid du Colombier 		if (hps == NULLHANDLE)
9727dd7cddfSDavid du Colombier 		    debugbeep(4);
9737dd7cddfSDavid du Colombier 		WinFillRect(hps, &rect, CLR_BACKGROUND);
9747dd7cddfSDavid du Colombier 		WinEndPaint(hwnd);
9757dd7cddfSDavid du Colombier 		return 0;
9767dd7cddfSDavid du Colombier 	    }
9777dd7cddfSDavid du Colombier 	    hps = WinBeginPaint(hwnd, (HPS) NULL, &rect);
9787dd7cddfSDavid du Colombier 	    if (hps == NULLHANDLE)
9797dd7cddfSDavid du Colombier 		debugbeep(4);
9807dd7cddfSDavid du Colombier 	    if ((bitmap.depth == 8) && display.hasPalMan && display.hpal_exists) {
9817dd7cddfSDavid du Colombier 		GpiSelectPalette(hps, display.hpal);
9827dd7cddfSDavid du Colombier 		WinRealizePalette(hwnd, hps, &ulclr);
9837dd7cddfSDavid du Colombier 		paint_bitmap(hps, &rect, nHscrollPos, nVscrollMax - nVscrollPos);
9847dd7cddfSDavid du Colombier 		GpiSelectPalette(hps, (HPAL) NULL);
9857dd7cddfSDavid du Colombier 	    } else
9867dd7cddfSDavid du Colombier 		paint_bitmap(hps, &rect, nHscrollPos, nVscrollMax - nVscrollPos);
9877dd7cddfSDavid du Colombier 	    WinEndPaint(hwnd);
9887dd7cddfSDavid du Colombier 
9897dd7cddfSDavid du Colombier 	    DosReleaseMutexSem(bmp_mutex_sem);
9907dd7cddfSDavid du Colombier 	    return 0;
9917dd7cddfSDavid du Colombier 	case WM_MOVE:
9927dd7cddfSDavid du Colombier 	    /* don't interrogate the window location immediately since */
9937dd7cddfSDavid du Colombier 	    /* it causes the Diamond Stealth VL24 with IBM S3 drivers */
9947dd7cddfSDavid du Colombier 	    /* to corrupt the display */
9957dd7cddfSDavid du Colombier 	    DosSleep(50);
9967dd7cddfSDavid du Colombier 	    if (hwnd_frame) {	/* save window position for INI file */
9977dd7cddfSDavid du Colombier 		SWP swp;
9987dd7cddfSDavid du Colombier 
9997dd7cddfSDavid du Colombier 		WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
10007dd7cddfSDavid du Colombier 		if (!(swp.fl & SWP_MINIMIZE)) {
10017dd7cddfSDavid du Colombier 		    option.img_origin.x = swp.x;
10027dd7cddfSDavid du Colombier 		    option.img_origin.y = swp.y;
10037dd7cddfSDavid du Colombier 		    option.img_max = ((swp.fl & SWP_MAXIMIZE) != 0);
10047dd7cddfSDavid du Colombier 		}
10057dd7cddfSDavid du Colombier 	    }
10067dd7cddfSDavid du Colombier 	    return 0;
10077dd7cddfSDavid du Colombier 	case WM_SIZE:
10087dd7cddfSDavid du Colombier 	    cyClient = SHORT2FROMMP(mp2);
10097dd7cddfSDavid du Colombier 	    cxClient = SHORT1FROMMP(mp2);
10107dd7cddfSDavid du Colombier 
10117dd7cddfSDavid du Colombier 	    cyAdjust = min(bitmap.height, cyClient) - cyClient;
10127dd7cddfSDavid du Colombier 	    cyClient += cyAdjust;
10137dd7cddfSDavid du Colombier 
10147dd7cddfSDavid du Colombier 	    nVscrollMax = max(0, bitmap.height - cyClient);
10157dd7cddfSDavid du Colombier 	    nVscrollPos = min(nVscrollPos, nVscrollMax);
10167dd7cddfSDavid du Colombier 	    scroll_pos.y = nVscrollMax - nVscrollPos;
10177dd7cddfSDavid du Colombier 
10187dd7cddfSDavid du Colombier 	    if (!bitmap.valid)
10197dd7cddfSDavid du Colombier 		cyClient = cyAdjust = nVscrollMax = nVscrollPos;
10207dd7cddfSDavid du Colombier 
10217dd7cddfSDavid du Colombier 	    hwndScroll = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), FID_VERTSCROLL);
10227dd7cddfSDavid du Colombier 	    WinSendMsg(hwndScroll, SBM_SETSCROLLBAR, MPFROMLONG(nVscrollPos),
10237dd7cddfSDavid du Colombier 		       MPFROM2SHORT(0, nVscrollMax));
10247dd7cddfSDavid du Colombier 	    if (bitmap.valid)
10257dd7cddfSDavid du Colombier 		WinSendMsg(hwndScroll, SBM_SETTHUMBSIZE, MPFROM2SHORT(cyClient, bitmap.height),
10267dd7cddfSDavid du Colombier 			   MPFROMLONG(0));
10277dd7cddfSDavid du Colombier 	    else
10287dd7cddfSDavid du Colombier 		WinSendMsg(hwndScroll, SBM_SETTHUMBSIZE, MPFROM2SHORT(1, 1),
10297dd7cddfSDavid du Colombier 			   MPFROMLONG(0));
10307dd7cddfSDavid du Colombier 
10317dd7cddfSDavid du Colombier 	    cxAdjust = min(bitmap.width, cxClient) - cxClient;
10327dd7cddfSDavid du Colombier 	    cxClient += cxAdjust;
10337dd7cddfSDavid du Colombier 
10347dd7cddfSDavid du Colombier 	    nHscrollMax = max(0, bitmap.width - cxClient);
10357dd7cddfSDavid du Colombier 	    nHscrollPos = min(nHscrollPos, nHscrollMax);
10367dd7cddfSDavid du Colombier 	    scroll_pos.x = nHscrollPos;
10377dd7cddfSDavid du Colombier 
10387dd7cddfSDavid du Colombier 	    if (!bitmap.valid)
10397dd7cddfSDavid du Colombier 		cxClient = cxAdjust = nHscrollMax = nHscrollPos;
10407dd7cddfSDavid du Colombier 
10417dd7cddfSDavid du Colombier 	    hwndScroll = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), FID_HORZSCROLL);
10427dd7cddfSDavid du Colombier 	    WinSendMsg(hwndScroll, SBM_SETSCROLLBAR, MPFROMLONG(nHscrollPos),
10437dd7cddfSDavid du Colombier 		       MPFROM2SHORT(0, nHscrollMax));
10447dd7cddfSDavid du Colombier 	    if (bitmap.valid)
10457dd7cddfSDavid du Colombier 		WinSendMsg(hwndScroll, SBM_SETTHUMBSIZE, MPFROM2SHORT(cxClient, bitmap.width),
10467dd7cddfSDavid du Colombier 			   MPFROMLONG(0));
10477dd7cddfSDavid du Colombier 	    else
10487dd7cddfSDavid du Colombier 		WinSendMsg(hwndScroll, SBM_SETTHUMBSIZE, MPFROM2SHORT(1, 1),
10497dd7cddfSDavid du Colombier 			   MPFROMLONG(0));
10507dd7cddfSDavid du Colombier 
10517dd7cddfSDavid du Colombier 	    if ((cxAdjust != 0 || cyAdjust != 0)) {
10527dd7cddfSDavid du Colombier 		SWP swp;
10537dd7cddfSDavid du Colombier 
10547dd7cddfSDavid du Colombier 		WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
10557dd7cddfSDavid du Colombier 		WinSetWindowPos(WinQueryWindow(hwnd, QW_PARENT), 0,
10567dd7cddfSDavid du Colombier 				swp.x, swp.y - cyAdjust,
10577dd7cddfSDavid du Colombier 		 swp.cx + cxAdjust, swp.cy + cyAdjust, SWP_SIZE | SWP_MOVE);
10587dd7cddfSDavid du Colombier 		cxAdjust = cyAdjust = 0;
10597dd7cddfSDavid du Colombier 	    }
10607dd7cddfSDavid du Colombier 	    if (hwnd_frame) {	/* save window size for INI file */
10617dd7cddfSDavid du Colombier 		SWP swp;
10627dd7cddfSDavid du Colombier 
10637dd7cddfSDavid du Colombier 		WinQueryWindowPos(WinQueryWindow(hwnd, QW_PARENT), &swp);
10647dd7cddfSDavid du Colombier 		if (!(swp.fl & SWP_MINIMIZE)) {
10657dd7cddfSDavid du Colombier 		    option.img_size.x = swp.cx;
10667dd7cddfSDavid du Colombier 		    option.img_size.y = swp.cy;
10677dd7cddfSDavid du Colombier 		    option.img_max = ((swp.fl & SWP_MAXIMIZE) != 0);
10687dd7cddfSDavid du Colombier 		}
10697dd7cddfSDavid du Colombier 	    }
10707dd7cddfSDavid du Colombier 	    break;
10717dd7cddfSDavid du Colombier 	case WM_VSCROLL:
10727dd7cddfSDavid du Colombier 	    switch (SHORT2FROMMP(mp2)) {
10737dd7cddfSDavid du Colombier 		case SB_LINEUP:
10747dd7cddfSDavid du Colombier 		    nVscrollInc = -cyClient / 16;
10757dd7cddfSDavid du Colombier 		    break;
10767dd7cddfSDavid du Colombier 		case SB_LINEDOWN:
10777dd7cddfSDavid du Colombier 		    nVscrollInc = cyClient / 16;
10787dd7cddfSDavid du Colombier 		    break;
10797dd7cddfSDavid du Colombier 		case SB_PAGEUP:
10807dd7cddfSDavid du Colombier 		    nVscrollInc = min(-1, -cyClient);
10817dd7cddfSDavid du Colombier 		    break;
10827dd7cddfSDavid du Colombier 		case SB_PAGEDOWN:
10837dd7cddfSDavid du Colombier 		    nVscrollInc = max(1, cyClient);
10847dd7cddfSDavid du Colombier 		    break;
10857dd7cddfSDavid du Colombier 		case SB_SLIDERPOSITION:
10867dd7cddfSDavid du Colombier 		    nVscrollInc = SHORT1FROMMP(mp2) - nVscrollPos;
10877dd7cddfSDavid du Colombier 		    break;
10887dd7cddfSDavid du Colombier 		case SB_TOP:
10897dd7cddfSDavid du Colombier 		    nVscrollInc = -nVscrollPos;
10907dd7cddfSDavid du Colombier 		    break;
10917dd7cddfSDavid du Colombier 		case SB_BOTTOM:
10927dd7cddfSDavid du Colombier 		    nVscrollInc = nVscrollMax - nVscrollPos;
10937dd7cddfSDavid du Colombier 		    break;
10947dd7cddfSDavid du Colombier 		default:
10957dd7cddfSDavid du Colombier 		    nVscrollInc = 0;
10967dd7cddfSDavid du Colombier 	    }
10977dd7cddfSDavid du Colombier 	    if ((nVscrollInc = max(-nVscrollPos,
10987dd7cddfSDavid du Colombier 		       min(nVscrollInc, nVscrollMax - nVscrollPos))) != 0) {
10997dd7cddfSDavid du Colombier 		LONG lComplexity;
11007dd7cddfSDavid du Colombier 
11017dd7cddfSDavid du Colombier 		hwndScroll = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), FID_VERTSCROLL);
11027dd7cddfSDavid du Colombier 		nVscrollPos += nVscrollInc;
11037dd7cddfSDavid du Colombier 		scroll_pos.y = nVscrollMax - nVscrollPos;
11047dd7cddfSDavid du Colombier 		lComplexity = WinScrollWindow(hwnd, 0, nVscrollInc, (PRECTL) NULL, (PRECTL) NULL,
11057dd7cddfSDavid du Colombier 				     (HRGN) NULLHANDLE, (PRECTL) & rect, 0);
11067dd7cddfSDavid du Colombier 		WinSendMsg(hwndScroll, SBM_SETPOS, MPFROMLONG(nVscrollPos), 0);
11077dd7cddfSDavid du Colombier 		if (lComplexity != RGN_RECT) {
11087dd7cddfSDavid du Colombier 		    WinInvalidateRect(hwnd, (PRECTL) NULL, FALSE);
11097dd7cddfSDavid du Colombier 		    WinUpdateWindow(hwnd);
11107dd7cddfSDavid du Colombier 		} else {
11117dd7cddfSDavid du Colombier 		    /* redraw exposed area */
11127dd7cddfSDavid du Colombier 		    hps = WinGetPS(hwnd);
11137dd7cddfSDavid du Colombier 		    if (hps == NULLHANDLE)
11147dd7cddfSDavid du Colombier 			debugbeep(1);
11157dd7cddfSDavid du Colombier 		    if ((bitmap.depth == 8) && display.hasPalMan && display.hpal_exists) {
11167dd7cddfSDavid du Colombier 			GpiSelectPalette(hps, display.hpal);
11177dd7cddfSDavid du Colombier 			WinRealizePalette(hwnd, hps, &ulclr);
11187dd7cddfSDavid du Colombier 			paint_bitmap(hps, &rect, nHscrollPos, nVscrollMax - nVscrollPos);
11197dd7cddfSDavid du Colombier 			GpiSelectPalette(hps, (HPAL) NULL);
11207dd7cddfSDavid du Colombier 		    } else
11217dd7cddfSDavid du Colombier 			paint_bitmap(hps, &rect, nHscrollPos, nVscrollMax - nVscrollPos);
11227dd7cddfSDavid du Colombier 		    WinReleasePS(hps);
11237dd7cddfSDavid du Colombier 		}
11247dd7cddfSDavid du Colombier 	    }
11257dd7cddfSDavid du Colombier 	    break;
11267dd7cddfSDavid du Colombier 	case WM_HSCROLL:
11277dd7cddfSDavid du Colombier 	    switch (SHORT2FROMMP(mp2)) {
11287dd7cddfSDavid du Colombier 		case SB_LINELEFT:
11297dd7cddfSDavid du Colombier 		    nHscrollInc = -cxClient / 16;
11307dd7cddfSDavid du Colombier 		    break;
11317dd7cddfSDavid du Colombier 		case SB_LINERIGHT:
11327dd7cddfSDavid du Colombier 		    nHscrollInc = cyClient / 16;
11337dd7cddfSDavid du Colombier 		    break;
11347dd7cddfSDavid du Colombier 		case SB_PAGELEFT:
11357dd7cddfSDavid du Colombier 		    nHscrollInc = min(-1, -cxClient);
11367dd7cddfSDavid du Colombier 		    break;
11377dd7cddfSDavid du Colombier 		case SB_PAGERIGHT:
11387dd7cddfSDavid du Colombier 		    nHscrollInc = max(1, cxClient);
11397dd7cddfSDavid du Colombier 		    break;
11407dd7cddfSDavid du Colombier 		case SB_SLIDERPOSITION:
11417dd7cddfSDavid du Colombier 		    nHscrollInc = SHORT1FROMMP(mp2) - nHscrollPos;
11427dd7cddfSDavid du Colombier 		    break;
11437dd7cddfSDavid du Colombier 		default:
11447dd7cddfSDavid du Colombier 		    nHscrollInc = 0;
11457dd7cddfSDavid du Colombier 	    }
11467dd7cddfSDavid du Colombier 	    if ((nHscrollInc = max(-nHscrollPos,
11477dd7cddfSDavid du Colombier 		       min(nHscrollInc, nHscrollMax - nHscrollPos))) != 0) {
11487dd7cddfSDavid du Colombier 		LONG lComplexity;
11497dd7cddfSDavid du Colombier 
11507dd7cddfSDavid du Colombier 		hwndScroll = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), FID_HORZSCROLL);
11517dd7cddfSDavid du Colombier 		nHscrollPos += nHscrollInc;
11527dd7cddfSDavid du Colombier 		scroll_pos.x = nHscrollPos;
11537dd7cddfSDavid du Colombier 		lComplexity = WinScrollWindow(hwnd, -nHscrollInc, 0, (PRECTL) NULL, (PRECTL) NULL,
11547dd7cddfSDavid du Colombier 				     (HRGN) NULLHANDLE, (PRECTL) & rect, 0);
11557dd7cddfSDavid du Colombier 		/* need to send next message BEFORE redrawing, otherwise S3 driver screws up */
11567dd7cddfSDavid du Colombier 		WinSendMsg(hwndScroll, SBM_SETPOS, MPFROMLONG(nHscrollPos), 0);
11577dd7cddfSDavid du Colombier 		if (lComplexity != RGN_RECT) {
11587dd7cddfSDavid du Colombier 		    WinInvalidateRect(hwnd, (PRECTL) NULL, FALSE);
11597dd7cddfSDavid du Colombier 		    WinUpdateWindow(hwnd);
11607dd7cddfSDavid du Colombier 		} else {
11617dd7cddfSDavid du Colombier 		    /* redraw exposed area */
11627dd7cddfSDavid du Colombier 		    hps = WinGetPS(hwnd);
11637dd7cddfSDavid du Colombier 		    if (hps == NULLHANDLE)
11647dd7cddfSDavid du Colombier 			debugbeep(1);
11657dd7cddfSDavid du Colombier 		    if ((bitmap.depth == 8) && display.hasPalMan && display.hpal_exists) {
11667dd7cddfSDavid du Colombier 			GpiSelectPalette(hps, display.hpal);
11677dd7cddfSDavid du Colombier 			WinRealizePalette(hwnd, hps, &ulclr);
11687dd7cddfSDavid du Colombier 			paint_bitmap(hps, &rect, nHscrollPos, nVscrollMax - nVscrollPos);
11697dd7cddfSDavid du Colombier 			GpiSelectPalette(hps, (HPAL) NULL);
11707dd7cddfSDavid du Colombier 		    } else
11717dd7cddfSDavid du Colombier 			paint_bitmap(hps, &rect, nHscrollPos, nVscrollMax - nVscrollPos);
11727dd7cddfSDavid du Colombier 		    WinReleasePS(hps);
11737dd7cddfSDavid du Colombier 		}
11747dd7cddfSDavid du Colombier 	    }
11757dd7cddfSDavid du Colombier 	    break;
11767dd7cddfSDavid du Colombier 	case WM_CHAR:		/* process keystrokes here */
11777dd7cddfSDavid du Colombier 	    if (SHORT1FROMMP(mp1) & KC_CHAR) {
11787dd7cddfSDavid du Colombier 		/* pass control to gs if ENTER pressed */
11797dd7cddfSDavid du Colombier 		if (hwnd_gs && (SHORT1FROMMP(mp2) == '\r'))
11807dd7cddfSDavid du Colombier 		    WinSetActiveWindow(HWND_DESKTOP, hwnd_gs);
11817dd7cddfSDavid du Colombier 	    }
11827dd7cddfSDavid du Colombier 	    /* Process only key presses, not key releases */
11837dd7cddfSDavid du Colombier 	    if (SHORT1FROMMP(mp1) & KC_KEYUP)
11847dd7cddfSDavid du Colombier 		break;
11857dd7cddfSDavid du Colombier 	    if (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) {
11867dd7cddfSDavid du Colombier 		USHORT vkey = SHORT2FROMMP(mp2);
11877dd7cddfSDavid du Colombier 
11887dd7cddfSDavid du Colombier 		switch (vkey) {
11897dd7cddfSDavid du Colombier 		    case VK_HOME:
11907dd7cddfSDavid du Colombier 			WinSendMsg(hwnd, WM_VSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_TOP));
11917dd7cddfSDavid du Colombier 			break;
11927dd7cddfSDavid du Colombier 		    case VK_END:
11937dd7cddfSDavid du Colombier 			WinSendMsg(hwnd, WM_VSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_BOTTOM));
11947dd7cddfSDavid du Colombier 			break;
11957dd7cddfSDavid du Colombier 		    case VK_UP:
11967dd7cddfSDavid du Colombier 			WinSendMsg(hwnd, WM_VSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_LINEUP));
11977dd7cddfSDavid du Colombier 			break;
11987dd7cddfSDavid du Colombier 		    case VK_DOWN:
11997dd7cddfSDavid du Colombier 			WinSendMsg(hwnd, WM_VSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_LINEDOWN));
12007dd7cddfSDavid du Colombier 			break;
12017dd7cddfSDavid du Colombier 		    case VK_PAGEUP:
12027dd7cddfSDavid du Colombier 			WinSendMsg(hwnd, WM_VSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_PAGEUP));
12037dd7cddfSDavid du Colombier 			break;
12047dd7cddfSDavid du Colombier 		    case VK_PAGEDOWN:
12057dd7cddfSDavid du Colombier 			WinSendMsg(hwnd, WM_VSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_PAGEDOWN));
12067dd7cddfSDavid du Colombier 			break;
12077dd7cddfSDavid du Colombier 		    case VK_LEFT:
12087dd7cddfSDavid du Colombier 			if (SHORT1FROMMP(mp1) & KC_CTRL)
12097dd7cddfSDavid du Colombier 			    WinSendMsg(hwnd, WM_HSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_PAGELEFT));
12107dd7cddfSDavid du Colombier 			else
12117dd7cddfSDavid du Colombier 			    WinSendMsg(hwnd, WM_HSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_LINELEFT));
12127dd7cddfSDavid du Colombier 			break;
12137dd7cddfSDavid du Colombier 		    case VK_RIGHT:
12147dd7cddfSDavid du Colombier 			if (SHORT1FROMMP(mp1) & KC_CTRL)
12157dd7cddfSDavid du Colombier 			    WinSendMsg(hwnd, WM_HSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_PAGERIGHT));
12167dd7cddfSDavid du Colombier 			else
12177dd7cddfSDavid du Colombier 			    WinSendMsg(hwnd, WM_HSCROLL, MPFROMLONG(0), MPFROM2SHORT(0, SB_LINERIGHT));
12187dd7cddfSDavid du Colombier 			break;
12197dd7cddfSDavid du Colombier 		}
12207dd7cddfSDavid du Colombier 	    }
12217dd7cddfSDavid du Colombier 	    break;
12227dd7cddfSDavid du Colombier 	default:
12237dd7cddfSDavid du Colombier 	    /* All messages not handled by the ClientWndProc must be passed
12247dd7cddfSDavid du Colombier 	     * along to the Presentation Manager for default processing
12257dd7cddfSDavid du Colombier 	     */
12267dd7cddfSDavid du Colombier 	    return WinDefWindowProc(hwnd, mess, mp1, mp2);
12277dd7cddfSDavid du Colombier     }
12287dd7cddfSDavid du Colombier     return (MRESULT) FALSE;
12297dd7cddfSDavid du Colombier }
12307dd7cddfSDavid du Colombier 
12317dd7cddfSDavid du Colombier 
12327dd7cddfSDavid du Colombier 
12337dd7cddfSDavid du Colombier /* About Dialog Box */
12347dd7cddfSDavid du Colombier MRESULT EXPENTRY
AboutDlgProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)12357dd7cddfSDavid du Colombier AboutDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
12367dd7cddfSDavid du Colombier {
12377dd7cddfSDavid du Colombier     switch (msg) {
12387dd7cddfSDavid du Colombier 	case WM_COMMAND:
12397dd7cddfSDavid du Colombier 	    switch (COMMANDMSG(&msg)->cmd) {
12407dd7cddfSDavid du Colombier 		case DID_OK:
12417dd7cddfSDavid du Colombier 		    WinDismissDlg(hwnd, TRUE);
12427dd7cddfSDavid du Colombier 		    return (MRESULT) TRUE;
12437dd7cddfSDavid du Colombier 	    }
12447dd7cddfSDavid du Colombier 	    break;
12457dd7cddfSDavid du Colombier     }
12467dd7cddfSDavid du Colombier     return WinDefDlgProc(hwnd, msg, mp1, mp2);
12477dd7cddfSDavid du Colombier }
1248