Changeset 190
- Timestamp:
- Jul 22, 2002, 10:08:02 PM (23 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/helpers/dosh.h
r161 r190 606 606 607 607 APIRET doshClose(PXFILE *ppFile); 608 609 APIRET doshReadText(PXFILE pFile, 610 PSZ* ppszContent, 611 PULONG pcbRead); 608 612 609 613 APIRET doshLoadTextFile(PCSZ pcszFile, -
trunk/include/helpers/gpih.h
r178 r190 322 322 typedef GPIHCREATEHALFTONEDBITMAP *PGPIHCREATEHALFTONEDBITMAP; 323 323 324 APIRET gpihLoadBitmap(HBITMAP *phbm, 325 HPS hps, 326 HMODULE hmodResource, 327 ULONG idBitmap); 328 324 329 APIRET XWPENTRY gpihLoadBitmapFile(HBITMAP *phbm, HPS hps, PCSZ pcszBmpFile); 325 330 typedef APIRET XWPENTRY GPIHLOADBITMAPFILE(HBITMAP *phbm, HPS hps, PCSZ pcszBmpFile); -
trunk/include/helpers/tmsgfile.h
r150 r190 32 32 /* 33 33 *@@ TMFMSGFILE: 34 * representation of a text message file opened by 35 * tmfOpenMessageFile. 34 36 * 35 37 *@@added V0.9.16 (2001-10-08) [umoeller] … … 39 41 { 40 42 PSZ pszFilename; // copy of .TMF file name 41 42 XSTRING strContent; // file's full contents (converted to C LF format)43 43 44 44 TREE *IDsTreeRoot; // root of tree with MSGENTRY's (a TREE* really) … … 59 59 ULONG cTableEntries); 60 60 61 /* APIRET tmfGetMessage(PCHAR *pTable,62 ULONG cTable,63 PBYTE pbBuffer,64 ULONG cbBuffer,65 PCSZ pszMessageName,66 PCSZ pszFile,67 PULONG pcbMsg);68 69 APIRET tmfGetMessageExt(PCHAR* pTable,70 ULONG cTable,71 PBYTE pbBuffer,72 ULONG cbBuffer,73 PCSZ pszMessageName,74 PCSZ pszFile,75 PULONG pcbMsg);76 */77 78 61 #endif // TMSGFILE_HEADER_INCLUDED 79 62 -
trunk/src/helpers/dosh.c
r169 r190 2854 2854 2855 2855 /* 2856 *@@ doshReadText: 2857 * reads all the contents of the given XFILE into 2858 * a newly allocated buffer. Handles Ctrl-Z properly. 2859 * 2860 * Implementation for doshLoadTextFile, but can 2861 * be called separately now. 2862 * 2863 *@@added V0.9.20 (2002-07-19) [umoeller] 2864 */ 2865 2866 APIRET doshReadText(PXFILE pFile, 2867 PSZ* ppszContent, // out: newly allocated buffer with file's content 2868 PULONG pcbRead) // out: size of that buffer including null byte (ptr can be NULL) 2869 { 2870 APIRET arc; 2871 PSZ pszContent; 2872 2873 if (!(pszContent = (PSZ)malloc(pFile->cbCurrent + 1))) 2874 arc = ERROR_NOT_ENOUGH_MEMORY; 2875 else 2876 { 2877 ULONG cbRead = 0; 2878 if (!(arc = DosRead(pFile->hf, 2879 pszContent, 2880 pFile->cbCurrent, 2881 &cbRead))) 2882 { 2883 if (cbRead != pFile->cbCurrent) 2884 arc = ERROR_NO_DATA; 2885 else 2886 { 2887 PSZ p; 2888 pszContent[cbRead] = '\0'; 2889 2890 // check if we have a ctrl-z (EOF) marker 2891 // this is present, for example, in config.sys 2892 // after install, and stupid E.EXE writes this 2893 // all the time when saving a file 2894 // V0.9.18 (2002-03-08) [umoeller] 2895 if (p = strchr(pszContent, '\26')) 2896 { 2897 *p = '\0'; 2898 cbRead = p - pszContent; 2899 } 2900 2901 *ppszContent = pszContent; 2902 if (pcbRead) 2903 *pcbRead = cbRead + 1; 2904 } 2905 } 2906 2907 if (arc) 2908 free(pszContent); 2909 } 2910 2911 return arc; 2912 } 2913 2914 /* 2856 2915 *@@ doshLoadTextFile: 2857 2916 * reads a text file from disk, allocates memory … … 2892 2951 &pFile))) 2893 2952 { 2894 PSZ pszContent; 2895 if (!(pszContent = (PSZ)malloc(cbFile + 1))) 2896 arc = ERROR_NOT_ENOUGH_MEMORY; 2897 else 2898 { 2899 ULONG cbRead = 0; 2900 if (!(arc = DosRead(pFile->hf, 2901 pszContent, 2902 cbFile, 2903 &cbRead))) 2904 { 2905 if (cbRead != cbFile) 2906 arc = ERROR_NO_DATA; 2907 else 2908 { 2909 PSZ p; 2910 pszContent[cbRead] = '\0'; 2911 2912 // check if we have a ctrl-z (EOF) marker 2913 // this is present, for example, in config.sys 2914 // after install 2915 // V0.9.18 (2002-03-08) [umoeller] 2916 if (p = strchr(pszContent, '\26')) 2917 { 2918 *p = '\0'; 2919 cbRead = p - pszContent; 2920 } 2921 2922 *ppszContent = pszContent; 2923 if (pcbRead) 2924 *pcbRead = cbRead + 1; 2925 } 2926 } 2927 2928 if (arc) 2929 free(pszContent); 2930 } 2931 2953 doshReadText(pFile, 2954 ppszContent, 2955 pcbRead); 2932 2956 doshClose(&pFile); 2933 2957 } -
trunk/src/helpers/gpih.c
r189 r190 34 34 35 35 #define INCL_DOSSEMAPHORES 36 #define INCL_DOSMODULEMGR 37 #define INCL_DOSRESOURCES 36 38 #define INCL_DOSERRORS 37 39 … … 140 142 } 141 143 142 return (FALSE);144 return FALSE; 143 145 } 144 146 … … 191 193 } 192 194 193 return (DisplayCaps[ulIndex]);195 return DisplayCaps[ulIndex]; 194 196 } 195 197 … … 300 302 BOOL gpihSwitchToRGB(HPS hps) 301 303 { 302 return (GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL));304 return GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL); 303 305 } 304 306 … … 567 569 } 568 570 569 return (lHits);571 return lHits; 570 572 } 571 573 … … 982 984 * 983 985 *@@added V0.9.1 (2000-02-15) [umoeller] 986 *@@changed V0.9.20 (2002-07-19) [umoeller]: optimized 984 987 */ 985 988 … … 990 993 // (e.g. "Courier") 991 994 { 992 BOOL brc = FALSE; 993 994 if (pszFontNameSize) 995 PCHAR pcDot; 996 if ( (pszFontNameSize) 997 && (pcDot = strchr(pszFontNameSize, '.')) 998 ) 995 999 { 996 PCHAR pcDot = strchr(pszFontNameSize, '.'); 997 if (pcDot) 998 { 999 // _Pmpf(("Found font PP: %s", pszFontFound)); 1000 sscanf(pszFontNameSize, "%lu", pulSize); 1001 *ppszFaceName = pcDot + 1; 1002 brc = TRUE; 1003 } 1000 // _Pmpf(("Found font PP: %s", pszFontFound)); 1001 // sscanf(pszFontNameSize, "%lu", pulSize); 1002 *pulSize = atoi(pszFontNameSize); // V0.9.20 (2002-07-19) [umoeller] 1003 *ppszFaceName = pcDot + 1; 1004 return TRUE; 1004 1005 } 1005 1006 1006 return brc;1007 return FALSE; 1007 1008 } 1008 1009 … … 1163 1164 // _Pmpf((__FUNCTION__ ": Returning lcid %d", lcidNext)); 1164 1165 1165 return (lcidNext);1166 return lcidNext; 1166 1167 } 1167 1168 … … 1190 1191 } 1191 1192 1192 return (lLCIDReturn);1193 return lLCIDReturn; 1193 1194 } 1194 1195 … … 1371 1372 pFontMetrics); 1372 1373 1373 return (gpihCreateFont(hps,1374 &FontAttrs));1374 return gpihCreateFont(hps, 1375 &FontAttrs); 1375 1376 1376 1377 // _Pmpf((__FUNCTION__ ": returning lcid %d", lLCIDReturn)); … … 1451 1452 *plSize = ulFontSize; 1452 1453 strcpy(szFaceName, pcDot + 1); 1453 return (gpihFindFont(hps,1454 1455 1456 1457 1458 pFontMetrics));1454 return gpihFindFont(hps, 1455 ulFontSize, 1456 FALSE, // face, not family name 1457 szFaceName, 1458 0, 1459 pFontMetrics); 1459 1460 } 1460 1461 } 1461 1462 1462 return (0);1463 return 0; 1463 1464 } 1464 1465 … … 1523 1524 box.cy = (FIXED)(lPointSize / 72 * alDevRes[1]); 1524 1525 1525 return (GpiSetCharBox(hps, &box));1526 return GpiSetCharBox(hps, &box); 1526 1527 } 1527 1528 … … 1547 1548 +fm.lExternalLeading) // space advised by font designer 1548 1549 ); 1549 else 1550 return (15);1550 1551 return 15; 1551 1552 } 1552 1553 … … 1640 1641 ULONG cy) // in: height of new bitmap 1641 1642 { 1642 return (gpihCreateBitmap2(hpsMem,1643 1644 1645 1646 0)); // current screen bit count1643 return gpihCreateBitmap2(hpsMem, 1644 cx, 1645 cy, 1646 0, 1647 0); // current screen bit count 1647 1648 } 1648 1649 … … 1715 1716 } 1716 1717 1717 return (hbm);1718 return hbm; 1718 1719 } 1719 1720 … … 1817 1818 } // end if (hbmSource) 1818 1819 1819 return (hbmReturn); 1820 return hbmReturn; 1821 } 1822 1823 /* 1824 typedef struct _BITMAPARRAYFILEHEADER { 1825 USHORT usType; // Type of structure. 1826 ULONG cbSize; // Size of the BITMAPARRAYFILEHEADER structure in bytes. 1827 ULONG offNext; // Offset of the next BITMAPARRAYFILEHEADER structure from the start of the file. 1828 USHORT cxDisplay; // Device width, in pels. 1829 USHORT cyDisplay; // Device height, in pels. 1830 BITMAPFILEHEADER bfh; // Bitmap file header structure. 1831 } BITMAPARRAYFILEHEADER; 1832 1833 typedef struct _BITMAPARRAYFILEHEADER2 { 1834 USHORT usType; // Type of structure. 1835 ULONG cbSize; // Size of the BITMAPARRAYFILEHEADER2 structure in bytes. 1836 ULONG offNext; // Offset of the next BITMAPARRAYFILEHEADER2 structure from the start of the file. 1837 USHORT cxDisplay; // Device width, in pels. 1838 USHORT cyDisplay; // Device height, in pels. 1839 BITMAPFILEHEADER2 bfh2; // Bitmap file header structure. 1840 } BITMAPARRAYFILEHEADER2; 1841 1842 These two are binarily the same, except for the file header that is contained. 1843 */ 1844 1845 /* OLD FORMAT 1846 1847 typedef struct _BITMAPFILEHEADER { 1848 USHORT usType; // Type of resource the file contains. 1849 ULONG cbSize; // Size of the BITMAPFILEHEADER structure in bytes. 1850 SHORT xHotspot; // Width of hotspot for icons and pointers. 1851 SHORT yHotspot; // Height of hotspot for icons and pointers. 1852 USHORT offBits; // Offset in bytes. 1853 BITMAPINFOHEADER bmp; // Bitmap information header structure. 1854 1855 typedef struct _BITMAPINFOHEADER { 1856 ULONG cbFix; // Length of structure. 1857 USHORT cx; // Bitmap width in pels. 1858 USHORT cy; // Bitmap height in pels. 1859 USHORT cPlanes; // Number of bit planes. 1860 USHORT cBitCount; // Number of bits per pel within a plane. 1861 } BITMAPINFOHEADER; 1862 1863 } BITMAPFILEHEADER; 1864 */ 1865 1866 /* NEW FORMAT 1867 1868 typedef struct _BITMAPFILEHEADER2 { 1869 USHORT usType; // Type of resource the file contains. 1870 ULONG cbSize; // Size of the BITMAPFILEHEADER2 structure in bytes. 1871 SHORT xHotspot; // Width of hotspot for icons and pointers. 1872 SHORT yHotspot; // Height of hotspot for icons and pointers. 1873 USHORT offBits; // Offset in bytes. 1874 BITMAPINFOHEADER2 bmp2; // Bitmap information header structure. 1875 1876 typedef struct _BITMAPINFOHEADER2 { 1877 ULONG cbFix; // Length of structure. 1878 ULONG cx; // Bitmap width in pels. 1879 ULONG cy; // Bitmap height in pels. 1880 USHORT cPlanes; // Number of bit planes. 1881 USHORT cBitCount; // Number of bits per pel within a plane. 1882 ULONG ulCompression; // Compression scheme used to store the bit map. 1883 ULONG cbImage; // Length of bitmap storage data, in bytes. 1884 ULONG cxResolution; // Horizontal component of the resolution of target device. 1885 ULONG cyResolution; // Vertical component of the resolution of target device. 1886 ULONG cclrUsed; // Number of color indexes used. 1887 ULONG cclrImportant; // Minimum number of color indexes for satisfactory appearance of the bit map. 1888 USHORT usUnits; // Units of measure. 1889 USHORT usReserved; // Reserved. 1890 USHORT usRecording; // Recording algorithm. 1891 USHORT usRendering; // Halftoning algorithm. 1892 ULONG cSize1; // Size value 1. 1893 ULONG cSize2; // Size value 2. 1894 ULONG ulColorEncoding; // Color encoding. 1895 ULONG ulIdentifier; // Reserved for application use. 1896 } BITMAPINFOHEADER2; 1897 1898 Because of the unfortunate replacement of USHORTs with ULONGs for 1899 cx and cy in the info header, the cx, cy, and cBitCount data is 1900 NOT the same between old and new formats. Well, IBM, good job. 1901 And ICONEDIT _still_ writes the old format, too. 1902 1903 } BITMAPFILEHEADER2; 1904 1905 */ 1906 1907 /* 1908 *@@ gpihCreateBitmapFromFile: 1909 * creates a new HBITMAP from the given bitmap data, 1910 * which is assumed to be in a standard OS/2 1.3 or 1911 * 2.0 bitmap file format. That is, it should start 1912 * with either a BITMAPFILEHEADER or BITMAPFILEHEADER2 1913 * (if single bitmap) or a BITMAPARRAYFILEHEADER or 1914 * BITMAPARRAYFILEHEADER2 (if bitmap array) and all 1915 * the bitmap bits following. This format is also 1916 * used by bitmap resources. 1917 * 1918 * If the file contains only a single bitmap, 1919 * this bitmap is used. 1920 * 1921 * If it contains a bitmap array, we use the 1922 * "best bitmap" in the array, which is determined 1923 * from the following criteria (in this order): 1924 * 1925 * -- a device-dependent bitmap, if its device 1926 * resolution is not too large and the given 1927 * HPS can display all its colors; 1928 * 1929 * -- a device-dependent bitmap, if its device 1930 * resolution is not too large, even if the 1931 * given HPS cannot display all its colors; 1932 * 1933 * -- a device-independent bitmap, if the given 1934 * HPS can display all its colors; 1935 * 1936 * -- the first device-independent bitmap in 1937 * the file; 1938 * 1939 * -- the first bitmap in the file. 1940 * 1941 * Support for bitmap arrays was added with V0.9.19. 1942 * I'm not quite sure if the above is the same way 1943 * of selecting the "best bitmap" that GpiLoadBitmap 1944 * would do, but without any documentation, who is 1945 * supposed to know. It appears to me however that 1946 * GpiLoadBitmap always does an _exact_ match of 1947 * device resolutions (in contrast to this function). 1948 * In other words, if you're running at 1152x864 1949 * and the device-dependent bitmap is for 1024x768, 1950 * _this_ function would use it, while GpiLoadBitmap 1951 * might load a device-independent VGA bitmap 1952 * instead. (Looks broken, if you ask me.) 1953 * 1954 * Returns: 1955 * 1956 * -- NO_ERROR 1957 * 1958 * -- ERROR_INVALID_DATA: we can't understand this format. 1959 * 1960 *@@added V0.9.20 (2002-07-19) [umoeller] 1961 */ 1962 1963 APIRET gpihCreateBitmapFromFile(HBITMAP *phbm, // out: bitmap if NO_ERROR 1964 HPS hps, // in: HPS for bmp 1965 PBYTE pData) // in: bitmap data 1966 { 1967 APIRET arc = NO_ERROR; 1968 1969 PBITMAPFILEHEADER2 pbfh = (PBITMAPFILEHEADER2)pData; 1970 1971 // check bitmap magic codes 1972 switch (pbfh->usType) 1973 { 1974 case BFT_BMAP: // "BM" 1975 // single bitmap in file (no array): 1976 if (!(*phbm = GpiCreateBitmap(hps, 1977 &pbfh->bmp2, 1978 CBM_INIT, 1979 (PBYTE)pbfh + pbfh->offBits, 1980 (PBITMAPINFO2)&pbfh->bmp2))) 1981 arc = ERROR_INVALID_DATA; 1982 break; 1983 1984 case BFT_BITMAPARRAY: // "BA" 1985 { 1986 // define a handy union for all the above crap 1987 typedef union 1988 { 1989 BITMAPFILEHEADER Old; 1990 BITMAPFILEHEADER2 New; 1991 } BMPUNION, *PBMPUNION; 1992 1993 PBMPUNION 1994 puFirstDI = NULL, // first device-independent bitmap 1995 puBestDI = NULL, // best device-independent bitmap 1996 puFirstDD = NULL, // first device-dependent bitmap 1997 puBestDD = NULL, // best device-dependent bitmap 1998 puFirstAny = NULL, // first bitmap of any type 1999 puUse; 2000 2001 // get device resolution for this HPS 2002 // so we can select the "best bitmap" 2003 #define GET_CAPS_FIRST CAPS_WIDTH 2004 #define GET_CAPS_LAST CAPS_COLOR_BITCOUNT 2005 #define GET_NO_CAPS GET_CAPS_LAST - GET_CAPS_FIRST + 1 2006 2007 LONG alCaps[GET_NO_CAPS]; 2008 PBITMAPARRAYFILEHEADER2 pba = (PBITMAPARRAYFILEHEADER2)pData; 2009 2010 DevQueryCaps(GpiQueryDevice(hps), 2011 GET_CAPS_FIRST, 2012 GET_NO_CAPS, 2013 alCaps); 2014 2015 #define BITCOUNT alCaps[CAPS_COLOR_BITCOUNT - GET_CAPS_FIRST] 2016 #define WIDTH alCaps[CAPS_WIDTH - GET_CAPS_FIRST] 2017 #define HEIGHT alCaps[CAPS_HEIGHT - GET_CAPS_FIRST] 2018 2019 // for-all-bitmaps-in-array loop 2020 while (pba) 2021 { 2022 PBMPUNION puThis = (PBMPUNION)&pba->bfh2; 2023 2024 LONG cx = 0, 2025 cy, 2026 cBitCount; 2027 2028 // ignore this if the type isn't "BM" 2029 if (puThis->Old.usType == BFT_BMAP) 2030 { 2031 // fill the three, but watch out, the offsets are 2032 // different between old and new formats 2033 if (puThis->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER)) 2034 { 2035 // old format: 2036 cx = puThis->Old.bmp.cx; 2037 cy = puThis->Old.bmp.cy; 2038 cBitCount = puThis->Old.bmp.cBitCount; 2039 } 2040 else if (puThis->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER2)) 2041 { 2042 // new format: 2043 cx = puThis->New.bmp2.cx; 2044 cy = puThis->New.bmp2.cy; 2045 cBitCount = puThis->New.bmp2.cBitCount; 2046 } 2047 } 2048 2049 if (cx) 2050 { 2051 // remember the first bitmap from all that we see 2052 if (!puFirstAny) 2053 puFirstAny = puThis; 2054 2055 // check device resolution... device-independent 2056 // one has cxDisplay and cyDisplay set to 0 2057 if ( (!pba->cxDisplay) 2058 && (!pba->cyDisplay) 2059 ) 2060 { 2061 // device-independent: 2062 2063 // remember the first device-independent bitmap 2064 if (!puFirstDI) 2065 puFirstDI = puThis; 2066 2067 if (cBitCount <= BITCOUNT) 2068 // we can display all the colors: 2069 puBestDI = puThis; 2070 } 2071 else 2072 { 2073 // device-dependent: 2074 // ignore if device resolution is too large 2075 if ( (pba->cxDisplay <= WIDTH) 2076 && (pba->cyDisplay <= HEIGHT) 2077 ) 2078 { 2079 // remember first matching device-dependent bitmap 2080 if (!puFirstDD) 2081 puFirstDD = puThis; 2082 2083 if (cBitCount <= BITCOUNT) 2084 puBestDD = puThis; 2085 } 2086 } 2087 } // end if cx 2088 2089 // go for next bmp in array 2090 if (pba->offNext) 2091 // another one coming up: 2092 // this ofs is from the beginning of the file 2093 pba = (PBITMAPARRAYFILEHEADER2)(pData + pba->offNext); 2094 else 2095 // no more bitmaps: 2096 break; 2097 } // end while (pba) 2098 2099 if ( (puUse = puBestDD) 2100 || (puUse = puFirstDD) 2101 || (puUse = puBestDI) 2102 || (puUse = puFirstDI) 2103 || (puUse = puFirstAny) 2104 ) 2105 { 2106 PBITMAPINFOHEADER2 pbih2; 2107 PBYTE pbInitData; 2108 2109 if (puUse->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER)) 2110 { 2111 // old format: 2112 pbih2 = (PBITMAPINFOHEADER2)&puUse->Old.bmp; 2113 pbInitData = (PBYTE)pData + puUse->Old.offBits; 2114 } 2115 else 2116 { 2117 // new format: 2118 pbih2 = &puUse->New.bmp2; 2119 pbInitData = (PBYTE)pData + puUse->New.offBits; 2120 } 2121 2122 if (!(*phbm = GpiCreateBitmap(hps, 2123 pbih2, 2124 CBM_INIT, 2125 pbInitData, 2126 (PBITMAPINFO2)pbih2))) 2127 arc = ERROR_INVALID_DATA; 2128 } 2129 else 2130 arc = ERROR_INVALID_DATA; 2131 } 2132 break; 2133 } 2134 2135 return arc; 2136 } 2137 2138 /* 2139 *@@ gpihLoadBitmap: 2140 * creates a new HBITMAP from the given resource. 2141 * 2142 * This is a replacement for GpiLoadBitmap which handles 2143 * device-dependent bitmaps in bitmap arrays in a 2144 * non-brain-dead way. 2145 * 2146 * Calls gpihCreateBitmapFromFile for handling the resource 2147 * data. See remarks there for how we select a bitmap from 2148 * bitmap arrays, which is _different_ from GpiLoadBitmap. 2149 * 2150 * Returns: 2151 * 2152 * -- NO_ERROR: *phbm has received new HBITMAP, 2153 * to be freed with GpiDeleteBitmap. 2154 * 2155 * -- ERROR_INVALID_DATA: resource exists, but we 2156 * can't understand its format. 2157 * 2158 * plus the error codes from DosGetResource. 2159 * 2160 *@@added V0.9.20 (2002-07-19) [umoeller] 2161 */ 2162 2163 APIRET gpihLoadBitmap(HBITMAP *phbm, // out: bitmap if NO_ERROR 2164 HPS hps, // in: HPS for bmp 2165 HMODULE hmodResource, // in: module to load bitmap from 2166 ULONG idBitmap) // in: resource ID for bitmap 2167 { 2168 APIRET arc; 2169 2170 PBYTE pbData; 2171 2172 if (!(arc = DosGetResource(hmodResource, 2173 RT_BITMAP, 2174 idBitmap, 2175 (PVOID*)&pbData))) 2176 { 2177 arc = gpihCreateBitmapFromFile(phbm, 2178 hps, 2179 pbData); 2180 2181 DosFreeResource(pbData); 2182 } 2183 2184 return arc; 1820 2185 } 1821 2186 … … 1826 2191 * yet selected into the HPS. 1827 2192 * 1828 * If the file contains only a single bitmap, 1829 * this bitmap is used. 1830 * 1831 * If it contains a bitmap array, we use the 1832 * "best bitmap" in the array, which is determined 1833 * from the following criteria (in this order): 1834 * 1835 * -- a device-dependent bitmap, if its device 1836 * resolution is not too large and the given 1837 * HPS can display all its colors; 1838 * 1839 * -- a device-dependent bitmap, if its device 1840 * resolution is not too large, even if the 1841 * given HPS cannot display all its colors; 1842 * 1843 * -- a device-independent bitmap, if the given 1844 * HPS can display all its colors; 1845 * 1846 * -- the first device-independent bitmap in 1847 * the file; 1848 * 1849 * -- the first bitmap in the file. 1850 * 1851 * Support for bitmap arrays was added with V0.9.19. 1852 * I'm not quite sure if the above is the same way 1853 * of selecting the "best bitmap" that GpiLoadBitmap 1854 * would do, but without any documentation, who is 1855 * supposed to know. 2193 * Calls gpihCreateBitmapFromFile for handling the resource 2194 * data. See remarks there for how we select a bitmap from 2195 * bitmap arrays, which is _different_ from GpiLoadBitmap. 1856 2196 * 1857 2197 * Returns: … … 1869 2209 *@@changed V0.9.4 (2000-08-03) [umoeller]: this didn't return NULLHANDLE on errors 1870 2210 *@@changed V0.9.19 (2002-04-14) [umoeller]: rewritten to support bitmap arrays, prototype changed 2211 *@@changed V0.9.20 (2002-07-19) [umoeller]: extracted bitmap selection into gpihCreateBitmapFromFile 1871 2212 */ 1872 2213 … … 1897 2238 cbFile, 1898 2239 &cbFile))) 1899 { 1900 // check bitmap magic codes 1901 PBITMAPFILEHEADER2 pbfh = (PBITMAPFILEHEADER2)pData; 1902 1903 switch (pbfh->usType) 1904 { 1905 case BFT_BMAP: // "BM" 1906 // single bitmap in file (no array): 1907 if (!(*phbm = GpiCreateBitmap(hps, 1908 &pbfh->bmp2, 1909 CBM_INIT, 1910 (PBYTE)pbfh + pbfh->offBits, 1911 (PBITMAPINFO2)&pbfh->bmp2))) 1912 arc = ERROR_INVALID_DATA; 1913 break; 1914 1915 case BFT_BITMAPARRAY: // "BA" 1916 { 1917 1918 /* 1919 typedef struct _BITMAPARRAYFILEHEADER { 1920 USHORT usType; // Type of structure. 1921 ULONG cbSize; // Size of the BITMAPARRAYFILEHEADER structure in bytes. 1922 ULONG offNext; // Offset of the next BITMAPARRAYFILEHEADER structure from the start of the file. 1923 USHORT cxDisplay; // Device width, in pels. 1924 USHORT cyDisplay; // Device height, in pels. 1925 BITMAPFILEHEADER bfh; // Bitmap file header structure. 1926 } BITMAPARRAYFILEHEADER; 1927 1928 typedef struct _BITMAPARRAYFILEHEADER2 { 1929 USHORT usType; // Type of structure. 1930 ULONG cbSize; // Size of the BITMAPARRAYFILEHEADER2 structure in bytes. 1931 ULONG offNext; // Offset of the next BITMAPARRAYFILEHEADER2 structure from the start of the file. 1932 USHORT cxDisplay; // Device width, in pels. 1933 USHORT cyDisplay; // Device height, in pels. 1934 BITMAPFILEHEADER2 bfh2; // Bitmap file header structure. 1935 } BITMAPARRAYFILEHEADER2; 1936 1937 These two are binarily the same, except for the file header that is contained. 1938 */ 1939 1940 /* OLD FORMAT 1941 1942 typedef struct _BITMAPFILEHEADER { 1943 USHORT usType; // Type of resource the file contains. 1944 ULONG cbSize; // Size of the BITMAPFILEHEADER structure in bytes. 1945 SHORT xHotspot; // Width of hotspot for icons and pointers. 1946 SHORT yHotspot; // Height of hotspot for icons and pointers. 1947 USHORT offBits; // Offset in bytes. 1948 BITMAPINFOHEADER bmp; // Bitmap information header structure. 1949 1950 typedef struct _BITMAPINFOHEADER { 1951 ULONG cbFix; // Length of structure. 1952 USHORT cx; // Bitmap width in pels. 1953 USHORT cy; // Bitmap height in pels. 1954 USHORT cPlanes; // Number of bit planes. 1955 USHORT cBitCount; // Number of bits per pel within a plane. 1956 } BITMAPINFOHEADER; 1957 1958 } BITMAPFILEHEADER; 1959 */ 1960 1961 /* NEW FORMAT 1962 1963 typedef struct _BITMAPFILEHEADER2 { 1964 USHORT usType; // Type of resource the file contains. 1965 ULONG cbSize; // Size of the BITMAPFILEHEADER2 structure in bytes. 1966 SHORT xHotspot; // Width of hotspot for icons and pointers. 1967 SHORT yHotspot; // Height of hotspot for icons and pointers. 1968 USHORT offBits; // Offset in bytes. 1969 BITMAPINFOHEADER2 bmp2; // Bitmap information header structure. 1970 1971 typedef struct _BITMAPINFOHEADER2 { 1972 ULONG cbFix; // Length of structure. 1973 ULONG cx; // Bitmap width in pels. 1974 ULONG cy; // Bitmap height in pels. 1975 USHORT cPlanes; // Number of bit planes. 1976 USHORT cBitCount; // Number of bits per pel within a plane. 1977 ULONG ulCompression; // Compression scheme used to store the bit map. 1978 ULONG cbImage; // Length of bitmap storage data, in bytes. 1979 ULONG cxResolution; // Horizontal component of the resolution of target device. 1980 ULONG cyResolution; // Vertical component of the resolution of target device. 1981 ULONG cclrUsed; // Number of color indexes used. 1982 ULONG cclrImportant; // Minimum number of color indexes for satisfactory appearance of the bit map. 1983 USHORT usUnits; // Units of measure. 1984 USHORT usReserved; // Reserved. 1985 USHORT usRecording; // Recording algorithm. 1986 USHORT usRendering; // Halftoning algorithm. 1987 ULONG cSize1; // Size value 1. 1988 ULONG cSize2; // Size value 2. 1989 ULONG ulColorEncoding; // Color encoding. 1990 ULONG ulIdentifier; // Reserved for application use. 1991 } BITMAPINFOHEADER2; 1992 1993 Because of the unfortunate replacement of USHORTs with ULONGs for 1994 cx and cy in the info header, the cx, cy, and cBitCount data is 1995 NOT the same between old and new formats. Well, IBM, good job. 1996 And ICONEDIT _still_ writes the old format, unfortunately. 1997 1998 } BITMAPFILEHEADER2; 1999 2000 */ 2001 // define a handy union for all the above bullshit 2002 typedef union 2003 { 2004 BITMAPFILEHEADER Old; 2005 BITMAPFILEHEADER2 New; 2006 } BMPUNION, *PBMPUNION; 2007 2008 PBMPUNION puFirstDI = NULL, // first device-independent bitmap 2009 puBestDI = NULL, // best device-independent bitmap 2010 puFirstDD = NULL, // first device-dependent bitmap 2011 puBestDD = NULL, // best device-dependent bitmap 2012 puFirstAny = NULL, // first bitmap of any type 2013 puUse; 2014 2015 // get device resolution for this HPS 2016 // so we can select the "best bitmap" 2017 #define GET_CAPS_FIRST CAPS_WIDTH 2018 #define GET_CAPS_LAST CAPS_COLOR_BITCOUNT 2019 #define GET_NO_CAPS GET_CAPS_LAST - GET_CAPS_FIRST + 1 2020 2021 LONG alCaps[GET_NO_CAPS]; 2022 PBITMAPARRAYFILEHEADER2 pba = (PBITMAPARRAYFILEHEADER2)pData; 2023 2024 DevQueryCaps(GpiQueryDevice(hps), 2025 GET_CAPS_FIRST, 2026 GET_NO_CAPS, 2027 alCaps); 2028 2029 #define BITCOUNT alCaps[CAPS_COLOR_BITCOUNT - GET_CAPS_FIRST] 2030 #define WIDTH alCaps[CAPS_WIDTH - GET_CAPS_FIRST] 2031 #define HEIGHT alCaps[CAPS_HEIGHT - GET_CAPS_FIRST] 2032 2033 // for-all-bitmaps-in-array loop 2034 while (pba) 2035 { 2036 PBMPUNION puThis = (PBMPUNION)&pba->bfh2; 2037 2038 LONG cx = 0, 2039 cy, 2040 cBitCount; 2041 2042 // ignore this if the type isn't "BM" 2043 if (puThis->Old.usType == BFT_BMAP) 2044 { 2045 // fill the three, but watch out, the offsets are 2046 // different between old and new formats 2047 if (puThis->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER)) 2048 { 2049 // old format: 2050 cx = puThis->Old.bmp.cx; 2051 cy = puThis->Old.bmp.cy; 2052 cBitCount = puThis->Old.bmp.cBitCount; 2053 } 2054 else if (puThis->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER2)) 2055 { 2056 // new format: 2057 cx = puThis->New.bmp2.cx; 2058 cy = puThis->New.bmp2.cy; 2059 cBitCount = puThis->New.bmp2.cBitCount; 2060 } 2061 } 2062 2063 if (cx) 2064 { 2065 // store first bitmap of any type 2066 if (!puFirstAny) 2067 puFirstAny = puThis; 2068 2069 // check device resolution... device-independent 2070 // one has cxDisplay and cyDisplay set to 0 2071 if ( (!pba->cxDisplay) 2072 && (!pba->cyDisplay) 2073 ) 2074 { 2075 // device-independent: 2076 2077 // store first device-independent bmp 2078 if (!puFirstDI) 2079 puFirstDI = puThis; 2080 2081 if (cBitCount <= BITCOUNT) 2082 // we can display all the colors: 2083 puBestDI = puThis; 2084 } 2085 else 2086 { 2087 // device-dependent: 2088 // ignore if device resolution is too large 2089 if ( (pba->cxDisplay <= WIDTH) 2090 && (pba->cyDisplay <= HEIGHT) 2091 ) 2092 { 2093 if (!puFirstDD) 2094 puFirstDD = puThis; 2095 2096 if (cBitCount <= BITCOUNT) 2097 puBestDD = puThis; 2098 } 2099 } 2100 } // end if cx 2101 2102 // go for next bmp in array 2103 if (pba->offNext) 2104 // another one coming up: 2105 // this ofs is from the beginning of the file 2106 pba = (PBITMAPARRAYFILEHEADER2)(pData + pba->offNext); 2107 else 2108 // no more bitmaps: 2109 break; 2110 } // end while (pba) 2111 2112 if ( (puUse = puBestDD) 2113 || (puUse = puFirstDD) 2114 || (puUse = puBestDI) 2115 || (puUse = puFirstDI) 2116 || (puUse = puFirstAny) 2117 ) 2118 { 2119 PBITMAPINFOHEADER2 pbih2; 2120 PBYTE pbInitData; 2121 2122 if (puUse->Old.bmp.cbFix == sizeof(BITMAPINFOHEADER)) 2123 { 2124 // old format: 2125 pbih2 = (PBITMAPINFOHEADER2)&puUse->Old.bmp; 2126 pbInitData = (PBYTE)pData + puUse->Old.offBits; 2127 } 2128 else 2129 { 2130 // new format: 2131 pbih2 = &puUse->New.bmp2; 2132 pbInitData = (PBYTE)pData + puUse->New.offBits; 2133 } 2134 2135 if (!(*phbm = GpiCreateBitmap(hps, 2136 pbih2, 2137 CBM_INIT, 2138 pbInitData, 2139 (PBITMAPINFO2)pbih2))) 2140 arc = ERROR_INVALID_DATA; 2141 } 2142 else 2143 arc = ERROR_INVALID_DATA; 2144 } 2145 break; 2146 } 2147 } 2240 // extracted all the code into this extra func 2241 // V0.9.20 (2002-07-19) [umoeller] 2242 arc = gpihCreateBitmapFromFile(phbm, 2243 hps, 2244 (PBYTE)pData); 2148 2245 2149 2246 free(pData); … … 2154 2251 2155 2252 return arc; 2156 2157 /* if (stat(pszBmpFile, &st) == 0)2158 {2159 2160 if ((pData = (PBYTE)malloc(st.st_size)))2161 {2162 // open bmp file2163 if ((BmpFile = fopen(pszBmpFile, "rb")))2164 {2165 // read bmp data2166 fread(pData, 1, st.st_size, BmpFile);2167 fclose(BmpFile);2168 2169 // check bitmap magic codes2170 if (pData[0] == 'B' && pData[1] == 'M')2171 {2172 pbfh = (PBITMAPFILEHEADER2)pData;2173 hbm = GpiCreateBitmap(hps,2174 &pbfh->bmp2,2175 CBM_INIT,2176 (pData + pbfh->offBits),2177 (PBITMAPINFO2)&pbfh->bmp2);2178 2179 if (hbm == NULLHANDLE)2180 {2181 if (pulError)2182 *pulError = -5;2183 }2184 }2185 else if (pulError)2186 *pulError = -4;2187 2188 }2189 else if (pulError)2190 *pulError = -3;2191 2192 free(pData);2193 }2194 else if (pulError)2195 *pulError = -2;2196 }2197 else if (pulError)2198 *pulError = -1;2199 2200 return (hbm);*/2201 2253 } 2202 2254 … … 2243 2295 BOOL fProportional) // in: preserve proportions when stretching? 2244 2296 { 2245 LONG lHits = 0;2246 2297 BITMAPINFOHEADER2 bih2; 2247 2298 POINTL aptl[4]; … … 2329 2380 } 2330 2381 2331 lHits =GpiWCBitBlt(hpsTarget, // target HPS (bmp selected)2332 2333 2334 2335 2336 2382 return GpiWCBitBlt(hpsTarget, // target HPS (bmp selected) 2383 hbmSource, 2384 4L, // must always be 4 2385 &aptl[0], // points array 2386 ROP_SRCCOPY, 2387 BBO_IGNORE); 2337 2388 // ignore eliminated rows or 2338 2389 // columns; useful for color 2339 2340 return (lHits);2341 2390 } 2342 2391 … … 2459 2508 * 2460 2509 * To do clipping with WinDrawPointer, one has to 2461 * limit the clip rectangle for the current HPS, 2462 * which is quite an overhead. This function instead 2463 * allows for specifying a clip rectangle directly. 2464 * Besides, since it uses GpiWCBitBlt, it should 2465 * probably work with all types of device contexts. 2510 * alter the clip rectangle for the current HPS, 2511 * which involves creating regions and is thus quite 2512 * some overhead. 2513 * 2514 * Instead, this function allows for specifying a clip 2515 * rectangle directly. Besides, since it uses GpiWCBitBlt, 2516 * it should probably work with all types of device contexts. 2466 2517 * 2467 2518 * This also replaces gpihIcon2Bitmap, which wasn't quite … … 2734 2785 LONG cy) // in: bitmap height 2735 2786 { 2736 return (gpihCreateXBitmap2(hab,2737 2738 2739 2740 0));2787 return gpihCreateXBitmap2(hab, 2788 cx, 2789 cy, 2790 0, 2791 0); 2741 2792 } 2742 2793 … … 2744 2795 *@@ gpihCreateXBitmap: 2745 2796 * creates an XBitmap, which is returned in an 2746 * _XBITMAP structure.2797 * XBITMAP structure. 2747 2798 * 2748 2799 * The problem with all the GPI bitmap functions … … 2825 2876 } 2826 2877 2827 return (pbmp);2878 return pbmp; 2828 2879 } 2829 2880 … … 2849 2900 GpiSetBitmap(pbmp->hpsMem, NULLHANDLE); 2850 2901 2851 return (hbm);2902 return hbm; 2852 2903 } 2853 2904 … … 2935 2986 aptl[2].y = prcl->yBottom; 2936 2987 2937 if (GpiBitBlt(pBmp->hpsMem, 2938 hpsScreen, 2939 sizeof(aptl) / sizeof(POINTL), // Number of points in aptl 2940 aptl, 2941 ROP_SRCCOPY, 2942 BBO_IGNORE) 2943 == GPI_ERROR) 2988 if (GPI_ERROR == GpiBitBlt(pBmp->hpsMem, 2989 hpsScreen, 2990 sizeof(aptl) / sizeof(POINTL), // Number of points in aptl 2991 aptl, 2992 ROP_SRCCOPY, 2993 BBO_IGNORE)) 2944 2994 { 2945 2995 // error during bitblt: … … 2948 2998 } 2949 2999 2950 return (pBmp);2951 } 2952 3000 return pBmp; 3001 } 3002 -
trunk/src/helpers/nls.c
r185 r190 198 198 * 199 199 *@@added V0.9.19 (2002-06-13) [umoeller] 200 *@@changed V0.9.20 (2002-07-22) [umoeller]: optimized 201 *@@changed V0.9.20 (2002-07-22) [lafaix]: optimized 200 202 */ 201 203 … … 203 205 { 204 206 PCSZ p2; 205 ULONG ulDBCS ;207 ULONG ulDBCSType = TYPE_SBCS; 206 208 207 209 if (!nlsDBCS()) … … 209 211 return strchr(p, c); 210 212 213 // we're on DBCS: 214 215 // we can't find c if it is a leading byte 216 if (G_afLeadByte[c] != TYPE_SBCS) 217 return NULL; 218 219 for (p2 = p; 220 *p2; 221 ++p2) 222 { 223 // check _previous_ DBCS type and refresh 224 // DBCS type accordingly 225 switch (ulDBCSType) 226 { 227 case TYPE_SBCS: 228 case TYPE_DBCS_2ND: 229 ulDBCSType = G_afLeadByte[*p2]; 230 // we can safely do the test here (and skip rechecking 231 // the type) because c can't possibly be a leading byte 232 // V0.9.20 (2002-07-22) [lafaix] 233 if (*p2 == c) 234 return (PSZ)p2; 235 break; 236 237 case TYPE_DBCS_1ST : 238 ulDBCSType = TYPE_DBCS_2ND; 239 break; 240 } 241 } 242 243 /* old code V0.9.20 (2002-07-22) [umoeller] 211 244 // we're on DBCS: 212 245 for (p2 = p; … … 228 261 } 229 262 } 263 */ 230 264 231 265 return NULL; … … 240 274 * 241 275 *@@added V0.9.19 (2002-06-13) [umoeller] 276 *@@changed V0.9.20 (2002-07-22) [lafaix]: optimized 242 277 */ 243 278 244 279 PSZ nlsrchr(PCSZ p, char c) 245 280 { 246 PCSZ p2 ;247 ULONG ulDBCS,248 ulLength;281 PCSZ p2, 282 pLast = NULL; 283 ULONG ulDBCSType = TYPE_SBCS; 249 284 250 285 if (!nlsDBCS()) … … 253 288 254 289 // we're on DBCS: 290 291 // we can't find c if it is a leading byte 292 if (G_afLeadByte[c] != TYPE_SBCS) 293 return NULL; 294 295 for (p2 = p; 296 *p2; 297 ++p2) 298 { 299 // check _previous_ DBCS type and refresh 300 // DBCS type accordingly 301 switch (ulDBCSType) 302 { 303 case TYPE_SBCS: 304 case TYPE_DBCS_2ND: 305 ulDBCSType = G_afLeadByte[*p2]; 306 if (*p2 == c) 307 pLast = p2; 308 break; 309 310 case TYPE_DBCS_1ST : 311 ulDBCSType = TYPE_DBCS_2ND; 312 break; 313 } 314 } 315 316 return (PSZ)pLast; 317 318 // old code V0.9.20 (2002-07-22) [lafaix] 319 /* 255 320 ulLength = strlen(p); 256 321 for (p2 = p + ulLength - 1; … … 274 339 275 340 return NULL; 341 */ 276 342 } 277 343 -
trunk/src/helpers/tmsgfile.c
r169 r190 105 105 /* 106 106 *@@ MSGENTRY: 107 * private representation of a message in a text 108 * message file. Each tree entry in 109 * TMFMSGFILE.IDsTreeRoot points to one of these 110 * structures. 107 111 * 108 112 *@@added V0.9.16 (2001-10-08) [umoeller] … … 111 115 typedef struct _MSGENTRY 112 116 { 113 TREE Tree; // ulKey points to strID.psz114 XSTRING strID; // message ID115 ULONG ulOfsText; // offset of start of text (in C-format buffer)116 ULONG cbText; // length of text in msg file117 TREE Tree; // ulKey points to strID.psz 118 XSTRING strID; // message ID 119 ULONG ulOfsText; // offset of start of message text in file 120 ULONG cbText; // length of text in msg file 117 121 } MSGENTRY, *PMSGENTRY; 118 122 … … 143 147 * 144 148 *@@added V0.9.18 (2002-03-24) [umoeller] 145 */ 146 147 APIRET LoadAndCompile(PTMFMSGFILE pFile) 149 *@@changed V0.9.20 (2002-07-19) [umoeller]: optimized, no longer holding all msgs im mem 150 */ 151 152 APIRET LoadAndCompile(PTMFMSGFILE pTmf, // in: TMF struct to set up 153 PXFILE pFile) // in: opened XFILE for msg file 148 154 { 149 APIRET arc; 150 151 PSZ pszContent = NULL; 152 if (!(arc = doshLoadTextFile(pFile->pszFilename, 153 &pszContent, 154 NULL))) 155 APIRET arc; 156 157 PSZ pszContent = NULL; 158 ULONG cbRead; 159 160 if (!(arc = doshReadText(pFile, 161 &pszContent, 162 &cbRead))) // bytes read including null char 155 163 { 156 164 // file loaded: … … 162 170 ulEndMarkerLength = strlen(G_pcszEndMarker); 163 171 172 XSTRING strContents; 173 164 174 // initialize TMFMSGFILE struct 165 treeInit(&pFile->IDsTreeRoot, NULL); 166 167 xstrInitSet(&pFile->strContent, pszContent); 175 treeInit(&pTmf->IDsTreeRoot, NULL); 176 177 xstrInit(&strContents, 178 cbRead); // including null byte 179 xstrcpy(&strContents, 180 pszContent, 181 cbRead - 1); // not including null byte 168 182 169 183 // convert to plain C format 170 xstrConvertLineFormat(&pFile->strContent,184 /* xstrConvertLineFormat(&pTmf->strContent, 171 185 CRLF2LF); 186 */ 172 187 173 188 // kick out all the comments 174 while (pStartOfMarker = strstr(pFile->strContent.psz, "\n;")) 189 /* 190 while (pStartOfMarker = strstr(pTmf->strContent.psz, "\n;")) 175 191 { 176 192 // copy the next line over this 177 193 PCSZ pEOL = strhFindEOL(pStartOfMarker + 2, NULL); 178 xstrrpl(&p File->strContent,194 xstrrpl(&pTmf->strContent, 179 195 // ofs of first char to replace: "\n;" 180 pStartOfMarker - p File->strContent.psz,196 pStartOfMarker - pTmf->strContent.psz, 181 197 // no. of chars to replace: 182 198 pEOL - pStartOfMarker, … … 186 202 0); 187 203 } 204 */ 188 205 189 206 // free excessive memory 190 xstrShrink(&pFile->strContent);191 192 pStartOfFile = pFile->strContent.psz;207 // xstrShrink(&pTmf->strContent); 208 209 pStartOfFile = strContents.psz; 193 210 194 211 // go build a tree of all message IDs... … … 205 222 // search next start marker 206 223 PCSZ pStartOfNextMarker = strstr(pStartOfMsgID + 1, 207 G_pcszStartMarker); 224 G_pcszStartMarker); // "\n<--" 208 225 // and the end-marker 209 226 PCSZ pEndOfMarker = strstr(pStartOfMsgID + 1, 210 G_pcszEndMarker); 227 G_pcszEndMarker); // "-->:" 211 228 212 229 PMSGENTRY pNew; … … 236 253 { 237 254 // length of the ID 238 ULONG ulIDLength = pEndOfMarker - pStartOfMsgID; 239 PCSZ pStartOfText = pEndOfMarker + ulEndMarkerLength; 255 ULONG ulIDLength = pEndOfMarker - pStartOfMsgID; 256 PCSZ pStartOfText = pEndOfMarker + ulEndMarkerLength, 257 pNextComment; 240 258 241 259 ZERO(pNew); … … 253 271 pStartOfText++; 254 272 255 // store start of text273 // store offset of start of text 256 274 pNew->ulOfsText = pStartOfText - pStartOfFile; 257 275 258 276 // check if there's a comment before the 259 277 // next item 260 /*if (pNextComment = strstr(pStartOfText, "\n;"))278 if (pNextComment = strstr(pStartOfText, "\n;")) 261 279 { 262 280 if ( (!pStartOfNextMarker) 263 281 || (pNextComment < pStartOfNextMarker) 264 282 ) 265 pEndOfText = pNextComment; 266 } */ 267 268 if (pStartOfNextMarker) 269 // other markers left: 270 pNew->cbText = // offset of next marker 271 (pStartOfNextMarker - pStartOfFile) 272 - pNew->ulOfsText; 283 pNew->cbText = // offset of comment marker 284 (pNextComment - pStartOfFile) 285 - pNew->ulOfsText; 286 else 287 // we have a next marker AND 288 // the comment comes after it 289 pNew->cbText = // offset of next marker 290 (pStartOfNextMarker - pStartOfFile) 291 - pNew->ulOfsText; 292 } 273 293 else 274 // this was the last message: 275 pNew->cbText = strlen(pStartOfText); 294 if (pStartOfNextMarker) 295 // other markers left: 296 pNew->cbText = // offset of next marker 297 (pStartOfNextMarker - pStartOfFile) 298 - pNew->ulOfsText; 299 else 300 // this was the last message: 301 pNew->cbText = strlen(pStartOfText); 276 302 277 303 // remove trailing newlines 278 304 while ( (pNew->cbText) 279 && (pStartOfText[pNew->cbText-1] == '\n') 305 && ( (pStartOfText[pNew->cbText - 1] == '\n') 306 || (pStartOfText[pNew->cbText - 1] == '\r') 307 ) 280 308 ) 281 309 (pNew->cbText)--; 282 310 283 311 // store this thing 284 if (!treeInsert(&p File->IDsTreeRoot,312 if (!treeInsert(&pTmf->IDsTreeRoot, 285 313 NULL, 286 314 (TREE*)pNew, 287 315 treeCompareStrings)) 288 316 // successfully inserted: 289 (p File->cIDs)++;317 (pTmf->cIDs)++; 290 318 } 291 319 … … 293 321 pStartOfMarker = pStartOfNextMarker; 294 322 } // end while ( (pStartOfMarker) ... 295 } // end else if (!(pFile = NEW(TMFMSGFILE))) 323 324 free(pszContent); 325 326 } // end else if (!(pTmf = NEW(TMFMSGFILE))) 296 327 297 328 return arc; … … 318 349 * 319 350 *@@added V0.9.16 (2001-10-08) [umoeller] 351 *@@changed V0.9.20 (2002-07-19) [umoeller]: optimized, no longer holding all msgs im mem 320 352 */ 321 353 … … 325 357 APIRET arc; 326 358 327 FILESTATUS3 fs3; 328 if (!(arc = DosQueryPathInfo((PSZ)pcszMessageFile, 329 FIL_STANDARD, 330 &fs3, 331 sizeof(fs3)))) 359 ULONG cbFile; 360 PXFILE pFile; 361 if (!(arc = doshOpen(pcszMessageFile, 362 XOPEN_READ_EXISTING, 363 &cbFile, 364 &pFile))) 332 365 { 333 366 // create a TMFMSGFILE entry 334 PTMFMSGFILE p File;335 if (!(p File= NEW(TMFMSGFILE)))367 PTMFMSGFILE pTmf; 368 if (!(pTmf = NEW(TMFMSGFILE))) 336 369 arc = ERROR_NOT_ENOUGH_MEMORY; 337 370 else 338 371 { 339 ZERO(p File);340 p File->pszFilename = strdup(pcszMessageFile);372 ZERO(pTmf); 373 pTmf->pszFilename = strdup(pcszMessageFile); 341 374 342 375 // TMFMSGFILE created: 343 if (!(arc = LoadAndCompile(p File)))376 if (!(arc = LoadAndCompile(pTmf, pFile))) 344 377 { 345 378 // set timestamp to that of the file 346 dtCreateFileTimeStamp(pFile->szTimestamp, 347 &fs3.fdateLastWrite, 348 &fs3.ftimeLastWrite); 349 350 // output 351 *ppMsgFile = pFile; 379 FILESTATUS3 fs3; 380 if (!(arc = DosQueryFileInfo(pFile->hf, 381 FIL_STANDARD, 382 &fs3, 383 sizeof(fs3)))) 384 { 385 dtCreateFileTimeStamp(pTmf->szTimestamp, 386 &fs3.fdateLastWrite, 387 &fs3.ftimeLastWrite); 388 389 // output 390 *ppMsgFile = pTmf; 391 } 352 392 } 353 else 393 394 if (arc) 354 395 // error: 355 tmfCloseMessageFile(&p File);396 tmfCloseMessageFile(&pTmf); 356 397 } 398 399 doshClose(&pFile); 357 400 } 358 401 … … 370 413 */ 371 414 372 static VOID FreeInternalMem(PTMFMSGFILE p File)415 static VOID FreeInternalMem(PTMFMSGFILE pTmf) 373 416 { 374 417 LONG cItems; 375 418 TREE** papNodes; 376 419 377 xstrClear(&pFile->strContent); 378 379 if (cItems = pFile->cIDs) 420 if (cItems = pTmf->cIDs) 380 421 { 381 if (papNodes = treeBuildArray(p File->IDsTreeRoot,422 if (papNodes = treeBuildArray(pTmf->IDsTreeRoot, 382 423 &cItems)) 383 424 { … … 410 451 if (ppMsgFile && *ppMsgFile) 411 452 { 412 PTMFMSGFILE p File= *ppMsgFile;413 414 if (p File->pszFilename)415 free(p File->pszFilename);416 417 FreeInternalMem(p File);418 419 free(p File);453 PTMFMSGFILE pTmf = *ppMsgFile; 454 455 if (pTmf->pszFilename) 456 free(pTmf->pszFilename); 457 458 FreeInternalMem(pTmf); 459 460 free(pTmf); 420 461 *ppMsgFile = NULL; 421 462 … … 453 494 *@@added V0.9.16 (2001-10-08) [umoeller] 454 495 *@@changed V0.9.18 (2002-03-24) [umoeller]: now recompiling if last write date changed 496 *@@changed V0.9.20 (2002-07-19) [umoeller]: optimized, no longer holding all msgs im mem 455 497 */ 456 498 … … 463 505 APIRET arc = NO_ERROR; 464 506 465 if (!pMsgFile) 507 if ( (!pMsgFile) 508 || (!pMsgFile->pszFilename) 509 ) 466 510 arc = ERROR_INVALID_PARAMETER; 467 511 else 468 512 { 469 // check if last-write date/time changed compared 470 // to the last time we opened the thing... 471 // V0.9.18 (2002-03-24) [umoeller] 472 FILESTATUS3 fs3; 473 if (!(arc = DosQueryPathInfo(pMsgFile->pszFilename, 474 FIL_STANDARD, 475 &fs3, 476 sizeof(fs3)))) 513 // open the file again V0.9.20 (2002-07-19) [umoeller] 514 ULONG cbFile; 515 PXFILE pFile; 516 if (!(arc = doshOpen(pMsgFile->pszFilename, 517 XOPEN_READ_EXISTING, 518 &cbFile, 519 &pFile))) 477 520 { 478 CHAR szTemp[30]; 479 dtCreateFileTimeStamp(szTemp, 480 &fs3.fdateLastWrite, 481 &fs3.ftimeLastWrite); 482 if (strcmp(szTemp, pMsgFile->szTimestamp)) 521 // check if last-write date/time changed compared 522 // to the last time we opened the thing... 523 // V0.9.18 (2002-03-24) [umoeller] 524 FILESTATUS3 fs3; 525 if (!(arc = DosQueryFileInfo(pFile->hf, 526 FIL_STANDARD, 527 &fs3, 528 sizeof(fs3)))) 483 529 { 484 // last write date changed: 485 _Pmpf((__FUNCTION__ ": timestamp changed, recompiling")); 486 FreeInternalMem(pMsgFile); 487 if (!(arc = LoadAndCompile(pMsgFile))) 488 strcpy(pMsgFile->szTimestamp, szTemp); 530 CHAR szTemp[30]; 531 dtCreateFileTimeStamp(szTemp, 532 &fs3.fdateLastWrite, 533 &fs3.ftimeLastWrite); 534 if (strcmp(szTemp, pMsgFile->szTimestamp)) 535 { 536 // last write date changed: 537 _Pmpf((__FUNCTION__ ": timestamp changed, recompiling")); 538 FreeInternalMem(pMsgFile); 539 540 if (!(arc = LoadAndCompile(pMsgFile, pFile))) 541 strcpy(pMsgFile->szTimestamp, szTemp); 542 } 489 543 } 490 } 491 492 if (!arc) 493 { 494 // go find the message in the tree 495 PMSGENTRY pEntry; 496 if (pEntry = (PMSGENTRY)treeFind(pMsgFile->IDsTreeRoot, 497 (ULONG)pcszMessageName, 498 treeCompareStrings)) 544 545 if (!arc) 499 546 { 500 // copy the raw string to the output buffer501 xstrcpy(pstr,502 pMsgFile->strContent.psz + pEntry->ulOfsText,503 pEntry->cbText);504 505 // now replace strings from the table506 if (cTableEntries && pTable)547 // go find the message in the tree 548 PMSGENTRY pEntry; 549 if (!(pEntry = (PMSGENTRY)treeFind(pMsgFile->IDsTreeRoot, 550 (ULONG)pcszMessageName, 551 treeCompareStrings))) 552 arc = ERROR_MR_MID_NOT_FOUND; 553 else 507 554 { 508 CHAR szFind[10] = "%0"; 509 ULONG ul; 510 for (ul = 0; 511 ul < cTableEntries; 512 ul++) 555 PSZ pszMsg; 556 ULONG cbRead = pEntry->cbText; 557 558 if (!(pszMsg = (PSZ)malloc(cbRead + 1))) 559 arc = ERROR_NOT_ENOUGH_MEMORY; 560 else if (!(arc = doshReadAt(pFile, 561 pEntry->ulOfsText, 562 &cbRead, 563 pszMsg, 564 DRFL_NOCACHE | DRFL_FAILIFLESS))) 513 565 { 514 ULONG ulOfs = 0; 515 516 _ultoa(ul + 1, szFind + 1, 10); 517 while (xstrFindReplaceC(pstr, 518 &ulOfs, 519 szFind, 520 pTable[ul])) 521 ; 566 // null-terminate 567 pszMsg[cbRead] = '\0'; 568 xstrset2(pstr, 569 pszMsg, 570 cbRead); 571 572 // kick out \r\n 573 xstrConvertLineFormat(pstr, 574 CRLF2LF); 575 576 // now replace strings from the table 577 if (cTableEntries && pTable) 578 { 579 CHAR szFind[10] = "%0"; 580 ULONG ul; 581 for (ul = 0; 582 ul < cTableEntries; 583 ul++) 584 { 585 ULONG ulOfs = 0; 586 587 _ultoa(ul + 1, szFind + 1, 10); 588 while (xstrFindReplaceC(pstr, 589 &ulOfs, 590 szFind, 591 pTable[ul])) 592 ; 593 } 594 } 522 595 } 523 596 } 524 597 } 525 else 526 arc = ERROR_MR_MID_NOT_FOUND;598 599 doshClose(&pFile); 527 600 } 528 601 }
Note:
See TracChangeset
for help on using the changeset viewer.