home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / S12442.ZIP / DIPOP.C < prev    next >
C/C++ Source or Header  |  1989-07-31  |  22KB  |  848 lines

  1. /* dipop.c RHS 7/14/89
  2.  *
  3.  * directory utility that allows use of keyboard and mouse to display
  4.  * directory information. To run it:
  5.  
  6.     DIPOP
  7.  
  8.  *
  9.  */
  10.  
  11. #define    INCL_SUB
  12. #define    INCL_DOSERRORS
  13. #define    INCL_DOS
  14. #include<os2.h>
  15. #include<mt\stdio.h>
  16. #include<mt\string.h>
  17. #include<mt\stdlib.h>
  18. #include<mt\process.h>
  19. #include<mt\dos.h>
  20. #include"moudefs.h"
  21. #include"kbddefs.h"
  22. #include"msgq.h"
  23. #include"button.h"
  24. #include"errexit.h"
  25. #include"di.h"
  26.  
  27. #define    MAINMSGQUEUE    "\\QUEUES\\DIPOPMSG.QUE"
  28. #define    PRINTQUEUE        "\\QUEUES\\DIPOPPRT.QUE"
  29.  
  30. #define    VIOHDL                0
  31. #define    PRINTTHREADSTACK    1000                /* mou/key thread stack size*/
  32. #define    THREADSTACK            500                    /* print thread stack size    */
  33.  
  34. #define    BORDERCOL    60
  35. #define    DIRROW        17
  36. #define    STARTROW    2
  37. #define    ENDROW        16
  38.  
  39. #define    BUTTON_ON                0x4f
  40. #define    BUTTON_OFF                0x1f
  41.  
  42. #define    SCAN                        0x0100
  43. #define    EVENT                        0x0200
  44. #define    MOUSE                        0x1000
  45.  
  46. #define    ASCIICODE(val)            (val)
  47. #define    SCANCODE(val)             (val | SCAN)
  48. #define    EVENTCODE(val)            (val | EVENT)
  49.  
  50. #define    MOUSECODE(val)            (val | MOUSE)
  51. #define    ButtonEvent(event)    (event & MOUSE)
  52. #define    MOUSECODEOFF(val)        (val &= ~MOUSE)
  53.  
  54. #define    REMAINING_CHARS    (sizeof(filespecbuffer)-(currchar-filespecbuffer))
  55.  
  56. #define    PAUSE_EVENT                EVENTCODE(1)
  57. #define    DIRECTORY_EVENT            EVENTCODE(2)
  58. #define    READONLY_EVENT            EVENTCODE(3)
  59. #define    HIDDEN_EVENT            EVENTCODE(4)
  60. #define    SYSTEM_EVENT            EVENTCODE(5)
  61. #define    ARCHIVE_EVENT            EVENTCODE(6)
  62. #define    DR_DEC_EVENT            EVENTCODE(7)
  63. #define    DR_INC_EVENT            EVENTCODE(8)
  64. #define    DIR_DEC_EVENT            EVENTCODE(9)
  65. #define    DIR_INC_EVENT            EVENTCODE(10)
  66. #define    ROOT_EVENT                EVENTCODE(11)
  67. #define    CD_PARENT_EVENT            EVENTCODE(12)
  68. #define    CD_CHILD_EVENT            EVENTCODE(13)
  69. #define    CLR_EVENT                EVENTCODE(14)
  70. #define    ESCAPE_EVENT            EVENTCODE(15)
  71. #define    POPUP_EVENT                EVENTCODE(16)
  72. #define    TERMINATE_EVENT            EVENTCODE(17)
  73.  
  74. #define    LEFT_ARROW_EVENT        SCANCODE(75)
  75. #define    RIGHT_ARROW_EVENT        SCANCODE(77)
  76. #define    DEL_EVENT                SCANCODE(83)
  77. #define    HOME_EVENT                SCANCODE(71)
  78. #define    END_EVENT                SCANCODE(79)
  79.  
  80. #define    ALT_R                    SCANCODE(19)
  81. #define    ALT_D                    SCANCODE(32)
  82. #define    ALT_H                    SCANCODE(35)
  83. #define    ALT_S                    SCANCODE(31)
  84. #define    ALT_A                    SCANCODE(30)
  85. #define    ALT_C                    SCANCODE(46)
  86. #define ALT_P                    SCANCODE(25)
  87.  
  88. #define    ENTER                    13
  89. #define    ESC                    27
  90. #define    BACKSPACE_EVENT    8
  91.  
  92.  
  93. #define FILE_UNUSED0            0x0040
  94. #define FILE_UNUSED1            0x0080
  95. #define FILE_VOLLABEL            0x0008
  96.  
  97.  
  98. #define    beep()                    DosBeep(440,200)
  99. #define    Lastchar(str)            (str[strlen(str)-1])
  100. #define DIROFFSET                3
  101.  
  102.  
  103.     /********************* Buttons ****************************/
  104.  
  105.         
  106. BUTTON buttonlist[18] =
  107.     {
  108. /* text            row,col,row,col,attr,        type    left val,         right val, accelerator    */
  109. {" Pause ",        22,    27,    0,    0,    BUTTON_OFF,    BTOGGLE,PAUSE_EVENT,    PAUSE_EVENT,       ALT_P,     0},
  110. {" Enter ",        22,    17,    0,    0,    BUTTON_OFF,    BPRESS,    ENTER,             ENTER,            ENTER,    0},
  111. {" Esc ",        22,    37,    0,    0,    BUTTON_OFF,    BPRESS,    ESCAPE_EVENT,    ESCAPE_EVENT,      ESC,    0},
  112. {" Directory ",0,        64,    0,    0,    BUTTON_OFF,    BTOGGLE,    DIRECTORY_EVENT,DIRECTORY_EVENT,    ALT_D,    0},
  113. {" Read-Only ",4,        64,    0,    0,    BUTTON_OFF,    BTOGGLE,    READONLY_EVENT,    READONLY_EVENT,    ALT_R,    0},
  114. {"  Hidden   ",8,        64,    0,    0,    BUTTON_OFF,    BTOGGLE,    HIDDEN_EVENT,    HIDDEN_EVENT,      ALT_H,    0},
  115. {"  System   ",12,    64,    0,    0,    BUTTON_OFF,    BTOGGLE,    SYSTEM_EVENT,    SYSTEM_EVENT,      ALT_S,    0},
  116. {"  Archive  ",16,    64,    0,    0,    BUTTON_OFF,    BTOGGLE,    ARCHIVE_EVENT,    ARCHIVE_EVENT,     ALT_A,    0},
  117. {"-C-",            19,    1,        0,    0,    BUTTON_OFF,    BPRESS,    DR_DEC_EVENT,    DR_INC_EVENT,      0,        0},
  118. {"Directory                                            ",
  119.                     19,    7,        0,    0,    BUTTON_OFF,    BPRESS,    DIR_DEC_EVENT,    DIR_INC_EVENT,     0,        0},
  120. {" [\\] ",        22,    0,        0,    0,    BUTTON_OFF,    BPRESS,    ROOT_EVENT,        ROOT_EVENT,           0,        0},
  121. {" [..] ",        22,    8,        0,    0,    BUTTON_OFF,    BPRESS,    CD_PARENT_EVENT,CD_CHILD_EVENT,    0,        0},
  122. {" Clear ",        22,    45,    0,    0,    BUTTON_OFF,    BPRESS,    CLR_EVENT,        CLR_EVENT,         ALT_C,    0},
  123. {" * ",            22,    55,    0,    0,    BUTTON_OFF,    BPRESS,    '*',               '*',               '*',    0},
  124. {" \\ ",            22,    61,    0,    0,    BUTTON_OFF,    BPRESS,  '\\',          '\\',              '\\',    0},
  125. {" . ",            22,    67,    0,    0,    BUTTON_OFF,    BPRESS,    '.',               '.',               '.',    0},
  126. {" ? ",            22,    73,    0,    0,    BUTTON_OFF,    BPRESS,    '?',               '?',               '?',    0},
  127. {NULL,            0,        0,        0,    0,    0,            0,        0,                0,                 0,        0}
  128.     };
  129.  
  130. BUTTON    *drive_button;
  131. BUTTON    *dir_button;
  132.  
  133. BUTTON filespecfield =
  134.     {
  135.     "            ",        19,    63,    21,    76,    BUTTON_OFF,    INPUT,    0,                0,                0,        0
  136.     };
  137.  
  138.  
  139. long PauseSem = 0L;
  140. unsigned InputMode = 0;
  141. char *title = "   Filename ----- Size ---- UpDate --- Time ---- Attributes ";
  142. char *format= "%-12s   %8ld   %2d/%02d/%02d   %2d:%02d:%02d%c   %8s";
  143.  
  144. BYTE MouseThreadStack[THREADSTACK];
  145. BYTE KeyboardThreadStack[THREADSTACK];
  146. BYTE PrintThreadStack[PRINTTHREADSTACK];
  147.  
  148. HMOU MouHandle;
  149.  
  150. #define    FILESPECSIZE    12
  151. char filespecbuffer[FILESPECSIZE+1];
  152. USHORT    attribute_mask;
  153.  
  154. ULONG            drive_map;
  155. char            dirspecbuffer[80];
  156. PVOID    dirheader = NULL;
  157. USHORT            dirbuflen = 0;
  158.  
  159. #define DIRPTRS        200
  160. PCH             dirptrs[DIRPTRS], *dirptr;
  161. USHORT            dirs;
  162. unsigned BlankCell = 0x1f20;
  163.  
  164. void main(void);
  165. void MouseThread(void);
  166. void KeyboardThread(void);
  167. void PrintThread(void);
  168.  
  169. void InitDriveButton(void);
  170. void InitScreen(void);
  171. void RefreshDirButton(void);
  172. void InitDirButton(void);
  173. void SendRequest(void);
  174. void PrintRequest(PVOID header);
  175. void PrintRequestEntry(PFILEFINDBUF f);
  176. void WriteRequestEntry(char *buffer);
  177. void WriteDirButton(char *result);
  178.  
  179. void display_button(BUTTON *button,unsigned    char attr);
  180. USHORT AcceleratorPressed(unsigned char key);
  181. USHORT ButtonPressed(MOUEVENTINFO *ev);
  182. void ButtonPress(USHORT *eventcode);
  183.  
  184. void buffermgr(unsigned event);
  185. void initfield(void);
  186. void set_attribute(USHORT attribute);
  187. void drive_event(USHORT event);
  188. void dir_event(USHORT event);
  189. void set_attribute_values(char *str, unsigned attribute);
  190. void child_changedir(void);
  191.  
  192.  
  193. void main(void)
  194.     {
  195.     USHORT event, pause = 0;
  196.     HQUEUE     qhandle;
  197.  
  198. #define DEBUG
  199. #ifdef DEBUG
  200.     USHORT    retval;
  201.  
  202.     if(retval = DosSelectDisk(5))
  203.         error_exit(retval,"Changing drive");
  204.     if(retval = DosChDir("\\wrk\\hello",0L))
  205.         error_exit(retval,"Changing dir");
  206. #endif
  207.  
  208.     MsgQCreate(&qhandle,MAINMSGQUEUE);
  209.     DosSemClear(&PauseSem);
  210.                                                 /* start mouse thread        */
  211.     if(_beginthread(PrintThread,PrintThreadStack,sizeof(PrintThreadStack),NULL) == -1)
  212.         error_exit(0,"_beginthread(Keyboard)");
  213.     if(_beginthread(MouseThread,MouseThreadStack,sizeof(MouseThreadStack),NULL) == -1)
  214.         error_exit(0,"_beginthread(Mouse)");
  215.     if(_beginthread(KeyboardThread,KeyboardThreadStack,sizeof(KeyboardThreadStack),NULL) == -1)
  216.         error_exit(0,"_beginthread(Keyboard)");
  217.  
  218.     DosSleep(1000L);                            /* let threads get going    */
  219.  
  220.     InitButtons();
  221.     InitScreen();
  222.     DisplayButtons();
  223.     InitDriveButton();
  224.     InitDirButton();
  225.     initfield();
  226.  
  227.     while(TRUE)
  228.         {
  229.         MsgQGet(qhandle,&event);
  230.  
  231.         if(ButtonEvent(event))
  232.             ButtonPress(&event);
  233.  
  234.         switch(event)
  235.             {
  236.             case PAUSE_EVENT:
  237.                 /* if text thread is active, pause text, if already paused, unpause */
  238.                 if(pause)                        /* if pause is on, clear sem*/
  239.                     DosSemClear(&PauseSem);
  240.                 else
  241.                     DosSemSet(&PauseSem);
  242.                 pause = !pause;                    /* toggle pause flag        */
  243.                 break;
  244.  
  245.             case ENTER:
  246.                 /* send request to directory server    */
  247.                 SendRequest();
  248.                 break;
  249.  
  250.             case ESCAPE_EVENT:
  251.             case ESC:
  252.                 DosCloseQueue(qhandle);
  253.                 if(dirheader)
  254.                     DiDestroyRequest(&dirheader);
  255.                 VioScrollUp(0,0,-1,-1,-1,(char *)&BlankCell,VIOHDL);
  256.                 DosExit(EXIT_PROCESS,0);        /* and exit                        */
  257.                 break;
  258.  
  259.             case READONLY_EVENT:
  260.                 /* set the request mask to only return files with read-only attr*/
  261.                 set_attribute(FILE_READONLY);
  262.                 break;
  263.             case HIDDEN_EVENT:
  264.                 /* set the request mask to only return files with hidden attr    */
  265.                 set_attribute(FILE_HIDDEN);
  266.                 break;
  267.             case SYSTEM_EVENT:
  268.                 /* set the request mask to only return files with system attr    */
  269.                 set_attribute(FILE_SYSTEM);
  270.                 break;
  271.             case ARCHIVE_EVENT:
  272.                 /* set the request mask to only return files with archive attr    */
  273.                 set_attribute(FILE_ARCHIVED);
  274.                 break;
  275.  
  276.             case DIRECTORY_EVENT:
  277.                 set_attribute(FILE_DIRECTORY);
  278.                 break;
  279.  
  280.             case DR_DEC_EVENT:
  281.             case DR_INC_EVENT:
  282.                 /* decrement/increment the current drive, get current dirs, redisplay        */
  283.                 drive_event(event);
  284.                 break;
  285.  
  286.             case DIR_DEC_EVENT:
  287.             case DIR_INC_EVENT:
  288.                 /* move up/down in directory list    */
  289.                 dir_event(event);
  290.                 break;
  291.  
  292.             case ROOT_EVENT:
  293.                 /* change to root of current drive    */
  294.                 DosChDir("\\",0L);
  295.                 RefreshDirButton();
  296.                 break;
  297.  
  298.             case CD_PARENT_EVENT:
  299.                 /* change to parent directory of current directory */
  300.                 DosChDir("..",0L);
  301.                 RefreshDirButton();
  302.                 break;
  303.             case CD_CHILD_EVENT:
  304.                 /* change to child directory of current directory */
  305.                 child_changedir();
  306.                 RefreshDirButton();
  307.                 break;
  308.  
  309.             default:
  310.                 buffermgr(event);
  311.                 break;
  312.             }
  313.         }
  314.     }
  315.  
  316. void InitScreen(void)
  317.     {
  318.     USHORT i;
  319.  
  320.     VioScrollUp(0,0,-1,-1,-1,(char *)&BlankCell,VIOHDL);
  321.     VioWrtNChar("─",BORDERCOL,DIRROW,0,VIOHDL);
  322.     VioWrtCharStr(title,strlen(title),0,0,VIOHDL);
  323.  
  324.     for( i = 0; i < DIRROW; i++)
  325.         VioWrtCharStr("│",1,i,BORDERCOL,VIOHDL);
  326.  
  327.     VioWrtCharStr("┘",1,DIRROW,BORDERCOL,VIOHDL);
  328.     }
  329.  
  330. void child_changedir(void)
  331.     {
  332.     char dirspec[70];
  333.  
  334.     if(!(*dirptr))
  335.         {
  336.         beep();
  337.         return;
  338.         }
  339.  
  340.     strcpy(dirspec,dirspecbuffer);
  341.     if(Lastchar(dirspec) != '\\')
  342.         strcat(dirspec,"\\");
  343.     strcat(dirspec,*dirptr);
  344.     DosChDir(dirspec,0L);
  345.     }
  346.  
  347. void SendRequest(void)
  348.     {
  349.     char requestbuffer[80];
  350.     PVOID header = NULL;
  351.     static HQUEUE qhandle = 0;
  352.  
  353.     if(!qhandle)
  354.         MsgQOpen(&qhandle,PRINTQUEUE);
  355.  
  356.     if(!strlen(filespecbuffer))
  357.         {
  358.         beep();
  359.         return;
  360.         }
  361.  
  362.     strcpy(requestbuffer,dirspecbuffer);
  363.     if(Lastchar(requestbuffer) != '\\')
  364.         strcat(requestbuffer,"\\");
  365.     strcat(requestbuffer,filespecbuffer);
  366.  
  367.     DiMakeRequest(&header,requestbuffer,attribute_mask);
  368.     DiSendRequest(header);
  369.  
  370.     MsgQSend(qhandle,SELECTOROF(header));
  371.     DosSleep(1000L);
  372.     }
  373.  
  374.  
  375. void set_attribute(USHORT attribute)
  376.     {
  377.     if(!(attribute_mask & attribute))
  378.         attribute_mask |= attribute;
  379.     else
  380.         attribute_mask &= ~attribute;
  381.     }
  382.  
  383.  
  384. void buffermgr(unsigned event)
  385.     {
  386.     static char *currchar = filespecbuffer;
  387.     static USHORT curpos = 0;
  388.  
  389.     switch(event)
  390.         {
  391.         case CLR_EVENT:
  392.                 /* clear the filespec input buffer    */
  393.             memset(filespecbuffer,0,sizeof(filespecbuffer));
  394.             attribute_mask = 0;
  395.             curpos = 0;
  396.             currchar = filespecbuffer;
  397.             ResetButtons();
  398.             break;
  399.  
  400.         case BACKSPACE_EVENT:
  401.             if(currchar > filespecbuffer)
  402.                 {
  403.                 currchar--;
  404.                 curpos--;
  405.                 memmove(currchar,currchar+1,REMAINING_CHARS);
  406.                 }
  407.             break;
  408.  
  409.         case DEL_EVENT:
  410.             if(*currchar)
  411.                 memmove(currchar,currchar+1,REMAINING_CHARS);
  412.             break;
  413.  
  414.         case RIGHT_ARROW_EVENT:
  415.             if(*currchar && (curpos < FILESPECSIZE-1))
  416.                 {
  417.                 currchar++;
  418.                 curpos++;
  419.                 }
  420.             break;
  421.  
  422.         case LEFT_ARROW_EVENT:
  423.             if(currchar > filespecbuffer)
  424.                 {
  425.                 currchar--;
  426.                 curpos--;
  427.                 }
  428.             break;
  429.  
  430.         case HOME_EVENT:
  431.             currchar = filespecbuffer;
  432.             curpos = 0;
  433.             break;
  434.  
  435.         case END_EVENT:
  436.             for(  ; *currchar; currchar++, curpos++);
  437.             if(curpos >= FILESPECSIZE)
  438.                 {
  439.                 curpos--;
  440.                 currchar--;
  441.                 }
  442.             break;
  443.  
  444.         default:                                                /* insert charcter at cursor*/
  445.                                                 /* if cursor is at end        */
  446.             if(curpos == FILESPECSIZE-1 && !(*currchar))
  447.                 *currchar = (char)event;                /* insert char at cursor    */
  448.                 /* else if cursor not at end and room for more in buffer            */
  449.             else if((curpos < FILESPECSIZE) && (strlen(filespecbuffer) < FILESPECSIZE))
  450.                 {
  451.                 memmove(currchar+1,currchar,strlen(currchar));
  452.                 *currchar++ = (char)event;
  453.                 curpos++;
  454.                 }
  455.             break;
  456.         }
  457.     VioWrtCharStr(filespecbuffer,FILESPECSIZE,filespecfield.startrow+1,
  458.             filespecfield.startcol+1,VIOHDL);
  459.     VioSetCurPos(filespecfield.startrow+1,filespecfield.startcol+1+curpos,
  460.             VIOHDL);
  461.     }
  462.  
  463. void initfield(void)
  464.     {
  465.     ButtonDisplay(&filespecfield);
  466.     VioSetCurPos(filespecfield.startrow+1,filespecfield.startcol+1,VIOHDL);
  467.     memset(filespecbuffer,0,sizeof(filespecbuffer));
  468.     attribute_mask = 0;
  469.     }
  470.  
  471. void InitDriveButton(void)
  472.     {
  473.     DosQCurDisk((PUSHORT)dirspecbuffer,&drive_map);
  474.     *dirspecbuffer += ('A'-1);
  475.     strcpy(&dirspecbuffer[1],":\\");
  476.     findbutton("-C-", &drive_button);
  477.  
  478.     VioWrtCharStr(dirspecbuffer,1,drive_button->startrow+1,drive_button->startcol+2,VIOHDL);
  479.     }
  480.  
  481.  
  482. void InitDirButton(void)
  483.     {
  484.     findbutton("Directory",&dir_button);
  485.     dirbuflen = strlen(dir_button->text);
  486.  
  487.     RefreshDirButton();
  488.     }
  489.  
  490. void RefreshDirButton(void)
  491.     {
  492.     USHORT numresults,numrequests,i;
  493.     PVOID    resulthdl;
  494.     PFILEFINDBUF    dirp;
  495.     char     *endbuf;
  496.     USHORT    dirspeclength = sizeof(dirspecbuffer)-DIROFFSET;
  497.  
  498.     DosQCurDir((USHORT)(*dirspecbuffer-'A'+1),&dirspecbuffer[DIROFFSET],&dirspeclength);
  499.     VioWrtCharStr(dirspecbuffer,strlen(dirspecbuffer),dir_button->startrow,
  500.             dir_button->startcol+1,VIOHDL);
  501.     VioWrtNChar("═",dirbuflen-strlen(dirspecbuffer),dir_button->startrow,
  502.             dir_button->startcol+1+strlen(dirspecbuffer),VIOHDL);
  503.  
  504.     WriteDirButton("<waiting....>");
  505.  
  506.     endbuf = &dirspecbuffer[strlen(dirspecbuffer)-1];
  507.     if(*endbuf != '\\')                        /* if not the root            */
  508.         strcat(endbuf,"\\");
  509.     endbuf++;
  510.  
  511.     strcat(dirspecbuffer,"*.*");
  512.     if(dirheader)
  513.         DiDestroyRequest(&dirheader);
  514.     DiMakeRequest(&dirheader,dirspecbuffer,0);
  515.     DiSendRequest(dirheader);
  516.     DiGetNumResults(dirheader,&numresults,&numrequests);
  517.     DiGetResultHdl(dirheader,0,&numresults,&resulthdl);
  518.     memset(dirptrs,0,sizeof(dirptrs));
  519.  
  520.     for( dirs = i = 0; i < numresults; i++)
  521.         {
  522.         if(!i)
  523.             DiGetFirstResultPtr(resulthdl,&dirp);
  524.         else
  525.             DiGetNextResultPtr(resulthdl,&dirp);
  526.         if((dirp->attrFile & FILE_DIRECTORY) && (*dirp->achName != '.'))
  527.             dirptrs[dirs++] = dirp->achName;
  528.         }
  529.  
  530.     *endbuf = '\0';
  531.  
  532.     dirptr = (dirs ? dirptrs : NULL);
  533.  
  534.     WriteDirButton(dirs ? *dirptr : "<No Sub-Directories>");
  535.     }
  536.  
  537. void WriteDirButton(char *result)
  538.     {
  539.     VioWrtCharStr(result,strlen(result),dir_button->startrow+1,
  540.             dir_button->startcol+1,VIOHDL);
  541.     VioWrtNChar(" ",dirbuflen-strlen(result),dir_button->startrow+1,
  542.             dir_button->startcol+1+strlen(result),VIOHDL);
  543.     }
  544.  
  545. void dir_event(USHORT event)
  546.     {
  547.     if(!dirs)
  548.         return;
  549.     if( ((event == DIR_DEC_EVENT) && (dirptr == dirptrs)) ||
  550.         ((event == DIR_INC_EVENT) && (dirptr == &dirptrs[dirs-1])) )
  551.         {
  552.         beep();
  553.         return;
  554.         }
  555.     if(event == DIR_DEC_EVENT)
  556.         dirptr--;
  557.     else
  558.         dirptr++;
  559.  
  560.     VioWrtCharStr(*dirptr,strlen(*dirptr),dir_button->startrow+1,
  561.             dir_button->startcol+1,VIOHDL);
  562.     VioWrtNChar(" ",dirbuflen-strlen(*dirptr),dir_button->startrow+1,
  563.             dir_button->startcol+1+strlen(*dirptr),VIOHDL);
  564.     }
  565.  
  566. void drive_event(USHORT event)
  567.     {
  568.     USHORT curdrive;
  569.  
  570.     curdrive = *dirspecbuffer-'A';
  571.     if( ((event == DR_DEC_EVENT) && !curdrive) ||
  572.             ((event == DR_INC_EVENT) && (*dirspecbuffer == 'Z')) )
  573.         {
  574.         beep();
  575.         return;
  576.         }
  577.     if( event == DR_DEC_EVENT)
  578.         curdrive--;
  579.     else
  580.         curdrive++;
  581.     if( ((drive_map >> curdrive) & 0x0001) && !DosSelectDisk(++curdrive))
  582.         *dirspecbuffer = (char)(curdrive+'A'-1);
  583.     else
  584.         {
  585.         beep();
  586.         return;
  587.         }
  588.     VioWrtCharStr(dirspecbuffer,1,drive_button->startrow+1,drive_button->startcol+2,VIOHDL);
  589.     RefreshDirButton();
  590.     }
  591.  
  592. void ButtonPress(USHORT *eventcode)
  593.     {
  594.     BUTTON *b = &buttonlist[0];
  595.  
  596.     MOUSECODEOFF(*eventcode);
  597.  
  598.     for( ; b->text; b++)                                /* find the button            */
  599.         if((b->left_button_val == *eventcode) ||
  600.                 (b->right_button_val == *eventcode) ||
  601.                 (b->accelerator == *eventcode))
  602.             {
  603.             switch(b->type)
  604.                 {
  605.                 case BPRESS:                                /* if a press button            */
  606.                     ButtonPaint(b,BUTTON_ON);            /* turn it on                    */
  607.                     DosSleep(100L);                        /* wait                            */
  608.                     ButtonPaint(b,BUTTON_OFF);            /* turn it off                    */
  609.                     break;
  610.  
  611.                 case BTOGGLE:                                /* if a toggle button        */
  612.                     b->state = !b->state;                /* toggle it                    */
  613.                                                                 /* and toggle the color        */
  614.                     ButtonPaint(b,(b->state ? (BYTE)BUTTON_ON : b->attribute));
  615.                     break;
  616.  
  617.                 default:
  618.                     break;
  619.                 }
  620.             return;
  621.             }
  622.     }
  623.  
  624.  
  625.     /******************* keyboard thread code *****************/
  626. void KeyboardThread(void)
  627.     {
  628.     KBDINFO    kbdinfo;
  629.     KBDKEYINFO kbdkeyinfo;
  630.     HKBD KbdHandle = 0;
  631.     HQUEUE    qhandle;
  632.     USHORT    event;
  633.  
  634.     MsgQOpen(&qhandle,MAINMSGQUEUE);
  635.  
  636.     KbdFlushBuffer(KbdHandle);                        /* flush keyboard buffer    */
  637.     KbdGetStatus(&kbdinfo,KbdHandle);                /* get keyboard status        */
  638.     kbdinfo.fsMask &= ~COOKED;                        /* turn    off    COOKED bit    */
  639.     kbdinfo.fsMask |= RAW;                              /* turn    on RAW bit            */
  640.     KbdSetStatus(&kbdinfo,KbdHandle);                /* set the keyboard status    */
  641.  
  642.     while(TRUE)
  643.         {
  644.         KbdCharIn(&kbdkeyinfo,IO_WAIT,KbdHandle);    /* get a character            */
  645.         if(kbdkeyinfo.chChar)                         /* if Ascii code                */
  646.             MsgQSend(qhandle,(USHORT)kbdkeyinfo.chChar);    /* pass it on        */
  647.         else if(event = AcceleratorPressed(kbdkeyinfo.chScan))    /* Accelerator?*/
  648.             MsgQSend(qhandle,event);        /* if so, pass it on            */
  649.         else
  650.             MsgQSend(qhandle,SCANCODE(kbdkeyinfo.chScan));
  651.         DosSleep(32L);
  652.         }
  653.     }
  654.  
  655.  
  656. USHORT AcceleratorPressed(unsigned char key)
  657.     {
  658.     BUTTON *b = &buttonlist[0];
  659.  
  660.     for( ; b->text; b++)
  661.         if(key == (unsigned char)b->accelerator)
  662.             return MOUSECODE(b->left_button_val);
  663.     return 0;
  664.     }
  665.  
  666.     /********** end of keyboard thread code *******************/
  667.  
  668.  
  669.     /****************** mouse thread code *********************/
  670. void MouseThread(void)
  671.     {
  672.     MOUEVENTINFO MouEvent;
  673.     USHORT WaitOption = MOU_WAIT;                        /* set to block on input    */
  674.     HQUEUE    qhandle;
  675.     USHORT    event,buttondown = FALSE;
  676.     USHORT    retval;
  677.  
  678.     MsgQOpen(&qhandle,MAINMSGQUEUE);
  679.  
  680.     if((retval = MouOpen((PSZ)NULL,(PHMOU)&MouHandle)))
  681.         error_exit(retval,"MouOpen");
  682.  
  683.     MouDrawPtr(MouHandle);                                /* display mouse pointer    */
  684.     MouFlushQue(MouHandle);                                /* flush mouse queue            */
  685.  
  686.     while(TRUE)
  687.         {                                                        /* read    the    queue            */
  688.         MouReadEventQue(&MouEvent,&WaitOption,MouHandle);
  689.         MouEventDropLowBit(MouEvent);                     /* turn off the low bit        */
  690.  
  691.         if(!buttondown && IsMouButtonPressed(MouEvent))/* if mouse button pressed    */
  692.             {
  693.             if(event = ButtonPressed(&MouEvent))    /* while on screen button    */
  694.                 {
  695.                 MsgQSend(qhandle,event);                /* notify                        */
  696.                 buttondown = TRUE;
  697.                 DosSleep(32L);
  698.                 }
  699.             }
  700.         else
  701.             buttondown = FALSE;
  702.         DosSleep(32L);
  703.         }
  704.  
  705.     MouClose(MouHandle);
  706.     }
  707.  
  708. USHORT ButtonPressed(MOUEVENTINFO *ev)
  709.     {
  710.     register USHORT row = ev->row, col = ev->col;
  711.     BUTTON    *b = &buttonlist[0];
  712.  
  713.     for( ; b->text; b++)
  714.         {
  715.         if((row    >= b->startrow)    && (row    <= b->endrow)/* if on button        */
  716.                 && (col >= b->startcol) && (col <= b->endcol))
  717.             
  718.             if(MouB1Pressed(ev->fs))
  719.                 return MOUSECODE(b->left_button_val);
  720.             else if(MouB2Pressed(ev->fs))
  721.                 return MOUSECODE(b->right_button_val);
  722.             else
  723.                 return 0;
  724.         }
  725.     return 0;
  726.     }
  727.  
  728.     /******* end of mouse thread code *************************/
  729.  
  730.  
  731.     /*************** print thread code ************************/
  732. void PrintThread(void)
  733.     {
  734.     HQUEUE             qhandle;
  735.     USHORT            retval,event;
  736.     PVOID    header = NULL;
  737.  
  738.     if(retval = DosCreateQueue(&qhandle,QUE_FIFO,PRINTQUEUE))
  739.         error_exit(retval,"DosCreateQueue");
  740.  
  741.     while(TRUE)
  742.         {
  743.         MsgQGet(qhandle,&event);
  744.         if(header)
  745.             DiDestroyRequest(&header);
  746.         header = MAKEP(event,0);
  747.         PrintRequest(header); 
  748.         DosSleep(32L);
  749.         }
  750.     }
  751.  
  752. void PrintRequest(PVOID header)
  753.     {
  754.     USHORT numresults,numrequests,i,len;
  755.     PFILEFINDBUF f;
  756.     PVOID resulthdl;
  757.     char dirspec[80];
  758.  
  759.     DiGetNumResults(header,&numresults,&numrequests);
  760.     DiGetResultHdl(header,0,&numresults,&resulthdl);
  761.  
  762.     WriteRequestEntry(" ");
  763.  
  764.     strcpy(dirspec,DiGetResultDir(resulthdl));
  765.     strcat(dirspec,"\\");
  766.     strcat(dirspec,DiGetResultFspec(resulthdl));
  767.  
  768.     VioWrtCharStr(dirspec,len = strlen(dirspec),DIRROW,1,VIOHDL);
  769.     VioWrtNChar("─",BORDERCOL-len-1,DIRROW,1+len,VIOHDL);
  770.  
  771.     for( i = 0; i < numresults; i++)
  772.         {
  773.         DosSemWait(&PauseSem,SEM_INDEFINITE_WAIT);
  774.  
  775.         if(!i)
  776.             DiGetFirstResultPtr(resulthdl,&f);
  777.         else
  778.             DiGetNextResultPtr(resulthdl,&f);
  779.         if( (attribute_mask && (f->attrFile & attribute_mask))
  780.                 || !attribute_mask)
  781.             PrintRequestEntry(f);
  782.         DosSleep(32L);
  783.         }
  784.     }
  785.  
  786. void PrintRequestEntry(PFILEFINDBUF f)
  787.     {
  788.     char formatbuffer[60];
  789.     char m, attrstr[9];
  790.     USHORT hours;
  791.  
  792.     if(f->ftimeLastWrite.hours > 12)
  793.         {
  794.         hours = (f->ftimeLastWrite.hours-12);
  795.         m = 'p';
  796.         }
  797.     else
  798.         {
  799.         hours = f->ftimeLastWrite.hours;
  800.         m = 'a';
  801.         }
  802.     set_attribute_values(attrstr,f->attrFile); 
  803.     sprintf(formatbuffer,format,
  804.             strlwr(f->achName),
  805.             f->cbFile,
  806.             f->fdateLastWrite.month,
  807.             f->fdateLastWrite.day,
  808.             f->fdateLastWrite.year+80,
  809.             hours,
  810.             f->ftimeLastWrite.minutes,
  811.             f->ftimeLastWrite.twosecs*2,
  812.             m,
  813.             attrstr);
  814.  
  815.     WriteRequestEntry(formatbuffer);
  816.     }
  817.  
  818. void WriteRequestEntry(char *buffer)
  819.     {    
  820.     VioScrollUp(STARTROW,0,ENDROW,BORDERCOL-1,1,(char *)&BlankCell,VIOHDL); 
  821.     VioWrtCharStr((PCH)buffer,strlen(buffer),ENDROW,1,VIOHDL);  
  822.     }
  823.  
  824. const char *attrs = "--advshr";
  825.  
  826. unsigned attrvals[8] =
  827.     {
  828.     FILE_UNUSED1,    FILE_UNUSED0,    FILE_ARCHIVED,    FILE_DIRECTORY,
  829.     FILE_VOLLABEL,    FILE_SYSTEM,    FILE_HIDDEN,    FILE_READONLY
  830.     };
  831.  
  832.     /* sets the string to "-----" or "drhsa", etc. */
  833. void set_attribute_values(char *str, unsigned attribute)
  834.     {
  835.     unsigned i, attrvals = FILE_UNUSED1, len = strlen(attrs);
  836.  
  837.     memset(str,'-',len);      /* initialize attribute value string */
  838.     str[len] = '\0';
  839.     for( i = 0; i < len; i++, attrvals >>= 1)
  840.         if(attrvals & attribute)
  841.             str[i] = attrs[i];
  842.     }
  843.  
  844.     /******* end of print thread code *************************/
  845.  
  846.     /********************** end of dipop.c ********************/
  847.  
  848.