Changeset 190


Ignore:
Timestamp:
Jul 22, 2002, 10:08:02 PM (23 years ago)
Author:
umoeller
Message:

DBCS fixes.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/dosh.h

    r161 r190  
    606606
    607607    APIRET doshClose(PXFILE *ppFile);
     608
     609    APIRET doshReadText(PXFILE pFile,
     610                        PSZ* ppszContent,
     611                        PULONG pcbRead);
    608612
    609613    APIRET doshLoadTextFile(PCSZ pcszFile,
  • trunk/include/helpers/gpih.h

    r178 r190  
    322322    typedef GPIHCREATEHALFTONEDBITMAP *PGPIHCREATEHALFTONEDBITMAP;
    323323
     324    APIRET gpihLoadBitmap(HBITMAP *phbm,
     325                          HPS hps,
     326                          HMODULE hmodResource,
     327                          ULONG idBitmap);
     328
    324329    APIRET XWPENTRY gpihLoadBitmapFile(HBITMAP *phbm, HPS hps, PCSZ pcszBmpFile);
    325330    typedef APIRET XWPENTRY GPIHLOADBITMAPFILE(HBITMAP *phbm, HPS hps, PCSZ pcszBmpFile);
  • trunk/include/helpers/tmsgfile.h

    r150 r190  
    3232    /*
    3333     *@@ TMFMSGFILE:
     34     *      representation of a text message file opened by
     35     *      tmfOpenMessageFile.
    3436     *
    3537     *@@added V0.9.16 (2001-10-08) [umoeller]
     
    3941    {
    4042        PSZ     pszFilename;            // copy of .TMF file name
    41 
    42         XSTRING strContent;             // file's full contents (converted to C LF format)
    4343
    4444        TREE    *IDsTreeRoot;           // root of tree with MSGENTRY's (a TREE* really)
     
    5959                         ULONG cTableEntries);
    6060
    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 
    7861#endif // TMSGFILE_HEADER_INCLUDED
    7962
  • trunk/src/helpers/dosh.c

    r169 r190  
    28542854
    28552855/*
     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
     2866APIRET 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/*
    28562915 *@@ doshLoadTextFile:
    28572916 *      reads a text file from disk, allocates memory
     
    28922951                         &pFile)))
    28932952    {
    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);
    29322956        doshClose(&pFile);
    29332957    }
  • trunk/src/helpers/gpih.c

    r189 r190  
    3434
    3535#define INCL_DOSSEMAPHORES
     36#define INCL_DOSMODULEMGR
     37#define INCL_DOSRESOURCES
    3638#define INCL_DOSERRORS
    3739
     
    140142    }
    141143
    142     return (FALSE);
     144    return FALSE;
    143145}
    144146
     
    191193    }
    192194
    193     return (DisplayCaps[ulIndex]);
     195    return DisplayCaps[ulIndex];
    194196}
    195197
     
    300302BOOL gpihSwitchToRGB(HPS hps)
    301303{
    302     return (GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL));
     304    return GpiCreateLogColorTable(hps, 0, LCOLF_RGB, 0, 0, NULL);
    303305}
    304306
     
    567569    }
    568570
    569     return (lHits);
     571    return lHits;
    570572}
    571573
     
    982984 *
    983985 *@@added V0.9.1 (2000-02-15) [umoeller]
     986 *@@changed V0.9.20 (2002-07-19) [umoeller]: optimized
    984987 */
    985988
     
    990993                                             // (e.g. "Courier")
    991994{
    992     BOOL brc = FALSE;
    993 
    994     if (pszFontNameSize)
     995    PCHAR   pcDot;
     996    if (    (pszFontNameSize)
     997         && (pcDot = strchr(pszFontNameSize, '.'))
     998       )
    995999    {
    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;
    10041005    }
    10051006
    1006     return brc;
     1007    return FALSE;
    10071008}
    10081009
     
    11631164    // _Pmpf((__FUNCTION__ ": Returning lcid %d", lcidNext));
    11641165
    1165     return (lcidNext);
     1166    return lcidNext;
    11661167}
    11671168
     
    11901191    }
    11911192
    1192     return (lLCIDReturn);
     1193    return lLCIDReturn;
    11931194}
    11941195
     
    13711372                  pFontMetrics);
    13721373
    1373     return (gpihCreateFont(hps,
    1374                            &FontAttrs));
     1374    return gpihCreateFont(hps,
     1375                          &FontAttrs);
    13751376
    13761377    // _Pmpf((__FUNCTION__ ": returning lcid %d", lLCIDReturn));
     
    14511452                *plSize = ulFontSize;
    14521453            strcpy(szFaceName, pcDot + 1);
    1453             return (gpihFindFont(hps,
    1454                                  ulFontSize,
    1455                                  FALSE,         // face, not family name
    1456                                  szFaceName,
    1457                                  0,
    1458                                  pFontMetrics));
     1454            return gpihFindFont(hps,
     1455                                ulFontSize,
     1456                                FALSE,         // face, not family name
     1457                                szFaceName,
     1458                                0,
     1459                                pFontMetrics);
    14591460        }
    14601461    }
    14611462
    1462     return (0);
     1463    return 0;
    14631464}
    14641465
     
    15231524    box.cy = (FIXED)(lPointSize / 72 * alDevRes[1]);
    15241525
    1525     return (GpiSetCharBox(hps, &box));
     1526    return GpiSetCharBox(hps, &box);
    15261527}
    15271528
     
    15471548                   +fm.lExternalLeading)    // space advised by font designer
    15481549               );
    1549     else
    1550         return (15);
     1550
     1551    return 15;
    15511552}
    15521553
     
    16401641                         ULONG cy)          // in: height of new bitmap
    16411642{
    1642     return (gpihCreateBitmap2(hpsMem,
    1643                               cx,
    1644                               cy,
    1645                               0,
    1646                               0));            // current screen bit count
     1643    return gpihCreateBitmap2(hpsMem,
     1644                             cx,
     1645                             cy,
     1646                             0,
     1647                             0);            // current screen bit count
    16471648}
    16481649
     
    17151716    }
    17161717
    1717     return (hbm);
     1718    return hbm;
    17181719}
    17191720
     
    18171818    } // end if (hbmSource)
    18181819
    1819     return (hbmReturn);
     1820    return hbmReturn;
     1821}
     1822
     1823/*
     1824typedef 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
     1833typedef 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
     1842These two are binarily the same, except for the file header that is contained.
     1843*/
     1844
     1845/*      OLD FORMAT
     1846
     1847typedef 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
     1868typedef 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
     1963APIRET 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
     2163APIRET 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;
    18202185}
    18212186
     
    18262191 *      yet selected into the HPS.
    18272192 *
    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.
    18562196 *
    18572197 *      Returns:
     
    18692209 *@@changed V0.9.4 (2000-08-03) [umoeller]: this didn't return NULLHANDLE on errors
    18702210 *@@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
    18712212 */
    18722213
     
    18972238                                cbFile,
    18982239                                &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);
    21482245
    21492246            free(pData);
     
    21542251
    21552252    return arc;
    2156 
    2157     /* if (stat(pszBmpFile, &st) == 0)
    2158     {
    2159 
    2160         if ((pData = (PBYTE)malloc(st.st_size)))
    2161         {
    2162             // open bmp file
    2163             if ((BmpFile = fopen(pszBmpFile, "rb")))
    2164             {
    2165                 // read bmp data
    2166                 fread(pData, 1, st.st_size, BmpFile);
    2167                 fclose(BmpFile);
    2168 
    2169                 // check bitmap magic codes
    2170                 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);*/
    22012253}
    22022254
     
    22432295                       BOOL fProportional)  // in: preserve proportions when stretching?
    22442296{
    2245     LONG                lHits = 0;
    22462297    BITMAPINFOHEADER2   bih2;
    22472298    POINTL              aptl[4];
     
    23292380    }
    23302381
    2331     lHits = GpiWCBitBlt(hpsTarget,     // target HPS (bmp selected)
    2332                         hbmSource,
    2333                         4L,             // must always be 4
    2334                         &aptl[0],       // points array
    2335                         ROP_SRCCOPY,
    2336                         BBO_IGNORE);
     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);
    23372388                                // ignore eliminated rows or
    23382389                                // columns; useful for color
    2339 
    2340     return (lHits);
    23412390}
    23422391
     
    24592508 *
    24602509 *      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.
    24662517 *
    24672518 *      This also replaces gpihIcon2Bitmap, which wasn't quite
     
    27342785                           LONG cy)         // in: bitmap height
    27352786{
    2736     return (gpihCreateXBitmap2(hab,
    2737                                cx,
    2738                                cy,
    2739                                0,
    2740                                0));
     2787    return gpihCreateXBitmap2(hab,
     2788                              cx,
     2789                              cy,
     2790                              0,
     2791                              0);
    27412792}
    27422793
     
    27442795 *@@ gpihCreateXBitmap:
    27452796 *      creates an XBitmap, which is returned in an
    2746  *      _XBITMAP structure.
     2797 *      XBITMAP structure.
    27472798 *
    27482799 *      The problem with all the GPI bitmap functions
     
    28252876    }
    28262877
    2827     return (pbmp);
     2878    return pbmp;
    28282879}
    28292880
     
    28492900    GpiSetBitmap(pbmp->hpsMem, NULLHANDLE);
    28502901
    2851     return (hbm);
     2902    return hbm;
    28522903}
    28532904
     
    29352986        aptl[2].y = prcl->yBottom;
    29362987
    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))
    29442994        {
    29452995            // error during bitblt:
     
    29482998    }
    29492999
    2950     return (pBmp);
    2951 }
    2952 
     3000    return pBmp;
     3001}
     3002
  • trunk/src/helpers/nls.c

    r185 r190  
    198198 *
    199199 *@@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
    200202 */
    201203
     
    203205{
    204206    PCSZ    p2;
    205     ULONG   ulDBCS;
     207    ULONG   ulDBCSType = TYPE_SBCS;
    206208
    207209    if (!nlsDBCS())
     
    209211        return strchr(p, c);
    210212
     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]
    211244    // we're on DBCS:
    212245    for (p2 = p;
     
    228261        }
    229262    }
     263    */
    230264
    231265    return NULL;
     
    240274 *
    241275 *@@added V0.9.19 (2002-06-13) [umoeller]
     276 *@@changed V0.9.20 (2002-07-22) [lafaix]: optimized
    242277 */
    243278
    244279PSZ nlsrchr(PCSZ p, char c)
    245280{
    246     PCSZ    p2;
    247     ULONG   ulDBCS,
    248             ulLength;
     281    PCSZ    p2,
     282            pLast = NULL;
     283    ULONG   ulDBCSType = TYPE_SBCS;
    249284
    250285    if (!nlsDBCS())
     
    253288
    254289    // 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    /*
    255320    ulLength = strlen(p);
    256321    for (p2 = p + ulLength - 1;
     
    274339
    275340    return NULL;
     341    */
    276342}
    277343
  • trunk/src/helpers/tmsgfile.c

    r169 r190  
    105105/*
    106106 *@@ 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.
    107111 *
    108112 *@@added V0.9.16 (2001-10-08) [umoeller]
     
    111115typedef struct _MSGENTRY
    112116{
    113     TREE    Tree;               // ulKey points to strID.psz
    114     XSTRING strID;              // message ID
    115     ULONG   ulOfsText;          // offset of start of text (in C-format buffer)
    116     ULONG   cbText;             // length of text in msg file
     117    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
    117121} MSGENTRY, *PMSGENTRY;
    118122
     
    143147 *
    144148 *@@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
     152APIRET LoadAndCompile(PTMFMSGFILE pTmf,     // in: TMF struct to set up
     153                      PXFILE pFile)         // in: opened XFILE for msg file
    148154{
    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
    155163    {
    156164        // file loaded:
     
    162170                ulEndMarkerLength = strlen(G_pcszEndMarker);
    163171
     172        XSTRING strContents;
     173
    164174        // 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
    168182
    169183        // convert to plain C format
    170         xstrConvertLineFormat(&pFile->strContent,
     184        /* xstrConvertLineFormat(&pTmf->strContent,
    171185                              CRLF2LF);
     186        */
    172187
    173188        // kick out all the comments
    174         while (pStartOfMarker = strstr(pFile->strContent.psz, "\n;"))
     189        /*
     190        while (pStartOfMarker = strstr(pTmf->strContent.psz, "\n;"))
    175191        {
    176192            // copy the next line over this
    177193            PCSZ pEOL = strhFindEOL(pStartOfMarker + 2, NULL);
    178             xstrrpl(&pFile->strContent,
     194            xstrrpl(&pTmf->strContent,
    179195                    // ofs of first char to replace: "\n;"
    180                     pStartOfMarker - pFile->strContent.psz,
     196                    pStartOfMarker - pTmf->strContent.psz,
    181197                    // no. of chars to replace:
    182198                    pEOL - pStartOfMarker,
     
    186202                    0);
    187203        }
     204        */
    188205
    189206        // free excessive memory
    190         xstrShrink(&pFile->strContent);
    191 
    192         pStartOfFile = pFile->strContent.psz;
     207        // xstrShrink(&pTmf->strContent);
     208
     209        pStartOfFile = strContents.psz;
    193210
    194211        // go build a tree of all message IDs...
     
    205222            // search next start marker
    206223            PCSZ pStartOfNextMarker = strstr(pStartOfMsgID + 1,
    207                                              G_pcszStartMarker);
     224                                             G_pcszStartMarker);    // "\n<--"
    208225            // and the end-marker
    209226            PCSZ pEndOfMarker = strstr(pStartOfMsgID + 1,
    210                                        G_pcszEndMarker);
     227                                       G_pcszEndMarker);              // "-->:"
    211228
    212229            PMSGENTRY pNew;
     
    236253            {
    237254                // 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;
    240258
    241259                ZERO(pNew);
     
    253271                    pStartOfText++;
    254272
    255                 // store start of text
     273                // store offset of start of text
    256274                pNew->ulOfsText = pStartOfText - pStartOfFile;
    257275
    258276                // check if there's a comment before the
    259277                // next item
    260                 /* if (pNextComment = strstr(pStartOfText, "\n;"))
     278                if (pNextComment = strstr(pStartOfText, "\n;"))
    261279                {
    262280                    if (    (!pStartOfNextMarker)
    263281                         || (pNextComment < pStartOfNextMarker)
    264282                       )
    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                }
    273293                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);
    276302
    277303                // remove trailing newlines
    278304                while (    (pNew->cbText)
    279                         && (pStartOfText[pNew->cbText-1] == '\n')
     305                        && (    (pStartOfText[pNew->cbText - 1] == '\n')
     306                             || (pStartOfText[pNew->cbText - 1] == '\r')
     307                           )
    280308                      )
    281309                    (pNew->cbText)--;
    282310
    283311                // store this thing
    284                 if (!treeInsert(&pFile->IDsTreeRoot,
     312                if (!treeInsert(&pTmf->IDsTreeRoot,
    285313                                NULL,
    286314                                (TREE*)pNew,
    287315                                treeCompareStrings))
    288316                    // successfully inserted:
    289                     (pFile->cIDs)++;
     317                    (pTmf->cIDs)++;
    290318            }
    291319
     
    293321            pStartOfMarker = pStartOfNextMarker;
    294322        } // end while (    (pStartOfMarker) ...
    295     } // end else if (!(pFile = NEW(TMFMSGFILE)))
     323
     324        free(pszContent);
     325
     326    } // end else if (!(pTmf = NEW(TMFMSGFILE)))
    296327
    297328    return arc;
     
    318349 *
    319350 *@@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
    320352 */
    321353
     
    325357    APIRET arc;
    326358
    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)))
    332365    {
    333366        // create a TMFMSGFILE entry
    334         PTMFMSGFILE pFile;
    335         if (!(pFile = NEW(TMFMSGFILE)))
     367        PTMFMSGFILE pTmf;
     368        if (!(pTmf = NEW(TMFMSGFILE)))
    336369            arc = ERROR_NOT_ENOUGH_MEMORY;
    337370        else
    338371        {
    339             ZERO(pFile);
    340             pFile->pszFilename = strdup(pcszMessageFile);
     372            ZERO(pTmf);
     373            pTmf->pszFilename = strdup(pcszMessageFile);
    341374
    342375            // TMFMSGFILE created:
    343             if (!(arc = LoadAndCompile(pFile)))
     376            if (!(arc = LoadAndCompile(pTmf, pFile)))
    344377            {
    345378                // 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                }
    352392            }
    353             else
     393
     394            if (arc)
    354395                // error:
    355                 tmfCloseMessageFile(&pFile);
     396                tmfCloseMessageFile(&pTmf);
    356397        }
     398
     399        doshClose(&pFile);
    357400    }
    358401
     
    370413 */
    371414
    372 static VOID FreeInternalMem(PTMFMSGFILE pFile)
     415static VOID FreeInternalMem(PTMFMSGFILE pTmf)
    373416{
    374417    LONG   cItems;
    375418    TREE**  papNodes;
    376419
    377     xstrClear(&pFile->strContent);
    378 
    379     if (cItems = pFile->cIDs)
     420    if (cItems = pTmf->cIDs)
    380421    {
    381         if (papNodes = treeBuildArray(pFile->IDsTreeRoot,
     422        if (papNodes = treeBuildArray(pTmf->IDsTreeRoot,
    382423                                      &cItems))
    383424        {
     
    410451    if (ppMsgFile && *ppMsgFile)
    411452    {
    412         PTMFMSGFILE pFile = *ppMsgFile;
    413 
    414         if (pFile->pszFilename)
    415             free(pFile->pszFilename);
    416 
    417         FreeInternalMem(pFile);
    418 
    419         free(pFile);
     453        PTMFMSGFILE pTmf = *ppMsgFile;
     454
     455        if (pTmf->pszFilename)
     456            free(pTmf->pszFilename);
     457
     458        FreeInternalMem(pTmf);
     459
     460        free(pTmf);
    420461        *ppMsgFile = NULL;
    421462
     
    453494 *@@added V0.9.16 (2001-10-08) [umoeller]
    454495 *@@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
    455497 */
    456498
     
    463505    APIRET arc = NO_ERROR;
    464506
    465     if (!pMsgFile)
     507    if (    (!pMsgFile)
     508         || (!pMsgFile->pszFilename)
     509       )
    466510        arc = ERROR_INVALID_PARAMETER;
    467511    else
    468512    {
    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)))
    477520        {
    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))))
    483529            {
    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                }
    489543            }
    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)
    499546            {
    500                 // copy the raw string to the output buffer
    501                 xstrcpy(pstr,
    502                         pMsgFile->strContent.psz + pEntry->ulOfsText,
    503                         pEntry->cbText);
    504 
    505                 // now replace strings from the table
    506                 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
    507554                {
    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)))
    513565                    {
    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                        }
    522595                    }
    523596                }
    524597            }
    525             else
    526                 arc = ERROR_MR_MID_NOT_FOUND;
     598
     599            doshClose(&pFile);
    527600        }
    528601    }
Note: See TracChangeset for help on using the changeset viewer.