home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tvos200.zip / TVISION / OS2STUFF.CPP < prev    next >
C/C++ Source or Header  |  1995-04-25  |  18KB  |  614 lines

  1. /*
  2.  *  os2stuff.cpp:   OS/2 base mode translation & helper calls.
  3.  *  ==========================================================
  4.  *  (C)1995 F.Jalvingh; Public domain.
  5.  *
  6.  *  $Header$
  7.  *
  8.  *  $Log$
  9.  */
  10. #define INCL_OS2
  11. #define INCL_BASE
  12. #define INCL_SUB
  13. #define INCL_DOSFILEMGR
  14. #define INCL_DOSMISC
  15. #include    "ttypes.h"
  16. #include    <tvision/tvosdef.h>
  17. #include    <cpl/compiler.h>
  18. #include    <cpl/osdefs.h>
  19.  
  20. #include    <string.h>
  21.  
  22.  
  23.  
  24. void MemCpyW(ushort *dest, ushort *src, ushort count)
  25. {
  26.     while(count-- > 0)
  27.         *dest++ = *src++;
  28. }
  29.  
  30.  
  31. /****************************************************************************/
  32. /*                                                                          */
  33. /*  CODING: Timer interface.                                                */
  34. /*                                                                          */
  35. /****************************************************************************/
  36. /*
  37.  *  osTimeGetRunning() returns the current millisecond time for every OS.
  38.  */
  39. ulong osTimeGetRunning(void)
  40. {
  41. #if defined(__OS2__)
  42. # if defined(__32BITS__)
  43.     ulong       errc;
  44.     ulong       msecs;
  45.  
  46.     errc= DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msecs, sizeof(msecs));
  47.     if(errc != 0) return 0;
  48.     return msecs;
  49. # else
  50.     /*
  51.      *  For OS/2 1.xx get the Global Info Segment ONCE, then use it..
  52.      */
  53.     SEL     gsel, lsel;
  54.  
  55.     if(tiGis == NULL)
  56.     {
  57.         DosGetInfoSeg(&gsel, &lsel);
  58.         tiGis   = MAKEPGINFOSEG(gsel);
  59.     }
  60.     return tiGis->msecs;
  61. # endif
  62. #elif defined(__MSDOS__)
  63.     return biostime(0, 0) * 55ul;
  64. #endif
  65. }
  66.  
  67.  
  68. /****************************************************************************/
  69. /*                                                                          */
  70. /*  CODING: Keyboard interface routines.                                    */
  71. /*                                                                          */
  72. /****************************************************************************/
  73. /*
  74.  *  This interface is made for OS/2, and allows entry of diacriticals by
  75.  *  pressing CTRL-2, followed by pressing two compound characters. For instance,
  76.  *  pressing CTRL-2 c , will result in the ç character.
  77.  */
  78. /*--------------------------------------------------------------------------*/
  79. /*  STRUCTURES: Diacritical Key translation table.                          */
  80. /*--------------------------------------------------------------------------*/
  81. struct KeyPair
  82. {
  83.     unsigned char       kp_c1, kp_c2, kp_cu;
  84. };
  85.  
  86.  
  87. /*--------------------------------------------------------------------------*/
  88. /*  STATIC GLOBALS: Diacritical key translation table.                      */
  89. /*--------------------------------------------------------------------------*/
  90. static struct KeyPair   Pair_ar[]   =
  91. {
  92.     {'c', ',', 0x87},             // c cedille,
  93.     {'C', ',', 0x80},             // C cedille,
  94.     {'u', '"', 0x81},             // u umlaud
  95.     {'U', '"', 0x9a},             // U umlaud
  96.     {'e', 0x27,0x82},             // e accent grave,
  97.     {'E', 0x27,0x90},             // E accent grave,
  98.     {'a', '^', 0x83},             // A accent circonflex,
  99.     {'a', '"', 0x84},             // a trema,
  100.     {'A', '"', 0x8e},             // A trema,
  101.     {'a', '`', 0x85},             // A accent aigu
  102.     {'a', 'o', 0x86},             // a with o above,
  103.     {'A', 'o', 0x8F},             // A with o above,
  104.     {'e', '^', 0x88},             // e accent circonflex,
  105.     {'e', '"', 0x89},             // e trema,
  106.     {'e', '`', 0x8a},             // e accent aigu,
  107.     {'i', '"', 0x8b},             // i trema,
  108.     {'i', '^', 0x8c},             // i accent circonflex,
  109.     {'i', '`', 0x8d},             // i accent aigu,
  110.     {'a', 'e', 0x91},             // ae
  111.     {'A', 'E', 0x92},             // AE
  112.     {'o', '^', 0x93},             // o accent circonflex,
  113.     {'o', '"', 0x94},             // o trema,
  114.     {'O', '"', 0x99},             // O trema,
  115.     {'o', '`', 0x95},             // o accent aigu,
  116.     {'u', '^', 0x96},             // u accent circonflex,
  117.     {'u', '`', 0x97},             // u accent aigu,
  118.     {'y', '"', 0x98},             // Dutch 'lange ij'
  119.     {'c', '|', 0x9b},             // c with |
  120.     {'L', '^', 0x9c},             // Pound sign
  121.  
  122.     {'Y', '=', 0x9d},             // Yen symbol?
  123.     {'P', 't', 0x9e},             // Pt
  124.     {'p', 't', 0x9e},             // Idem,
  125.     {'f', 'f', 0x9f},             // Dutch florin symbol,
  126.     {'f', 'l', 0x9f},             // Idem,
  127.     {'a', 0x27,0x0a0},            // a accent grave,
  128.     {'i', 0x27,0x0a1},            // i accent grave,
  129.     {'o', 0x27,0x0a2},            // o accent grave,
  130.     {'u', 0x27,0x0a3},            // u accent grave,
  131.     {'n', '~', 0x0a4},            // n ma(n)ana,
  132.     {'N', '~', 0x0a5},            // N ma(N)ana,
  133.     {'a', '-', 0x0a6},            // High a with - below,
  134.     {'o', '-', 0x0a7},            // as above, with o,
  135.     {'?', '?', 0x0a8},            // Query sign opposite dir,
  136.     {'1', '2', 0x0ab},            // 1/2
  137.     {'1', '4', 0x0ac},            // 1/4
  138.     {'!', '!', 0x0ad},            // Exclamation marker opposite dir.
  139.     {'<', '<', 0x0ae},            // <<
  140.     {'>', '>', 0x0af},            // >>
  141.  
  142.     {0, 0, 0}
  143. };
  144.  
  145. static HKBD     hKbd = (HKBD)0xffff;
  146. static int      TwoKey;                             /* NZ if in twokey mode, */
  147. static ushort   CombKey;                            /* Key to be combined (1st one of TwoKey) */
  148. ushort          (*sv_kbLink)(ushort key);
  149.  
  150.  
  151. /*
  152.  *  CheckOpenKbd() ensures that a keyboard handle's open.
  153.  */
  154. static void CheckOpenKbd(void)
  155. {
  156.     if(hKbd == 0xffff)
  157.     {
  158. #if 0
  159.         /**** Open the keyboard..   ****/
  160.         KbdOpen(&hKbd);            /* Open keybd -> MUST(!) work */
  161.         KbdGetFocus(IO_WAIT, hKbd);
  162. #else
  163.         hKbd = 0;
  164. #endif
  165.     }
  166. }
  167.  
  168.  
  169. /*
  170.  *  TransKey() translates a keycode passed to an internal code.
  171.  */
  172. static ushort TransKey(KBDKEYINFO *ki)
  173. {
  174. #if 0
  175.     if(ki->chChar != 0 && ki->chChar != 0xe0) return (ushort)(uchar)ki->chChar;
  176.  
  177.     /**** Is extended code...   ****/
  178.     return (ushort)(uchar)ki->chScan << 8;
  179. #else
  180.     if(ki->chChar == 0xe0)
  181.         return ushort ((uchar)ki->chScan << 8);
  182.     return ushort( (((uchar)ki->chScan) << 8) | ushort(ki->chChar));
  183. #endif
  184. }
  185.  
  186.  
  187. /*
  188.  *  TransDbl() translates a diacritical key code (one starting with CTRL-2).
  189.  */
  190. static ushort TransDbl(ushort key)
  191. {
  192.     struct KeyPair  *kp;
  193.  
  194.     if(TwoKey)                      /* Are we in twokey mode ? */
  195.     {
  196.         /**** Is this the 2nd in a row? ****/
  197.         if(CombKey == 0)
  198.         {
  199.             CombKey = key;          /* Save 1st key pressed, */
  200.             return 0;
  201.         }
  202.  
  203.         /**** This is the 2nd key! Find the combination in the key table.. ****/
  204.         for(kp = Pair_ar; kp->kp_c1 != 0; kp++)
  205.         {
  206.             if( (kp->kp_c1 == key && kp->kp_c2 == CombKey) ||
  207.                 (kp->kp_c2 == key && kp->kp_c1 == CombKey))
  208.             {
  209.                 TwoKey = FALSE;     /* End of TwoKey indicator, */
  210.                 return kp->kp_cu;
  211.  
  212.             }
  213.         }
  214.  
  215.         /**** Unknown diacritical key-> Beep, then exit.. ****/
  216.         return 0;
  217.     }
  218.     else if(key == 0x0300)          // CTRL-2 key
  219.     {
  220.         TwoKey  = TRUE;             /* Set 2key indicator, */
  221.         CombKey = 0;                /* No combinator known, */
  222.         return 0;                   /* No key pressed, */
  223.     }
  224.     else
  225.         return key;                 /* Else return key pressed as-is. */
  226. }
  227.  
  228.  
  229. /*
  230.  *  kbReadF() reads the keyboard quicky and returns a keycode when a key is
  231.  *  pressed or ZERO if no key is buffered. It does not translate the key in any
  232.  *  way.
  233.  */
  234. static ushort kbReadF(ushort *kstate)
  235. {
  236.     KBDKEYINFO  kki;
  237.  
  238.     CheckOpenKbd();                                 /* Make sure keybd is open, */
  239.  
  240.     KbdGetFocus(IO_WAIT, hKbd);                     /* Get this keyboard, */
  241.     if(KbdPeek(&kki, hKbd) != 0)
  242.     {
  243.         KbdFreeFocus(hKbd);                         /* Release focus, */
  244.         return 0;
  245.     }
  246.     KbdFreeFocus(hKbd);
  247.  
  248.     if(kki.fbStatus != 0)
  249.     {
  250.         if(KbdCharIn(&kki, IO_WAIT, hKbd) == 0)
  251.         {
  252.             if(kki.fbStatus != 0)
  253.             {
  254.                 if(kstate != NULL)
  255.                     *kstate = kki.fsState;          // Save current keybd state,
  256.                 return TransKey(&kki);
  257.             }
  258.         }
  259.     }
  260. #if !defined(__32BITS__)
  261.     DosSleep(25);
  262. #endif
  263.     return 0;
  264. }
  265.  
  266.  
  267. #if 0
  268. /*
  269.  *  kbRead() reads the keyboard and waits till a key is pressed. It does NOT
  270.  *  perform any translation or other auxiliary action.
  271.  */
  272. static ushort kbRead(void)
  273. {
  274.     KBDKEYINFO  kki;
  275.  
  276.     CheckOpenKbd();                                  /* Make sure keybd is open, */
  277.  
  278.     KbdGetFocus(IO_WAIT, hKbd);                     /* Get this keyboard, */
  279.     if(KbdCharIn(&kki, IO_WAIT, hKbd) != 0)
  280.     {
  281.         KbdFreeFocus(hKbd);
  282.         return 0;                                   /* No key <> error! */
  283.     }
  284.     KbdFreeFocus(hKbd);
  285.     return TransKey(&kki);
  286. }
  287. #endif
  288.  
  289.  
  290. /*
  291.  *  osKeyFast() checks for a key quickly. It is the main entry point, it
  292.  *  also translates keycodes when TwoKey (CTRL-2) is pressed AND it calls the
  293.  *  sv_kbLink routine(s).
  294.  */
  295. ushort osKeyFast(ushort *kstate)
  296. {
  297.     ushort       key;
  298.  
  299.     key = kbReadF(kstate);                          /* Read keyboard quickly, */
  300.     if(key != 0)                                    /* Key has been read? */
  301.         key = TransDbl(key);                        /* Translate if double key, */
  302.  
  303.     /**** Right. If there's a keyboard handler call it, ****/
  304.     if(sv_kbLink) return (*sv_kbLink)(key);         /* Call handler and return, */
  305.     return key;
  306. }
  307.  
  308.  
  309. /*
  310.  *  osKeyState() gets the current control key state.
  311.  */
  312. ushort osKeyState(void)
  313. {
  314.     KBDINFO     ki;
  315.  
  316.     if(KbdGetStatus(&ki, hKbd) != 0) return 0;      // Return no state on error.
  317.     return ki.fsState;
  318. }
  319.  
  320.  
  321. #if defined(__WATCOMC__) || defined(__ICC__)
  322.  
  323.  
  324.  
  325. int setdisk(int drive)
  326. {
  327. #if defined(__32BITS__)
  328.     return (int)DosSetDefaultDisk((ULONG)drive + 1);
  329. #else
  330.     return (int)DosSelectDisk((USHORT)drive + 1);  /* Bcc getdisk: 'A' = 0; MSC DosSelectdisk: 'A' = 1 */
  331. #endif
  332. }
  333.  
  334. int getdisk(void)
  335. {
  336. #ifdef  __32BITS__
  337.     ULONG   drive, numdrives;
  338.  
  339.     DosQueryCurrentDisk(&drive, &numdrives);
  340. #else
  341.     USHORT  drive;
  342.     ULONG   numdrives;
  343.  
  344.     DosQCurDisk(&drive, &numdrives);
  345. #endif
  346.     return (int)drive - 1;
  347.  
  348. }
  349.  
  350.  
  351.  
  352. int getcurdir(int drive, char *dir)
  353. {
  354. #ifdef __32BITS__
  355.     ULONG   bytes;
  356.  
  357.     bytes   = 0;
  358.     DosQueryCurrentDir(drive, NULL, &bytes);
  359.     if(bytes > OS_MAXPATH) return -1;
  360.     DosQCurDir(drive, (PBYTE) dir, &bytes);
  361.     return 0;
  362. #else
  363.     USHORT  bytes;
  364.  
  365.     bytes   = 0;
  366.     DosQCurDir(drive, NULL, &bytes);
  367.     if(bytes > OS_MAXPATH) return -1;
  368.     DosQCurDir(drive, dir, &bytes);
  369.     return 0;
  370. #endif
  371. }
  372.  
  373. static void CopyIt(char *dst, const char *src, unsigned maxlen)
  374. {
  375.     if (dst)
  376.     {
  377.         if(strlen(src) >= maxlen)
  378.         {
  379.             strncpy(dst, src, maxlen);
  380.             dst[maxlen] = 0;
  381.         }
  382.         else
  383.             strcpy(dst, src);
  384.     }
  385. }
  386.  
  387. static int DotFound(char *pb)
  388. {
  389.     if (*(pb-1) == '.')
  390.         pb--;
  391.  
  392.     switch (*--pb)
  393.     {
  394.         case ':'  : if (*(pb-2) != '\0') break;
  395.         case '/'  :
  396.         case '\\' :
  397.         case '\0' : return 1;
  398.     }
  399.  
  400.     return 0;
  401. }
  402.  
  403.  
  404.  
  405.  
  406. int fnsplit(const char *pathp, char *drivep, char *dirp, char *namep, char *extp)
  407. {
  408.     register char   *pb;
  409.     register int    wrk;
  410.     int     ret;
  411.     char    buf[OS_MAXPATH+2];
  412.  
  413.     /**** Set all string to default value zero ****/
  414.     ret = 0;
  415.     if (drivep) *drivep = 0;
  416.     if (dirp)   *dirp   = 0;
  417.     if (namep)  *namep  = 0;
  418.     if (extp)   *extp   = 0;
  419.  
  420.     /**** Copy filename into template up to MAXPATH characters ****/
  421.     pb = buf;
  422.     while (*pathp == ' ') pathp++;
  423.  
  424.     if ((wrk = strlen(pathp)) > OS_MAXPATH)
  425.         wrk = OS_MAXPATH;
  426.  
  427.     *pb++ = 0;
  428.     strncpy(pb, pathp, wrk);
  429.     *(pb += wrk) = 0;
  430.  
  431.     /**** Split the filename and fill corresponding nonzero pointers ****/
  432.     wrk = 0;
  433.     for (;;)
  434.     {
  435.         switch (*--pb)
  436.         {
  437.             case '.'  : if (!wrk && (*(pb+1) == '\0')) wrk = DotFound(pb);
  438.                         if ((!wrk) && ((ret & EXTENSION) == 0))
  439.                         {
  440.                             ret |= EXTENSION;
  441.                             CopyIt(extp, pb, OS_MAXEXT - 1);
  442.                             *pb = 0;
  443.                         }
  444.                         continue;
  445.  
  446.             case ':'  : if (pb != &buf[2]) continue;
  447.  
  448.             case '\0' : if (wrk)
  449.                         {
  450.                             if (*++pb)
  451.                                 ret |= DIRECTORY;
  452.                             CopyIt(dirp, pb, OS_MAXPATH - 1);
  453.                             *pb-- = 0;
  454.                             break;
  455.                         }
  456.  
  457.             case '/'  :
  458.             case '\\' : if (!wrk)
  459.                         {
  460.                             wrk++;
  461.                             if (*++pb)
  462.                                 ret |= FILENAME;
  463.                             CopyIt(namep, pb, OS_MAXFILE - 1);
  464.                             *pb-- = 0;
  465.                             if (*pb == 0 || (*pb == ':' && pb == &buf[2]))
  466.                                 break;
  467.                         }
  468.                         continue;
  469.  
  470.             case '*'  :
  471.             case '?'  : if (!wrk) ret |= WILDCARDS;
  472.  
  473.             default   : continue;
  474.         }
  475.  
  476.         break;
  477.     }
  478.  
  479.     if (*pb == ':')
  480.     {
  481.         if (buf[1])
  482.             ret |= DRIVE;
  483.         CopyIt(drivep, &buf[1], OS_MAXDRIVE - 1);
  484.     }
  485.  
  486.     return (ret);
  487. }
  488.  
  489. #include    <errno.h>
  490.  
  491. void fnmerge(char *out, char const *drive, char const *dir, char const *name, char const *ext)
  492. {
  493.     *out    = '\0';
  494.     if(*drive != '\0') strcpy(out, drive);
  495.     if(*dir   != '\0') strcat(out, dir);
  496.     if(*name  != '\0') strcat(out, name);
  497.     if(*ext   != '\0') strcat(out, ext);
  498. }
  499.  
  500. /*
  501.  *      findfirst() searches a '1st' file..
  502.  */
  503. int findfirst(const char *path, struct ffblk *ff, int attrib)
  504. {
  505. #ifdef __32BITS__
  506.     FILEFINDBUF3    fb;
  507.     HDIR            hdir = 0xffff;      /* HDIR_SYSTEM */
  508.     ULONG           count = 1,          /* File count, */
  509.                     err;
  510.  
  511.     err = DosFindFirst((PSZ)path, &hdir, attrib, &fb, sizeof(fb), &count, 1l);
  512.     if(err)
  513.     {
  514.         /**** Translate error.. ****/
  515.         switch(err)
  516.         {
  517.             case ERROR_PATH_NOT_FOUND:  errno = ENOENT; break;
  518.             case ERROR_NO_MORE_FILES:   errno = EMFILE; break;
  519.             default:                    errno = EINVAL; break;
  520.         }
  521.         return -1;
  522.     }
  523. #else
  524.     FILEFINDBUF     fb;
  525.     HDIR            hdir = 0xffff;      /* HDIR_SYSTEM */
  526.     USHORT          count = 1,          /* File count, */
  527.                     err;
  528.  
  529.     err = DosFindFirst(path, &hdir, attrib, &fb, sizeof(fb), &count, 0l);
  530.     if(err)
  531.     {
  532.         /**** Translate error.. ****/
  533.         switch(err)
  534.         {
  535.             case ERROR_PATH_NOT_FOUND:  errno = ENOENT; break;
  536.             case ERROR_NO_MORE_FILES:   errno = EMFILE; break;
  537.             default:                    errno = EINVAL; break;
  538.         }
  539.         return -1;
  540.     }
  541. #endif
  542.  
  543.     /**** Translate find buffer..   ****/
  544.     memcpy(ff->ff_reserved, &hdir, sizeof(hdir));   /* Save handle, */
  545.     ff->ff_attrib   = (char)fb.attrFile;        /* Copy file attributes, */
  546.     memcpy(&ff->ff_ftime, &fb.ftimeLastWrite, sizeof(ff->ff_ftime));
  547.     memcpy(&ff->ff_fdate, &fb.fdateLastWrite, sizeof(ff->ff_fdate));
  548.     ff->ff_fsize    = fb.cbFile;
  549.     memcpy(ff->ff_name, fb.achName, sizeof(ff->ff_name));
  550.     return 0;
  551. }
  552.  
  553.  
  554. /*
  555.  *      findnext() finds the next file..
  556.  */
  557. int findnext(struct ffblk *ff)
  558. {
  559. #ifdef __32BITS__
  560.     FILEFINDBUF3    fb;
  561.     HDIR            hdir;
  562.     ULONG           count = 1,
  563.                     err;
  564.  
  565.     /**** Get HDIR from reserved area,  ****/
  566.     memcpy(&hdir, ff->ff_reserved, sizeof(hdir));
  567.     err = DosFindNext(hdir, &fb, sizeof(fb), &count);
  568.     if(err != 0)
  569.     {
  570.         switch(err)
  571.         {
  572.             case ERROR_PATH_NOT_FOUND:  errno = ENOENT; break;
  573.             case ERROR_NO_MORE_FILES:   errno = EMFILE; break;
  574.             default:                    errno = EINVAL; break;
  575.         }
  576.         return -1;
  577.     }
  578. #else
  579.     FILEFINDBUF     fb;
  580.     HDIR            hdir;
  581.     USHORT          count = 1,
  582.                     err;
  583.  
  584.     /**** Get HDIR from reserved area,  ****/
  585.     memcpy(&hdir, ff->ff_reserved, sizeof(hdir));
  586.     err = DosFindNext(hdir, &fb, sizeof(fb), &count);
  587.     if(err != 0)
  588.     {
  589.         switch(err)
  590.         {
  591.             case ERROR_PATH_NOT_FOUND:  errno = ENOENT; break;
  592.             case ERROR_NO_MORE_FILES:   errno = EMFILE; break;
  593.             default:                    errno = EINVAL; break;
  594.         }
  595.         return -1;
  596.     }
  597. #endif
  598.  
  599.     /**** Copy..    ****/
  600.     ff->ff_attrib   = (char)fb.attrFile;        /* Copy file attributes, */
  601.     memcpy(&ff->ff_ftime, &fb.ftimeLastWrite, sizeof(ff->ff_ftime));
  602.     memcpy(&ff->ff_fdate, &fb.fdateLastWrite, sizeof(ff->ff_fdate));
  603.     ff->ff_fsize    = fb.cbFile;
  604.     memcpy(ff->ff_name, fb.achName, sizeof(ff->ff_name));
  605.     return 0;
  606. }
  607.  
  608.  
  609.  
  610.  
  611. #endif
  612.  
  613.  
  614.