Ignore:
Timestamp:
Apr 2, 2001, 12:38:55 PM (24 years ago)
Author:
umoeller
Message:

Dialog mgr.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/gpih.c

    r46 r53  
    3333    // as unsigned char
    3434
     35#define INCL_DOSSEMAPHORES
    3536#define INCL_DOSERRORS
    3637
    3738#define INCL_WINWINDOWMGR
     39#define INCL_WINMESSAGEMGR
    3840#define INCL_WINPOINTERS
    3941#define INCL_WINSYS
     
    9294 *      By contrast, the GpiBox expects an inclusive-inclusive rectangle.
    9395 */
     96
     97/* ******************************************************************
     98 *
     99 *   Global variables
     100 *
     101 ********************************************************************/
     102
     103static HMTX     G_hmtxLCIDs = NULLHANDLE;
    94104
    95105/* ******************************************************************
     
    492502
    493503/*
     504 *@@ gpihLockLCIDs:
     505 *      requests the mutex for serializing the
     506 *      lcids.
     507 *
     508 *      With GPI, lcids are a process-wide resource and not
     509 *      guaranteed to be unique. In the worst case, while your
     510 *      font routines are running, another thread modifies the
     511 *      lcids and you get garbage. If your fonts suddenly
     512 *      turn to "System Proportional", you know this has
     513 *      happened.
     514 *
     515 *      As a result, whenever you work on lcids, request this
     516 *      mutex during your processing. If you do this consistently
     517 *      across all your code, you should be safe.
     518 *
     519 *      gpihFindFont uses this mutex. If you call GpiCreateLogFont
     520 *      yourself somewhere, do this after you called this function.
     521 *
     522 *      Call gpihUnlockLCIDs to unlock.
     523 *
     524 *@@added V0.9.9 (2001-04-01) [umoeller]
     525 */
     526
     527BOOL gpihLockLCIDs(VOID)
     528{
     529    BOOL brc = FALSE;
     530
     531    if (G_hmtxLCIDs == NULLHANDLE)
     532        // first call: create
     533        brc = !DosCreateMutexSem(NULL,
     534                                 &G_hmtxLCIDs,
     535                                 0,
     536                                 TRUE);     // request!
     537    else
     538        // subsequent calls: request
     539        brc = !WinRequestMutexSem(G_hmtxLCIDs, SEM_INDEFINITE_WAIT);
     540
     541    return (brc);
     542}
     543
     544/*
     545 *@@ UnlockLCIDs:
     546 *      releases the mutex for serializing the
     547 *      lcids.
     548 *
     549 *@@added V0.9.9 (2001-04-01) [umoeller]
     550 */
     551
     552VOID gpihUnlockLCIDs(VOID)
     553{
     554    DosReleaseMutexSem(G_hmtxLCIDs);
     555}
     556
     557/*
    494558 *@@ gpihQueryNextLCID:
    495559 *      returns the next available lcid for the given HPS.
     
    498562 *      Gets called by gpihFindFont automatically.
    499563 *
    500  *      This is possibly the sickest code I've ever written.
    501  *
    502  *      Warning: This function is _not_ thread-safe.
    503  *      We use GpiQueryNumberSetIds to find out the no. of
    504  *      LCID's in use by the process. In the worst case,
    505  *      between that call and the call to GpiCreateLogFont,
    506  *      another font has been created, and you'll get garbage.
     564 *      WARNING: This function by itself is not thread-safe.
     565 *      See gpihLockLCIDs for how to serialize this.
    507566 *
    508567 *@@added V0.9.3 (2000-05-06) [umoeller]
     568 *@@changed V0.9.9 (2001-04-01) [umoeller]: removed all those sick sub-allocs
    509569 */
    510570
     
    524584    else
    525585    {
    526         #define GQNCL_BLOCK_SIZE 400*sizeof(LONG)
     586        // #define GQNCL_BLOCK_SIZE 400*sizeof(LONG)
     587
     588        PLONG  alTypes = NULL;  // object types
     589        PSTR8  aNames = NULL;   // font names
     590        PLONG  allcids = NULL;  // local identifiers
     591
     592        if (    (alTypes = (PLONG)malloc(lCount * sizeof(LONG)))
     593             && (aNames = (PSTR8)malloc(lCount * sizeof(STR8)))
     594             && (allcids = (PLONG)malloc(lCount * sizeof(LONG)))
     595           )
     596        {
     597            if (GpiQuerySetIds(hps,
     598                               lCount,
     599                               alTypes,
     600                               aNames,
     601                               allcids))
     602            {
     603                // FINALLY we have all the lcids in use.
     604                BOOL    fContinue = TRUE;
     605                lcidNext = 1;
     606
     607                // now, check if this lcid is in use already:
     608                while (fContinue)
     609                {
     610                    BOOL fFound = FALSE;
     611                    ULONG ul;
     612                    fContinue = FALSE;
     613                    for (ul = 0;
     614                         ul < lCount;
     615                         ul++)
     616                    {
     617                        if (allcids[ul] == lcidNext)
     618                        {
     619                            fFound = TRUE;
     620                            break;
     621                        }
     622                    }
     623
     624                    if (fFound)
     625                    {
     626                        // lcid found:
     627                        // try next higher one
     628                        lcidNext++;
     629                        fContinue = TRUE;
     630                    }
     631                    // else: return that one
     632                }
     633            }
     634        }
     635
     636        if (alTypes)
     637            free(alTypes);
     638        if (aNames)
     639            free(aNames);
     640        if (allcids)
     641            free(allcids);
     642
     643/*
    527644        PLONG   pBase;
    528 
    529645        APIRET  arc;
    530646
     
    612728            arc = DosFreeMem(pBase);
    613729        }
     730        */
    614731    }
    615732
     
    744861 *          certain point sizes only.
    745862 *
    746  *      4)  <B>Warning: This function is _not_ thread-safe.</B>
    747  *          Since logical font IDs are shared across the
    748  *          process, this function should _not_ be called
    749  *          from several threads at the same time.
     863 *      4)  Since logical font IDs are shared across the
     864 *          process, a mutex is requested while the lcids are
     865 *          being queried and/or manipulated. In other words,
     866 *          this func is now thread-safe (V0.9.9).
    750867 *
    751868 *          This calls gpihQueryNextFontID in turn to find the
    752869 *          next free lcid. See remarks there.
    753  *          If your fonts suddenly change to "System Proportional"
    754  *          in your application, you probably have a serialization
    755  *          problem.
    756  *
    757  *          To make this thread-safe, create your own wrapper
    758  *          function which calls this function while a mutex
    759  *          semaphore is held by the wrapper. Then use only
    760  *          the wrapper in your code.
    761870 *
    762871 *      <B>Font metrics:</B>
     
    793902 *@@changed V0.9.3 (2000-05-06) [umoeller]: usFormat didn't work; fixed
    794903 *@@changed V0.9.4 (2000-08-08) [umoeller]: added fFamily
     904 *@@changed V0.9.9 (2001-04-01) [umoeller]: made this thread-safe, finally
    795905 */
    796906
     
    9811091    free(pfm);
    9821092
    983     // new logical font ID: last used plus one
    984     lLCIDReturn = gpihQueryNextFontID(hps);
    985 
    986     GpiCreateLogFont(hps,
    987                      NULL,  // don't create "logical font name" (STR8)
    988                      lLCIDReturn,
    989                      &FontAttrs);
     1093    if (gpihLockLCIDs())        // V0.9.9 (2001-04-01) [umoeller]
     1094    {
     1095        // new logical font ID: last used plus one
     1096        lLCIDReturn = gpihQueryNextFontID(hps);
     1097
     1098        GpiCreateLogFont(hps,
     1099                         NULL,  // don't create "logical font name" (STR8)
     1100                         lLCIDReturn,
     1101                         &FontAttrs);
     1102
     1103        gpihUnlockLCIDs();
     1104    }
    9901105
    9911106    return (lLCIDReturn);
     
    10251140 *
    10261141 *@@added V0.9.0 [umoeller]
    1027  */
    1028 
    1029 LONG gpihFindPresFont(HWND hwnd,          // in: window to search for presparam
     1142 *@@changed V0.9.9 (2001-04-01) [umoeller]: now supporting NULLHANDLE hwnd
     1143 */
     1144
     1145LONG gpihFindPresFont(HWND hwnd,          // in: window to search for presparam or NULLHANDLE
    10301146                      BOOL fInherit,      // in: search parent windows too?
    10311147                      HPS hps,            // in: HPS for font selection
    1032                       PSZ pszDefaultFont, // in: default font if not found (i.e. "8.Helv")
     1148                      const char *pcszDefaultFont, // in: default font if not found (i.e. "8.Helv")
    10331149                      PFONTMETRICS pFontMetrics, // out: font metrics of created font (optional)
    10341150                      PLONG plSize)       // out: presparam's point size (optional)
    10351151{
    10361152    CHAR    szPPFont[200] = "";
    1037     PSZ     pszFontFound = 0;
     1153    const char *pcszFontFound = 0;
    10381154    CHAR    szFaceName[300] = "";
    10391155    ULONG   ulFontSize = 0;
    10401156
    1041     if (WinQueryPresParam(hwnd,
    1042                           PP_FONTNAMESIZE,          // first PP to query
    1043                           0,                        // second PP to query
    1044                           NULL,                     // out: which one is returned
    1045                           (ULONG)sizeof(szPPFont),  // in: buffer size
    1046                           (PVOID)&szPPFont,         // out: PP value returned
    1047                           (fInherit)
    1048                                ? 0
    1049                                : QPF_NOINHERIT))
     1157    if (    (hwnd)        // V0.9.9 (2001-04-01) [umoeller]
     1158         && (WinQueryPresParam(hwnd,
     1159                               PP_FONTNAMESIZE,          // first PP to query
     1160                               0,                        // second PP to query
     1161                               NULL,                     // out: which one is returned
     1162                               (ULONG)sizeof(szPPFont),  // in: buffer size
     1163                               (PVOID)&szPPFont,         // out: PP value returned
     1164                               (fInherit)
     1165                                    ? 0
     1166                                    : QPF_NOINHERIT))
     1167       )
    10501168        // PP found:
    1051         pszFontFound = szPPFont;
     1169        pcszFontFound = szPPFont;
    10521170    else
    1053         pszFontFound = pszDefaultFont;
    1054 
    1055     if (pszFontFound)
     1171        pcszFontFound = pcszDefaultFont;
     1172
     1173    if (pcszFontFound)
    10561174    {
    1057         PCHAR   pcDot = strchr(pszFontFound, '.');
     1175        const char *pcDot = strchr(pcszFontFound, '.');
    10581176        if (pcDot)
    10591177        {
    10601178            // _Pmpf(("Found font PP: %s", pszFontFound));
    1061             sscanf(pszFontFound, "%lu", &ulFontSize);
     1179            sscanf(pcszFontFound, "%lu", &ulFontSize);
    10621180            if (plSize)
    10631181                *plSize = ulFontSize;
Note: See TracChangeset for help on using the changeset viewer.