home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / fed0217s.zip / source / vio.cpp < prev   
C/C++ Source or Header  |  2001-11-06  |  22KB  |  837 lines

  1. /*
  2. ** Module   :VIO.C
  3. ** Abstract :Screen and keyboard I/O routines
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. **
  7. ** Log: Wed  29/01/1997       Created
  8. **      Sun  09/11/1997       Some minor changes and updates
  9. */
  10.  
  11. #include <string.h>
  12. #include <stdio.h>
  13.  
  14. #include <vio.h>
  15. #include <fio.h>
  16. #include <_ctype.h>
  17. #include <keynames.h>
  18. #include <version.h>
  19.  
  20. #include <pmproc.h>
  21.  
  22. #define ScreenOffset(Row,Col) (((Row) * Cols + (Col)) << 1)
  23.  
  24. #define ScreenPtr(Row,Col) \
  25.             ((((Row) * Cols + (Col)) << 1) < BufLen ? \
  26.             (&Screen[(((Row) * Cols + (Col)) << 1)]): \
  27.             0)
  28.  
  29.  
  30. BOOL (APIENTRY *_inCloseClipbrd)(HAB);
  31. HMQ  (APIENTRY *_inCreateMsgQueue)(HAB, LONG);
  32. BOOL (APIENTRY *_inDestroyMsgQueue)(HMQ);
  33. BOOL (APIENTRY *_inEmptyClipbrd)(HAB);
  34. HAB  (APIENTRY *_inInitialize)(ULONG);
  35. BOOL (APIENTRY *_inOpenClipbrd)(HAB);
  36. ULONG(APIENTRY *_inQueryClipbrdData)(HAB, ULONG);
  37. BOOL (APIENTRY *_inQueryClipbrdFmtInfo)(HAB, ULONG, PULONG);
  38. BOOL (APIENTRY *_inSetClipbrdData)(HAB, ULONG, ULONG, ULONG);
  39. BOOL (APIENTRY *_inTerminate)(HAB);
  40.  
  41. HSWITCH (APIENTRY *_inQuerySwitchHandle)(HWND, PID);
  42. ULONG (APIENTRY *_inQuerySwitchEntry)(HSWITCH, PSWCNTRL);
  43. ULONG (APIENTRY *_inChangeSwitchEntry)(HSWITCH, PSWCNTRL);
  44.  
  45. LONG (APIENTRY *_inQueryWindowText)(HWND, LONG, PCH);
  46. BOOL (APIENTRY *_inSetWindowText)(HWND, PCSZ);
  47.  
  48.  
  49. HAB hab;
  50. HMQ hmq;
  51. HWND hwndFrame;
  52. char cOldTitle[257];
  53. HSWITCH hSw;
  54. SWCNTRL swOldData = {0};
  55.  
  56. static int VioInitComplete = 0;
  57. static VIOCURSORINFO CUR_SAVE;
  58.  
  59. static void importKey(KeyInfo*, USHORT, USHORT);
  60.  
  61. KeyInfo kiLastKey;
  62.  
  63. int init_pm(int)
  64. {
  65.     PPIB pib;
  66.     PTIB tib;
  67.     APIRET rc;
  68.     HMODULE hMte = 0;
  69.     char loadErr[256];
  70.  
  71.     if(hab || hmq)
  72.         return 0;
  73.  
  74.     //Store startup directory
  75.     get_cur_dir(StartupDir);
  76.  
  77.     rc = DosGetInfoBlocks(&tib, &pib);
  78.     DD_TRACE("DosGetInfoBlocks",rc);
  79.  
  80.     rc = DosQueryModuleName(pib->pib_hmte, FED_MAXPATH, _cFedPATH);
  81.     DD_TRACE("DosQueryModuleName",rc);
  82.  
  83. //    rc = DosQueryModuleHandle("PMWIN", &hMte);
  84.  
  85. //    mutex   \SEM32\PMDRAG.SEM
  86.  
  87.     rc = 0;
  88.  
  89.     if(pib->pib_ultype < 2) //If this is an full screen session
  90.     {
  91.         HMTX hMtx = 0;
  92.  
  93.         rc = DosOpenMutexSem((PCH)"\\SEM32\\PMDRAG.SEM", &hMtx);
  94.  
  95.         if(!rc)
  96.             DosCloseMutexSem(hMtx);
  97.     }
  98.  
  99.     if(!rc)
  100.     {
  101.         pib->pib_ultype = 3;
  102.  
  103.         rc = DosLoadModule((PCH)loadErr, 256, (PCH)"PMWIN", &hMte);
  104.  
  105.         if(rc)
  106.             return 1;
  107.  
  108.         rc = DosQueryProcAddr(hMte, 707, 0, (PFN*)&_inCloseClipbrd);
  109.         rc = DosQueryProcAddr(hMte, 716, 0, (PFN*)&_inCreateMsgQueue);
  110.         rc = DosQueryProcAddr(hMte, 726, 0, (PFN*)&_inDestroyMsgQueue);
  111.         rc = DosQueryProcAddr(hMte, 733, 0, (PFN*)&_inEmptyClipbrd);
  112.         rc = DosQueryProcAddr(hMte, 763, 0, (PFN*)&_inInitialize);
  113.         rc = DosQueryProcAddr(hMte, 793, 0, (PFN*)&_inOpenClipbrd);
  114.         rc = DosQueryProcAddr(hMte, 806, 0, (PFN*)&_inQueryClipbrdData);
  115.         rc = DosQueryProcAddr(hMte, 807, 0, (PFN*)&_inQueryClipbrdFmtInfo);
  116.         rc = DosQueryProcAddr(hMte, 854, 0, (PFN*)&_inSetClipbrdData);
  117.         rc = DosQueryProcAddr(hMte, 888, 0, (PFN*)&_inTerminate);
  118.         rc = DosQueryProcAddr(hMte, 841, 0, (PFN*)&_inQueryWindowText);
  119.         rc = DosQueryProcAddr(hMte, 877, 0, (PFN*)&_inSetWindowText);
  120.  
  121.         rc = DosLoadModule((PCH)loadErr, 256, (PCH)"PMSHAPI", &hMte);
  122.  
  123.         if(rc)
  124.             return 1;
  125.  
  126.         rc = DosQueryProcAddr(hMte, 123, 0, (PFN*)&_inChangeSwitchEntry);
  127.         rc = DosQueryProcAddr(hMte, 124, 0, (PFN*)&_inQuerySwitchEntry );
  128.         rc = DosQueryProcAddr(hMte, 125, 0, (PFN*)&_inQuerySwitchHandle);
  129.  
  130.         hab = _inInitialize(0);
  131.         hmq = _inCreateMsgQueue(hab, 0);
  132.  
  133.         hSw = _inQuerySwitchHandle(0, pib->pib_ulpid);
  134.         if(hSw)
  135.         {
  136.             _inQuerySwitchEntry(hSw, &swOldData);
  137.             hwndFrame = swOldData.hwnd;
  138.  
  139.             if(hwndFrame)
  140.                 _inQueryWindowText(hwndFrame, sizeof(cOldTitle), (PCH)cOldTitle);
  141.         }
  142.  
  143.         return 0;
  144.     }
  145.     return 1;
  146. }
  147.  
  148. void deinit_pm(void)
  149. {
  150.     if(hwndFrame)
  151.         set_title(cOldTitle);
  152.     _inChangeSwitchEntry(hSw, &swOldData);
  153.  
  154.     if(hmq)
  155.         _inDestroyMsgQueue(hmq);
  156.     if(hab)
  157.         _inTerminate(hab);
  158. }
  159.  
  160. void set_title(char *title)
  161. {
  162.     if(hmq)
  163.     {
  164.         static char vTitle[FED_MAXPATH]="";
  165.         if(strcmp(vTitle, title))
  166.         {
  167.             SWCNTRL swData = swOldData;
  168.             strcpy(vTitle, title);
  169.             strncpy(swData.szSwtitle, title, MAXNAMEL);
  170.             _inChangeSwitchEntry(hSw, &swData);
  171.             _inSetWindowText(hwndFrame, (PCH)title);
  172.         }
  173.     }
  174. }
  175.  
  176. void vio_init(void)
  177. {
  178.     USHORT blen = 0;
  179.     ULONG badr = 0;
  180.     HKBD hKbd = 0;
  181.     VIOMODEINFO MI;
  182.     KBDINFO kbInfo;
  183.     APIRET rc;
  184.  
  185.     if(VioInitComplete)
  186.         return;
  187.  
  188.     memset(&MI, 0, sizeof(MI));
  189.  
  190.     MI.cb = sizeof(MI);
  191.     rc = VioGetMode(&MI, 0);
  192.     DD_TRACE("VioGetMode",rc);
  193.     VioGetBuf(&badr, &blen, 0);
  194.     DD_TRACE("VioGetBuf",rc);
  195.  
  196.     Rows = MI.row;
  197.     Cols = MI.col;
  198.  
  199.     Screen = (char *) (((badr >> 3) & 0xffff0000L) | (badr & 0xffffL));
  200.     BufLen = blen;
  201.     kbInfo.cb = sizeof(KBDINFO);
  202.  
  203.     rc = KbdFlushBuffer(hKbd);
  204.     DD_TRACE("KbdFlushBuffer",rc);
  205.     rc = KbdGetStatus(&kbInfo, hKbd);
  206.     DD_TRACE("KbdGetStatus",rc);
  207.  
  208.  
  209.     if(!rc)
  210.     {
  211.         kbInfo.fsMask = KEYBOARD_BINARY_MODE | KEYBOARD_SHIFT_REPORT ;
  212.         rc = KbdSetStatus(&kbInfo, hKbd);
  213.         DD_TRACE("KbdSetStatus",rc);
  214.     }
  215.     rc = KbdFlushBuffer(hKbd);
  216.     DD_TRACE("KbdFlushBuffer",rc);
  217.  
  218.     rc = DosAllocMem((PPVOID)&AlignedBuffer,
  219.                 BufLen,
  220.                 PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_TILE);
  221.     DD_TRACE("DosAllocMem",rc);
  222.  
  223.     rc = VioGetCurType(&CUR_SAVE,0);
  224.     DD_TRACE("VioGetCurType",rc);
  225.  
  226.     __nls_init();
  227.     init_pm(0);
  228.  
  229.     VioInitComplete = 1;
  230. }
  231.  
  232. void vio_shutdown(void)
  233. {
  234.     deinit_pm();
  235.     vio_cls(0x07);
  236.     vio_show();
  237.     vio_cursor_pos(0, 0);
  238.  
  239.     VioSetCurType(&CUR_SAVE, 0);
  240. }
  241.  
  242. void vio_read_key(KeyInfo* key)
  243. {
  244.     KBDKEYINFO skInfo;
  245.     KBDKEYINFO skNewInfo;
  246.     HKBD   hKbd    = 0;
  247.     APIRET rc      = 0;
  248.     USHORT usKey   = 0;
  249.     USHORT usShift = 0;
  250.  
  251.     key->rep_count = 1;
  252.  
  253.     rc = KbdCharIn(&skInfo, IO_WAIT, hKbd);
  254.  
  255.     if(!rc)
  256.     {
  257.         usKey   = (USHORT)(skInfo.chScan << 8) | skInfo.chChar;
  258.         usShift = skInfo.fsState;
  259.         key->old_key = usKey;
  260.         do
  261.         {
  262.             rc = KbdPeek(&skNewInfo, hKbd);
  263.             if(!rc)
  264.             {
  265.                 if(   skInfo.chScan == skNewInfo.chScan
  266.                    && skInfo.chChar == skNewInfo.chChar
  267.                    && skInfo.fsState== skNewInfo.fsState
  268.                    && skInfo.time   != skNewInfo.time)
  269.                 {
  270.                     rc = KbdCharIn(&skInfo, IO_WAIT, hKbd);
  271.                     key->rep_count++;
  272.                 }
  273.                 else
  274.                     rc = (APIRET)-1;
  275.             }
  276.         }
  277.         while(!rc);
  278.     }
  279.     importKey(key, usKey, usShift);
  280. }
  281.  
  282. void vio_cls(int Color)
  283. {
  284. //    memset((unsigned int *)Screen, (Color << 8), BufLen);
  285.     vio_fill(Color, ' ');
  286. }
  287.  
  288. void vio_fill(int Color, int Char)
  289. {
  290.     unsigned short *uScr = (unsigned short *)Screen;
  291.     int i;
  292.     for(i = 0; i < (BufLen /2); i++)
  293.         *uScr++ = (unsigned short)((Color << 8) | (Char & 0xFF));
  294. }
  295.  
  296. void vio_print2(int Row, int Col, char *String, int MaxLen, int Color)
  297. {
  298.     vio_print(Row, Col, String, MaxLen, Color);
  299.     vio_show_str(Row, Col, MaxLen);
  300. }
  301.  
  302. void vio_print(int Row, int Col, char *String, int MaxLen, int Color)
  303. {
  304.     int i;
  305.     char *sptr = ScreenPtr(Row, Col);
  306.  
  307.     if(!String)
  308.         return;
  309.     if((Cols - Col) < MaxLen)
  310.         MaxLen = Cols - Col;
  311.  
  312.     for(i = 0; i < MaxLen; i++)
  313.     {
  314. #ifdef __FED_DEBUG__
  315.         if(((char*)sptr-Screen) >= (BufLen - 1))
  316.             fprintf(stderr, "access out of bounds (%d,%d,\"%s\" (%s,%d)",
  317.                     Row, Col, String, __FILE__, __LINE__);
  318. #endif
  319.  
  320.         *sptr ++ = (*String) ? (*String):' ';
  321.         *sptr++  = (char)Color;
  322.  
  323.         if(*String)
  324.             String++;
  325.     }
  326. }
  327.  
  328. void vio_printh(int Row, int Col, char *String, int MaxLen, int Color, int ColorH)
  329. {
  330.     int i;
  331.     char *sptr = ScreenPtr(Row, Col);
  332.     char *Ccolor = (char *) &Color;
  333.  
  334.     if(!String)
  335.         return;
  336.  
  337.     if((Cols - Col) < MaxLen)
  338.         MaxLen = Cols - Col;
  339.  
  340.     for(i = 0; i < MaxLen; i++)
  341.     {
  342. #ifdef __FED_DEBUG__
  343.         if((sptr-Screen) >= (BufLen - 1))
  344.             fprintf(stderr, "access out of bounds (%d,%d) \"%s\" (%s,%d)",
  345.                     Row, Col, String, __FILE__, __LINE__);
  346. #endif
  347.         if(*String == SWITCH_CHAR)
  348.         {
  349.             /*Swap colors*/
  350.             Ccolor = (Ccolor == (char *) &Color) ?
  351.                         ((char *) &ColorH):
  352.                         ((char *) &Color);
  353.             i--;
  354.         }
  355.         else
  356.         {
  357.             *sptr ++ = (*String) ? (*String):' ';
  358.  
  359. #ifdef __FED_DEBUG__
  360.         if((sptr-Screen) >= (BufLen - 1))
  361.             fprintf(stderr, "access out of bounds (%d,%d) \"%s\" (%s,%d)",
  362.                     Row, Col, String, __FILE__, __LINE__);
  363. #endif
  364.             *sptr ++ = *Ccolor;
  365.         }
  366.         if(*String)
  367.             String++;
  368.     }
  369. }
  370. void vio_hdraw(int Row, int Col, char Char, int Len, int Color)
  371. {
  372.     char *sptr = ScreenPtr(Row, Col);
  373.     int i;
  374.  
  375.     if((Cols - Col) < Len)
  376.         Len = Cols - Col;
  377.  
  378.     for(i = 0; i < Len; i++)
  379.     {
  380. #ifdef __FED_DEBUG__
  381.         if((sptr-Screen) >= (BufLen - 1))
  382.             fprintf(stderr, "access out of bounds (%d,%d) (%s,%d)",
  383.                     Row, Col,  __FILE__, __LINE__);
  384. #endif
  385.         *sptr ++ = Char;
  386. #ifdef __FED_DEBUG__
  387.         if((sptr-Screen) >= (BufLen - 1))
  388.             fprintf(stderr, "access out of bounds (%d,%d) (%s,%d)",
  389.                     Row, Col,  __FILE__, __LINE__);
  390. #endif
  391.         *sptr ++ = (char)Color;
  392.     }
  393. }
  394.  
  395. void vio_vdraw(int Row, int Col, char Char, int Len, int Color)
  396. {
  397.     char *sptr = ScreenPtr(Row, Col);
  398.     int Shift = (Cols - 1) << 1;
  399.     int i;
  400.  
  401.     if((Rows - Row) < Len)
  402.         Len = Rows - Row;
  403.     for(i = 0; i < Len; i++)
  404.     {
  405. #ifdef __FED_DEBUG__
  406.         if((sptr-Screen) >= (BufLen - 1))
  407.             fprintf(stderr, "access out of bounds (%d,%d) (%s,%d)",
  408.                     Row, Col,  __FILE__, __LINE__);
  409. #endif
  410.         *sptr++ = Char;
  411. #ifdef __FED_DEBUG__
  412.         if((sptr-Screen) >= (BufLen - 1))
  413.             fprintf(stderr, "access out of bounds (%d,%d) (%s,%d)",
  414.                     Row, Col,  __FILE__, __LINE__);
  415. #endif
  416.         *sptr++ = (char)Color;
  417.         sptr += Shift;
  418.     }
  419. }
  420.  
  421. void vio_box(int Row, int Col, int Hight, int Width, int Type, int Color)
  422. {
  423.     static char* sideTypes[]=
  424.     {
  425.         /*Corners, Top, Bottom, Left, Right sides */
  426.         "┌┐└┘──││", /*Single line             */
  427.         "╒╕└┘═─││", /*Double top              */
  428.         "╔╗╚╝══║║", /*Double                  */
  429.         "╒╕└╝═─││", /*Double top, resizeable  */
  430.         "││└┘█─││", /*Single line, bold top   */
  431.         "        "
  432.     };
  433. #define UL_Corner  0
  434. #define UR_Corner  1
  435. #define BL_Corner  2
  436. #define BR_Corner  3
  437. #define T_Side     4
  438. #define B_Side     5
  439. #define L_Side     6
  440. #define R_Side     7
  441.  
  442.     if(Type < (sizeof(sideTypes)/sizeof(char *)))
  443.     {
  444.         vio_hdraw(Row            , Col            , sideTypes[Type][UL_Corner], 1, Color);
  445.         vio_hdraw(Row            , Col + Width - 1, sideTypes[Type][UR_Corner], 1, Color);
  446.         vio_hdraw(Row + Hight - 1, Col            , sideTypes[Type][BL_Corner], 1, Color);
  447.         vio_hdraw(Row + Hight - 1, Col + Width - 1, sideTypes[Type][BR_Corner], 1, Color);
  448.         vio_hdraw(Row            , Col + 1        , sideTypes[Type][T_Side], Width - 2, Color);
  449.         vio_hdraw(Row + Hight - 1, Col + 1        , sideTypes[Type][B_Side], Width - 2, Color);
  450.         vio_vdraw(Row + 1        , Col            , sideTypes[Type][L_Side], Hight - 2, Color);
  451.         vio_vdraw(Row + 1        , Col + Width - 1, sideTypes[Type][R_Side], Hight - 2, Color);
  452.     }
  453. }
  454. void vio_show(void)
  455. {
  456.     VioShowBuf((USHORT) 0, (USHORT)BufLen, 0);
  457. }
  458. void vio_cursor_pos(int row, int col)
  459. {
  460.     VioSetCurPos((USHORT)row, (USHORT)col, 0);
  461. }
  462. void vio_cursor_type(int shape)
  463. {
  464.     VIOCURSORINFO cursor;
  465.     cursor.cEnd   = (USHORT)-100;
  466.     cursor.cx     = 1;
  467.     cursor.attr   = (USHORT)-1;
  468.  
  469.     if(iShape[0] <= 0)
  470.         iShape[0] = 10;
  471.  
  472.     if(iShape[0] >= 100)
  473.         iShape[0] = 90;
  474.  
  475.     if(iShape[1] <= 0)
  476.         iShape[1] = 10;
  477.  
  478.     if(iShape[1] >= 100)
  479.         iShape[1] = 90;
  480.  
  481.     cursor.yStart = (USHORT)(iShape[0] - 100);
  482.  
  483.     switch(shape)
  484.     {
  485.         case BigCursor:
  486.             cursor.yStart = (USHORT)(iShape[1] - 100);
  487.         case Underline :
  488.             cursor.attr   = 0;
  489.         case NoCursor :
  490.             break;
  491.     }
  492.     VioSetCurType(&cursor, 0);
  493. }
  494.  
  495. struct stScreen
  496. {
  497.     int Row;
  498.     int Col;
  499.     int Rows;
  500.     int Cols;
  501.     char Data[1];
  502. };
  503.  
  504. void *vio_save_box(int Row, int Col, int Hight, int Width)
  505. {
  506.     stScreen * save_data;
  507.  
  508.     if(Hight * Width <= 0 || Row < 0 && Col < 0)
  509.         return 0;
  510.  
  511.     save_data = (stScreen *) new char[(sizeof(stScreen) + (Hight*Width) << 1)];
  512.     save_data->Row  = Row ;
  513.     save_data->Col  = Col ;
  514.     save_data->Rows = Hight;
  515.     save_data->Cols = Width;
  516.     int offset_sb = 0;
  517.     int offset = ScreenOffset(Row, Col);
  518.  
  519.     for(int i = 0; i < Hight; i++)
  520.     {
  521. #ifdef __FED_DEBUG__
  522.         if(offset + (Width << 1) >= (BufLen - 1))
  523.             fprintf(stderr, "access out of bounds (%d,%d) %d (%s,%d)",
  524.                     Row, Col, offset, __FILE__, __LINE__);
  525. #endif
  526.         memcpy(&save_data->Data[offset_sb], &Screen[offset], Width << 1);
  527.         offset    += Cols << 1;
  528.         offset_sb += Width << 1;
  529.     }
  530.     return save_data;
  531. }
  532.  
  533. void vio_restore_box(void *data)
  534. {
  535.     stScreen * save_data = (stScreen *)data;
  536.     if(!save_data)
  537.         return;
  538.     int offset_sb = 0;
  539.     int offset = ScreenOffset(save_data->Row, save_data->Col);
  540.     for(int i = 0; i < save_data->Rows; i++)
  541.     {
  542. #ifdef __FED_DEBUG__
  543.         if(offset + (save_data->Cols << 1) >= (BufLen - 1))
  544.             fprintf(stderr, "access out of bounds (%d,%d) %d (%s,%d)",
  545.                     save_data->Row, save_data->Col, offset, __FILE__, __LINE__);
  546. #endif
  547.         memcpy(&Screen[offset], &save_data->Data[offset_sb], save_data->Cols << 1);
  548.         VioShowBuf((USHORT)offset, (USHORT)(save_data->Cols << 1), 0);
  549.         offset    += Cols << 1;
  550.         offset_sb += save_data->Cols << 1;
  551.     }
  552.  
  553.     delete save_data;
  554. }
  555.  
  556. void vio_show_str(int Row, int Col, int Len)
  557. {
  558.     USHORT offset = (USHORT)ScreenOffset(Row,Col);
  559.     VioShowBuf((USHORT)offset, (USHORT)(Len << 1), 0);
  560. }
  561.  
  562. void vio_show_buf(int Offset, int Len)
  563. {
  564.     VioShowBuf((USHORT)Offset, (USHORT)Len, 0);
  565. }
  566.  
  567. char *vio_set_work_buff(char *buff)
  568. {
  569.     char *old = Screen;
  570.     Screen = buff;
  571.     return old;
  572. }
  573.  
  574. void importKey(KeyInfo* key, USHORT usKey, USHORT usShift)
  575. {
  576.     key->skey = AltKey[usKey >> 8].code;
  577.     key->key  = (unsigned short)(usKey & 0x00FF);
  578.     key->KeyName[0] = 0;
  579.  
  580.     if(key->skey == kbEsc)      //ESC-key handling
  581.         key->skey |= shIsCtrl;
  582.  
  583.     if(usShift & 8)
  584.         key->skey |= shIsCtrl | shAlt;
  585.  
  586.     if(usShift & 4)
  587.         key->skey |= shIsCtrl | shCtrl;
  588.  
  589.     if(usShift & 3) //'Shift' pressed
  590.     {
  591.         key->skey |= shShift;
  592.  
  593.         //Shift can be pressed in many situations
  594.         //We will try to separate them into two categories:
  595.         //1. Shift pressed with usual alpha-numeric key
  596.         //2. Shift pressed with control key
  597.  
  598.         //First try:
  599.         // If this key don't have ASCII code this is control key
  600.         //Second try:
  601.         // Another similar case: ASCII code for this key is 0xE0
  602.         //Last try:
  603.         // If ASCII code for this key is from '0' to '9', or '.',
  604.         // and shift is pressed, we assume that this is control key
  605.         // By the way: this codes cant come from another source, because
  606.         // from the other sources they come _without_ Shift pressed
  607.  
  608.         if( (usKey & 0x00FF) == 0 ||
  609.             (usKey & 0x00FF) == 0xE0 ||
  610.             ((usKey & 0x00FF) >= '0' && (usKey & 0x00FF) <= '9') ||
  611.             ((usKey & 0x00FF) == '.' && (usKey & 0xFF00) != 0))
  612.         {
  613.             key->skey |= shIsCtrl;
  614.         }
  615.  
  616.     }
  617.     if((usKey & 0x00FF) == 0 ||
  618.        ((usKey & 0x00FF) == 0xE0 && (usKey & 0xFF00) != 0))
  619.         key->skey |= shIsCtrl;
  620.     if((usKey & 0x00FF) == 0x0D)
  621.         key->skey |= shIsCtrl;
  622.     if((usKey & 0x00FF) == 0x08)
  623.         key->skey |= shIsCtrl;
  624.     if((usKey & 0xFF00) == 0x4A00)
  625.         key->skey |= shIsCtrl;
  626.     if((usKey & 0xFF00) == 0x4E00)
  627.         key->skey |= shIsCtrl;
  628.  
  629.     if(key->skey & shIsCtrl)
  630.     {
  631.         char *ptr = key->KeyName;
  632.         static char cAlt  []="Alt";
  633.         static char cCtrl []="Ctrl";
  634.         static char cShift[]="Shift";
  635.  
  636.         *ptr++ = 'k';
  637.         *ptr++ = 'b';
  638.         if(key->skey & shAlt)
  639.         {
  640.             memcpy(ptr, cAlt, sizeof(cAlt) - 1);
  641.             ptr += sizeof(cAlt) - 1;
  642.         }
  643.  
  644.         if(key->skey & shCtrl)
  645.         {
  646.             memcpy(ptr, cCtrl, sizeof(cCtrl) - 1);
  647.             ptr += sizeof(cCtrl) - 1;
  648.         }
  649.  
  650.         if(key->skey & shShift)
  651.         {
  652.             memcpy(ptr, cShift, sizeof(cShift) - 1);
  653.             ptr += sizeof(cShift) - 1;
  654.         }
  655.         // Copy string from array, including '\x00' terminator
  656.  
  657.         memcpy(ptr, AltKey[usKey >> 8].name, strlen(AltKey[usKey >> 8].name) + 1);
  658.     }
  659.     else
  660.     {
  661.         key->KeyName[0] = key->key;
  662.         key->KeyName[1] = 0;
  663.     }
  664.  
  665.     memcpy(&kiLastKey, key, sizeof(kiLastKey));
  666. }
  667.  
  668. int cstrlen(char *str)
  669. {
  670.     int rc = 0;
  671.     if(str)
  672.     {
  673.         while(*str)
  674.         {
  675.             if(*str != SWITCH_CHAR)
  676.                 rc++;
  677.             str++;
  678.         }
  679.     }
  680.     return rc;
  681. }
  682.  
  683. void vio_draw_attr(int Row, int Col, int Len, int Color)
  684. {
  685.     char *sptr = ScreenPtr(Row, Col);
  686.     int i;
  687.  
  688.     if((Cols - Col) < Len)
  689.         Len = Cols - Col;
  690.     for(i = 0; i < Len; i++)
  691.     {
  692.         sptr ++;
  693.         *sptr ++ = (char)Color;
  694.     }
  695. }
  696.  
  697. void vio_scroll(int Dir, Rect& rect, int Num, int Attr)
  698. {
  699.     static BYTE cell[]= {' ', ' '};
  700.  
  701.     cell[1] = (BYTE)Attr;
  702.  
  703.     switch(Dir)
  704.     {
  705.         case SCROLL_UP:
  706.             VioScrollUp((USHORT)rect.row,
  707.                         (USHORT)rect.col,
  708.                         (USHORT)(rect.row + rect.rows - Num),
  709.                         (USHORT)(rect.col + rect.cols),
  710.                         (USHORT)Num,
  711.                         (PBYTE)cell,
  712.                         0);
  713.                         break;
  714.         case SCROLL_DN:
  715.             VioScrollDn((USHORT)rect.row,
  716.                         (USHORT)rect.col,
  717.                         (USHORT)(rect.row + rect.rows - Num),
  718.                         (USHORT)(rect.col + rect.cols),
  719.                         (USHORT)Num,
  720.                         (PBYTE)cell,
  721.                         0);
  722.                         break;
  723.         case SCROLL_LT:
  724.             VioScrollLf((USHORT)rect.row,
  725.                         (USHORT)rect.col,
  726.                         (USHORT)(rect.row + rect.rows - 1),
  727.                         (USHORT)(rect.col + rect.cols - Num),
  728.                         (USHORT)Num,
  729.                         (PBYTE)cell,
  730.                         0);
  731.                         break;
  732.         case SCROLL_RT:
  733.             VioScrollRt((USHORT)rect.row,
  734.                         (USHORT)rect.col,
  735.                         (USHORT)(rect.row + rect.rows - 1),
  736.                         (USHORT)(rect.col + rect.cols - Num),
  737.                         (USHORT)Num,
  738.                         (PBYTE)cell,
  739.                         0);
  740.                         break;
  741.     }
  742. }
  743.  
  744. char * cvt_num(unsigned int ulID, int minlen)
  745. {
  746.     static char numbuff[12];
  747.     char *buff = numbuff;
  748.     char *str;
  749.     int  slen = 0;
  750.  
  751.     str = buff;
  752.  
  753.     do
  754.     {
  755.         *str++ = (char)((ulID % 10) + '0');
  756.         ulID /= 10;
  757.         slen++;
  758.     }
  759.     while(ulID);
  760.  
  761.     while(slen < minlen)
  762.     {
  763.         *str++ = '0';
  764.         slen++;
  765.     }
  766.  
  767.     *str-- = 0;
  768.  
  769.     for(; str > buff; str--, buff++)
  770.     {
  771.         *buff ^= *str;
  772.         *str  ^= *buff;
  773.         *buff ^= *str;
  774.     }
  775.     return numbuff;
  776. }
  777.  
  778. char * xcvt_char(int chr)
  779. {
  780.     static char numbuff[3];
  781.     char nibble;
  782.  
  783.     nibble = (char)(chr >> 4);
  784.  
  785.     numbuff[0] = (char)((nibble > 9) ? (nibble + 'A' - 10) : (nibble + '0'));
  786.  
  787.     nibble = (char)(chr & 0x0F);
  788.  
  789.     numbuff[1] = (char)((nibble > 9) ? (nibble + 'A' - 10) : (nibble + '0'));
  790.  
  791.     numbuff[2] = 0;
  792.  
  793.     return numbuff;
  794. }
  795.  
  796. char *str_dup(char* str, int len)
  797. {
  798.     if(len < 0)
  799.         len = (str) ? strlen(str):0;
  800.  
  801.     char *ptr = new char[len+1];
  802.  
  803.     if(len)
  804.     {
  805.         if(str)
  806.             memcpy(ptr, str, len);
  807.         else
  808.             memset(ptr, ' ', len);
  809.     }
  810.  
  811.     ptr[len] = 0;
  812.  
  813.     return ptr;
  814. }
  815.  
  816. //-----------------------------------------
  817. // Thread level HAB/HMQ handler
  818. //-----------------------------------------
  819.  
  820. PMObj::PMObj():hab(0),hmq(0)
  821. {
  822.     if(!::hmq)
  823.         return;
  824.  
  825.     hab = _inInitialize(0);
  826.     hmq = _inCreateMsgQueue(hab, 0);
  827. }
  828.  
  829. PMObj::~PMObj()
  830. {
  831.     if(hmq)
  832.         _inDestroyMsgQueue(hmq);
  833.     if(hab)
  834.         _inTerminate(hab);
  835. }
  836.  
  837.