comparison os2/dw.c @ 1696:c01961b48c40

Added initial support on OS/2 for runtime loading GBM (Generalized Bitmap Module) which allows JPG/PNG/etc bitmap support.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 02 May 2012 22:28:20 +0000
parents b2311922a4de
children f5b187156cc0
comparison
equal deleted inserted replaced
1695:90d02916b878 1696:c01961b48c40
35 #include <sys/time.h> 35 #include <sys/time.h>
36 #include <sys/stat.h> 36 #include <sys/stat.h>
37 #ifdef __WATCOMC__ 37 #ifdef __WATCOMC__
38 #include <alloca.h> 38 #include <alloca.h>
39 #endif 39 #endif
40 #include <fcntl.h>
40 #include "dw.h" 41 #include "dw.h"
41 42
42 #define QWP_USER 0 43 #define QWP_USER 0
43 44
44 /* The toolkit headers don't seem to have this */ 45 /* The toolkit headers don't seem to have this */
59 MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2); 60 MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
60 void _do_resize(Box *thisbox, int x, int y); 61 void _do_resize(Box *thisbox, int x, int y);
61 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y); 62 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
62 int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height); 63 int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height);
63 void _free_menu_data(HWND menu); 64 void _free_menu_data(HWND menu);
65 BOOL (API_FUNC _WinQueryDesktopWorkArea)(HWND hwndDesktop, PWRECT pwrcWorkArea) = 0;
66 /* PMPrintf support for dw_debug() */
64 ULONG (API_FUNC _PmPrintfString)(char *String) = 0; 67 ULONG (API_FUNC _PmPrintfString)(char *String) = 0;
65 BOOL (API_FUNC _WinQueryDesktopWorkArea)(HWND hwndDesktop, PWRECT pwrcWorkArea) = 0; 68 /* GBM (Generalize Bitmap Module) support for file loading */
69 #pragma pack(4)
70 typedef struct
71 {
72 int w, h, bpp;
73 unsigned char priv[2000];
74 } GBM;
75 typedef struct { unsigned char r, g, b; } GBMRGB;
76 #pragma pack()
77 int (API_FUNC _gbm_init)(void) = 0;
78 int (API_FUNC _gbm_deinit)(void) = 0;
79 int (API_FUNC _gbm_guess_filetype)(const char *fn, int *type) = 0;
80 int (API_FUNC _gbm_io_open)(const char *fn, int mode) = 0;
81 int (API_FUNC _gbm_io_close)(int fd) = 0;
82 int (API_FUNC _gbm_read_header)(const char *fn, int fd, int ft, GBM *gbm, const char *info) = 0;
83 int (API_FUNC _gbm_read_palette)(int fd, int ft, GBM *gbm, GBMRGB *gbmrgb) = 0;
84 int (API_FUNC _gbm_read_data)(int fd, int ft, GBM *gbm, unsigned char *data) = 0;
66 85
67 char ClassName[] = "dynamicwindows"; 86 char ClassName[] = "dynamicwindows";
68 char SplitbarClassName[] = "dwsplitbar"; 87 char SplitbarClassName[] = "dwsplitbar";
69 char ScrollClassName[] = "dwscroll"; 88 char ScrollClassName[] = "dwscroll";
70 char CalendarClassName[] = "dwcalendar"; 89 char CalendarClassName[] = "dwcalendar";
79 HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE; 98 HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE;
80 99
81 PRECORDCORE pCoreEmph = NULL; 100 PRECORDCORE pCoreEmph = NULL;
82 ULONG aulBuffer[4]; 101 ULONG aulBuffer[4];
83 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop; 102 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
84 HMOD wpconfig = 0, pmprintf = 0, pmmerge = 0; 103 HMOD wpconfig = 0, pmprintf = 0, pmmerge = 0, gbm = 0;
85 static char _dw_exec_dir[MAX_PATH+1] = {0}; 104 static char _dw_exec_dir[MAX_PATH+1] = {0};
86 105
87 unsigned long _colors[] = { 106 unsigned long _colors[] = {
88 CLR_BLACK, 107 CLR_BLACK,
89 CLR_DARKRED, 108 CLR_DARKRED,
4106 DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"WPCONFIG", &wpconfig); 4125 DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"WPCONFIG", &wpconfig);
4107 if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMPRINTF", &pmprintf)) 4126 if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMPRINTF", &pmprintf))
4108 DosQueryProcAddr(pmprintf, 0, (PSZ)"PmPrintfString", (PFN*)&_PmPrintfString); 4127 DosQueryProcAddr(pmprintf, 0, (PSZ)"PmPrintfString", (PFN*)&_PmPrintfString);
4109 if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMMERGE", &pmmerge)) 4128 if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMMERGE", &pmmerge))
4110 DosQueryProcAddr(pmmerge, 5469, NULL, (PFN*)&_WinQueryDesktopWorkArea); 4129 DosQueryProcAddr(pmmerge, 5469, NULL, (PFN*)&_WinQueryDesktopWorkArea);
4130 if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"GBM", &gbm))
4131 {
4132 /* Load the _System versions of the functions from the library */
4133 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_init", (PFN*)&_gbm_init);
4134 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_deinit", (PFN*)&_gbm_deinit);
4135 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_io_open", (PFN*)&_gbm_io_open);
4136 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_io_close", (PFN*)&_gbm_io_close);
4137 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_read_data", (PFN*)&_gbm_read_data);
4138 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_read_header", (PFN*)&_gbm_read_header);
4139 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_read_palette", (PFN*)&_gbm_read_palette);
4140 DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_guess_filetype", (PFN*)&_gbm_guess_filetype);
4141 /* If we got the functions, try to initialize the library */
4142 if(!_gbm_init || _gbm_init())
4143 {
4144 /* Otherwise clear out the function pointers */
4145 _gbm_init=0;_gbm_deinit=0;_gbm_io_open=0;_gbm_io_close=0;_gbm_guess_filetype=0;
4146 _gbm_read_header=0;_gbm_read_palette=0;_gbm_read_data=0;
4147 }
4148 }
4111 return rc; 4149 return rc;
4112 } 4150 }
4113 4151
4114 static int _dw_main_running = FALSE; 4152 static int _dw_main_running = FALSE;
4115 4153
6685 /* Internal function to load a bitmap from a file and return handles 6723 /* Internal function to load a bitmap from a file and return handles
6686 * to the bitmap, presentation space etc. 6724 * to the bitmap, presentation space etc.
6687 */ 6725 */
6688 int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height) 6726 int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height)
6689 { 6727 {
6690 HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */ 6728 PBITMAPINFOHEADER2 pBitmapInfoHeader;
6691 ULONG OpenAction = 0; 6729 /* pointer to the first byte of bitmap data */
6692 PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data */ 6730 PBYTE BitmapFileBegin, BitmapBits;
6693 FILESTATUS BitmapStatus; 6731 ULONG ulFlags;
6694 ULONG cbRead; 6732 SIZEL sizl = { 0 };
6695 PBITMAPFILEHEADER2 pBitmapFileHeader; 6733 HPS hps1;
6696 PBITMAPINFOHEADER2 pBitmapInfoHeader; 6734 HDC hdc1;
6697 ULONG ScanLines, ulFlags; 6735
6698 HPS hps1; 6736 /* If we have GBM support open the file using GBM */
6699 HDC hdc1; 6737 if(_gbm_init)
6700 SIZEL sizl = { 0, 0 }; 6738 {
6701 6739 int fd, ft = 0;
6702 /* open bitmap file */ 6740 GBM gbm;
6703 DosOpen((PSZ)file, &BitmapFileHandle, &OpenAction, 0L, 6741 GBMRGB *gbmrgb;
6704 FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY, 6742 ULONG byteswidth;
6705 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, 6743
6706 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY | 6744 /* Try to open the file */
6707 OPEN_FLAGS_NOINHERIT, 0L); 6745 if((fd = _gbm_io_open(file, O_RDONLY|O_BINARY)) == -1)
6708 6746 return 0;
6709 if(!BitmapFileHandle) 6747
6710 return 0; 6748 /* guess the source file type from the source filename */
6711 6749 _gbm_guess_filetype(file, &ft);
6712 /* find out how big the file is */ 6750
6713 DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus, 6751 /* Read the file header */
6714 sizeof(BitmapStatus)); 6752 if(_gbm_read_header(file, fd, ft, &gbm, ""))
6715 6753 {
6716 /* allocate memory to load the bitmap */ 6754 _gbm_io_close(fd);
6717 DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile, 6755 return 0;
6718 PAG_READ | PAG_WRITE | PAG_COMMIT); 6756 }
6719 6757
6720 /* read bitmap file into memory buffer */ 6758 /* if less than 24-bit, then have palette */
6721 DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin, 6759 if(gbm.bpp < 24)
6722 BitmapStatus.cbFile, &cbRead); 6760 {
6723 6761 gbmrgb = alloca(sizeof(GBMRGB));
6724 /* access first bytes as bitmap header */ 6762 /* Read the palette from the file */
6725 pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin; 6763 if(_gbm_read_palette(fd, ft, &gbm, gbmrgb))
6726 6764 {
6727 /* check if it's a valid bitmap data file */ 6765 _gbm_io_close(fd);
6728 if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) && 6766 return 0;
6729 (pBitmapFileHeader->usType != BFT_BMAP)) 6767 }
6730 { 6768 }
6731 /* free memory of bitmap file buffer */ 6769 else
6732 DosFreeMem(BitmapFileBegin); 6770 gbmrgb = NULL;
6733 /* close the bitmap file */ 6771
6734 DosClose(BitmapFileHandle); 6772 /* Save the dimension for return */
6735 return 0; 6773 *width = gbm.w;
6736 } 6774 *height = gbm.h;
6737 6775 byteswidth = (((gbm.w*gbm.bpp + 31)/32)*4);
6738 /* check if it's a file with multiple bitmaps */ 6776 /* Allocate a buffer to store the image */
6739 if(pBitmapFileHeader->usType == BFT_BITMAPARRAY) 6777 DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)byteswidth * gbm.h,
6740 { 6778 PAG_READ | PAG_WRITE | PAG_COMMIT);
6741 /* we'll just use the first bitmap and ignore the others */ 6779
6742 pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2); 6780 /* Read the data into our buffer */
6743 } 6781 if(_gbm_read_data(fd, ft, &gbm, BitmapFileBegin))
6744 6782 {
6745 /* set pointer to bitmap information block */ 6783 _gbm_io_close(fd);
6746 pBitmapInfoHeader = &pBitmapFileHeader->bmp2; 6784 return 0;
6747 6785 }
6748 /* find out if it's the new 2.0 format or the old format */ 6786
6749 /* and query number of lines */ 6787 /* Close the file */
6750 if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER)) 6788 _gbm_io_close(fd);
6751 { 6789
6752 *height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy; 6790 pBitmapInfoHeader = alloca(sizeof(BITMAPINFOHEADER2));
6753 *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx; 6791 memset(pBitmapInfoHeader, 0, sizeof(BITMAPINFOHEADER2));
6754 } 6792 pBitmapInfoHeader->cbFix = sizeof(BITMAPINFOHEADER2);
6755 else 6793 pBitmapInfoHeader->cx = (SHORT)gbm.w;
6756 { 6794 pBitmapInfoHeader->cy = (SHORT)gbm.h;
6757 *height = ScanLines = pBitmapInfoHeader->cy; 6795 pBitmapInfoHeader->cPlanes = (SHORT)1;
6758 *width = pBitmapInfoHeader->cx; 6796 pBitmapInfoHeader->cBitCount = (SHORT)gbm.bpp;
6759 } 6797
6760 6798 /* Put the bitmap bits into the destination */
6761 /* now we need a presentation space, get it from static control */ 6799 BitmapBits = BitmapFileBegin;
6762 hps1 = WinGetPS(handle); 6800 }
6763 6801 else
6764 hdc1 = GpiQueryDevice(hps1); 6802 {
6765 ulFlags = GpiQueryPS(hps1, &sizl); 6803 HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
6766 6804 ULONG OpenAction = 0;
6767 *hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc1); 6805 FILESTATUS BitmapStatus;
6768 *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC); 6806 ULONG cbRead;
6769 6807 PBITMAPFILEHEADER2 pBitmapFileHeader;
6770 /* create bitmap now using the parameters from the info block */ 6808
6771 *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL); 6809 /* open bitmap file */
6772 6810 DosOpen((PSZ)file, &BitmapFileHandle, &OpenAction, 0L,
6773 /* select the new bitmap into presentation space */ 6811 FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
6774 GpiSetBitmap(*hps, *hbm); 6812 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
6775 6813 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
6776 /* now copy the bitmap data into the bitmap */ 6814 OPEN_FLAGS_NOINHERIT, 0L);
6777 GpiSetBitmapBits(*hps, 0L, ScanLines, 6815
6778 BitmapFileBegin + pBitmapFileHeader->offBits, 6816 if(!BitmapFileHandle)
6779 (PBITMAPINFO2)pBitmapInfoHeader); 6817 return 0;
6780 6818
6781 WinReleasePS(hps1); 6819 /* find out how big the file is */
6782 6820 DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
6783 /* free memory of bitmap file buffer */ 6821 sizeof(BitmapStatus));
6784 DosFreeMem(BitmapFileBegin); 6822
6785 /* close the bitmap file */ 6823 /* allocate memory to load the bitmap */
6786 DosClose(BitmapFileHandle); 6824 DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
6787 return 1; 6825 PAG_READ | PAG_WRITE | PAG_COMMIT);
6826
6827 /* read bitmap file into memory buffer */
6828 DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
6829 BitmapStatus.cbFile, &cbRead);
6830
6831 /* access first bytes as bitmap header */
6832 pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
6833
6834 /* check if it's a valid bitmap data file */
6835 if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
6836 (pBitmapFileHeader->usType != BFT_BMAP))
6837 {
6838 /* free memory of bitmap file buffer */
6839 DosFreeMem(BitmapFileBegin);
6840 /* close the bitmap file */
6841 DosClose(BitmapFileHandle);
6842 return 0;
6843 }
6844
6845 /* check if it's a file with multiple bitmaps */
6846 if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
6847 {
6848 /* we'll just use the first bitmap and ignore the others */
6849 pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
6850 }
6851
6852 /* set pointer to bitmap information block */
6853 pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
6854
6855 /* find out if it's the new 2.0 format or the old format */
6856 /* and query number of lines */
6857 if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
6858 {
6859 *height = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
6860 *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
6861 }
6862 else
6863 {
6864 *height = pBitmapInfoHeader->cy;
6865 *width = pBitmapInfoHeader->cx;
6866 }
6867
6868 /* Put the bitmap bits into the destination */
6869 BitmapBits = BitmapFileBegin + pBitmapFileHeader->offBits;
6870
6871 /* close the bitmap file */
6872 DosClose(BitmapFileHandle);
6873 }
6874
6875 /* now we need a presentation space, get it from static control */
6876 hps1 = WinGetPS(handle);
6877
6878 hdc1 = GpiQueryDevice(hps1);
6879 ulFlags = GpiQueryPS(hps1, &sizl);
6880
6881 *hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc1);
6882 *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
6883
6884 /* create bitmap now using the parameters from the info block */
6885 *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
6886
6887 /* select the new bitmap into presentation space */
6888 GpiSetBitmap(*hps, *hbm);
6889
6890 /* now copy the bitmap data into the bitmap */
6891 GpiSetBitmapBits(*hps, 0L, *height,
6892 BitmapBits,
6893 (PBITMAPINFO2)pBitmapInfoHeader);
6894
6895 WinReleasePS(hps1);
6896
6897 /* free memory of bitmap file buffer */
6898 if(BitmapFileBegin)
6899 DosFreeMem(BitmapFileBegin);
6900 return 1;
6788 } 6901 }
6789 6902
6790 /* 6903 /*
6791 * Sets the bitmap used for a given static window. 6904 * Sets the bitmap used for a given static window.
6792 * Parameters: 6905 * Parameters:
10199 SIZEL sizl = { 0, 0 }; 10312 SIZEL sizl = { 0, 0 };
10200 HPIXMAP pixmap; 10313 HPIXMAP pixmap;
10201 HDC hdc; 10314 HDC hdc;
10202 HPS hps; 10315 HPS hps;
10203 ULONG ulFlags; 10316 ULONG ulFlags;
10204 LONG cPlanes, cBitCount; 10317 LONG cPlanes, cBitCount;
10205 10318
10206 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) 10319 if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
10207 return NULL; 10320 return NULL;
10208 10321
10209 hps = WinGetPS(handle); 10322 hps = WinGetPS(handle);
11017 * try to free memory that could possibly be 11130 * try to free memory that could possibly be
11018 * free()'d by the runtime already. 11131 * free()'d by the runtime already.
11019 */ 11132 */
11020 Root = NULL; 11133 Root = NULL;
11021 11134
11135 /* Deinit the GBM */
11136 if(_gbm_deinit)
11137 _gbm_deinit();
11138
11022 /* Destroy the main message queue and anchor block */ 11139 /* Destroy the main message queue and anchor block */
11023 WinDestroyMsgQueue(dwhmq); 11140 WinDestroyMsgQueue(dwhmq);
11024 WinTerminate(dwhab); 11141 WinTerminate(dwhab);
11025 11142
11026 /* Free any in use modules */ 11143 /* Free any in use modules */
11027 DosFreeModule(wpconfig); 11144 DosFreeModule(wpconfig);
11028 DosFreeModule(pmprintf); 11145 DosFreeModule(pmprintf);
11029 DosFreeModule(pmmerge); 11146 DosFreeModule(pmmerge);
11147 DosFreeModule(gbm);
11030 11148
11031 /* And finally exit */ 11149 /* And finally exit */
11032 exit(exitcode); 11150 exit(exitcode);
11033 } 11151 }
11034 11152