Mercurial > dwindows
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 |