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