home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk10 / apps / ds / display.c next >
Encoding:
C/C++ Source or Header  |  1988-08-11  |  7.3 KB  |  298 lines

  1. /*  display.c - screen display stuff for tree */
  2.  
  3. #include <conio.h>
  4. #include <process.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. #include "ds.h"
  9. #include "vars.h"
  10.  
  11.  
  12. /*  External routines */
  13.  
  14. extern pruneTree (Directory **);
  15.  
  16.  
  17. /*  Local variables */
  18.  
  19. static char helpMsg[] = "Press F1 for Help";
  20.  
  21.  
  22. /***    getKey - return two-byte key stroke; includes IBM extended ASCII codes
  23. *
  24. *
  25. */
  26. unsigned int getKey ()
  27. {
  28.     char c;
  29.     unsigned int key;
  30.  
  31.     if (c = getch())            /* Get character */
  32.     key = c << 8;            /* Make scan code zero */
  33.     else
  34.     key = getch();            /* Get scan code */
  35. }   /* getKey */
  36.  
  37.  
  38. /***    screenInit - Initialize the screen
  39. *
  40. *
  41. */
  42. screenInit ()
  43. {
  44.     struct ModeData TheModeData;    /* Mode return data from VIOGETMODE */
  45.  
  46.     VIOGETMODE ((struct ModeData far *) &TheModeData, VioHandle);
  47.     N_of_Cols = TheModeData.col;
  48.     N_of_Rows = TheModeData.row;
  49.     WINDOW_RIGHT = N_of_Cols - 1;
  50.     WINDOW_BOTTOM = N_of_Rows - 1;
  51.     WINDOW_SIZE = WINDOW_BOTTOM - WINDOW_TOP + 1;
  52. }   /* screenInit */
  53.  
  54.  
  55. /***    handleDisplay - display tree and handel user keystrokes
  56. *
  57. *
  58. */
  59. handleDisplay (root)
  60. Directory   *root;
  61. {
  62.     int topRow;
  63.     unsigned int key;
  64.     char tmp[MAX_PATH_LEN];
  65.     char path[MAX_PATH_LEN];
  66.     int imageRow;
  67.     Directory *curDir,*lastDir,*p;
  68.     int rc;
  69.     char *commandPath;
  70.  
  71.     LastTopRow = LastRow-WINDOW_SIZE+1; /* Top row when last row displayed */
  72.                     /*   at the bottom of the window */
  73.     if (LastTopRow < 0)
  74.     LastTopRow = 0;
  75.  
  76.     topRow = 0;
  77.     displayWindow (WINDOW_TOP,topRow,WINDOW_SIZE);
  78.     curDir = root->d_child;
  79.     highlightDir (topRow, curDir, color[cursorC]);
  80.     key = 0;
  81.     while (key != exitKey) {
  82.     lastDir = curDir;
  83.     key = getKey();
  84.     switch (key) {
  85.         case optKey:
  86.         showOption ();
  87.         refreshDisplay (topRow, curDir);
  88.         break;
  89.         case helpKey:
  90.         showHelp ();
  91.         refreshDisplay (topRow, curDir);
  92.         break;
  93.         case enterKey:              /* Exec shell */
  94.         p = curDir;
  95.         path[0] = '\0';           /* Empty path */
  96.         while (p->d_parent) {          /* Process all but root */
  97.             strcpy (tmp, path);       /* Save path so far */
  98.             strcpy (path,"\\");       /* Put in separator */
  99.             strcat (path, p->d_name); /* Append directory name */
  100.             strcat (path, tmp);       /* Append rest of path so far */
  101.             p = p->d_parent;          /* Go up to parent */
  102.         }
  103.         strcpy (tmp, path);          /* Save tail of path */
  104.         strcpy (path, IntRootPath);   /* Get root path */
  105.         strcat (path, tmp);          /* Append tail of path */
  106.  
  107.         if (chdir(path) == -1)          /* Change directory failed */
  108.             pruneTree (&curDir);      /* Node is gone, update tree */
  109.         else {
  110.             commandPath = getenv ("COMSPEC");    /* Get shell path */
  111.             clearBottomLine ();
  112.             if (commandPath)
  113.             rc = spawnl(P_WAIT,commandPath,"COMMAND",NULL);
  114.             else
  115.             rc = spawnlp(P_WAIT,"COMMAND","COMMAND",NULL);
  116.             if (rc == -1) {          /* Exec failed */
  117.             perror ("\nCouldn't spawn shell");
  118.             exitError (2);
  119.             }
  120.             clearScreen ();
  121.         }
  122.         refreshDisplay (topRow, curDir);
  123.         break;
  124.         case upKey:               /* Go to previous sibling */
  125.         if (curDir->d_prev)          /* Previous sibling exists */
  126.             curDir = curDir->d_prev;  /* Go to previous sibling */
  127.         break;
  128.         case downKey:              /* Go to next sibling */
  129.         if (curDir->d_next)          /* Next sibling exists */
  130.             curDir = curDir->d_next;  /* Go to next sibling */
  131.         break;
  132.         case leftKey:        /* Go to parent */
  133.         if (curDir->d_parent->d_parent) /* Not top level directory */
  134.             curDir = curDir->d_parent;    /* Go to parent */
  135.         break;
  136.         case rightKey:        /* Go to first child */
  137.         if (curDir->d_child)    /* Child exists */
  138.             curDir = curDir->d_child;  /* Go to child */
  139.         break;
  140.         default:
  141.         break;
  142.     }   /* switch */
  143.     if (curDir != lastDir)
  144.         adjustWindow (&topRow, curDir, lastDir);
  145.     }    /* while */
  146. }   /* handleDisplay */
  147.  
  148.  
  149. /***    clearScreen - blank out the entire screen
  150. *
  151. *
  152. */
  153. clearScreen ()
  154. {
  155.     Cell c;
  156.  
  157.     c.ch = ' ';
  158.     c.at = color[blankC];
  159.     VIOWRTNCELL(cefs(&c), N_of_Rows*N_of_Cols, 0, 0, VioHandle);
  160.  
  161. }   /* clearScreen */
  162.  
  163.  
  164. /***    clearBottomLine - Clear the bottom line on the screen
  165. *
  166. *
  167. */
  168. clearBottomLine ()
  169. {
  170.     Cell c;
  171.  
  172.     c.ch = ' ';
  173.     c.at = color[blankC];
  174.     VIOWRTNCELL(cefs(&c), N_of_Cols, N_of_Rows-1,0, VioHandle);
  175.  
  176. }   /* clearBottomLine */
  177.  
  178.  
  179. /***    refreshDisplay - Repaint the main screen
  180. *
  181. *
  182. */
  183. refreshDisplay (topRow, curDir)
  184. int topRow;
  185. Directory *curDir;
  186. {
  187.     int col;
  188.     char buf[MAX_PATH_LEN];
  189.     int lStr;
  190.     Cell c;
  191.     Attr a;
  192.  
  193.     c.ch = '[';
  194.     c.at = color[statusC];
  195.     VIOWRTNCELL(cefs(&c), 1, 0,0, VioHandle);
  196.  
  197.     lStr = strlen(RootPath);
  198.     a = color[nameC];
  199.     VIOWRTCHARSTRATT (chfs(RootPath), lStr, 0,1, afs(&a), VioHandle);
  200.  
  201.     c.ch = ']';
  202.     c.at = color[statusC];
  203.     VIOWRTNCELL(cefs(&c), 1, 0,lStr+1, VioHandle);
  204.  
  205.     lStr = strlen(helpMsg);
  206.     col = N_of_Cols - lStr;
  207.     a = color[statusC];
  208.     VIOWRTCHARSTRATT (chfs(helpMsg), lStr, 0,col, afs(&a), VioHandle);
  209.  
  210.     if (topRow >= 0) {
  211.     displayWindow (WINDOW_TOP,topRow,WINDOW_SIZE);
  212.     highlightDir (topRow, curDir, color[cursorC]);
  213.     }
  214.     VIOSETCURPOS (N_of_Rows-1, N_of_Cols-1, VioHandle); /* Hide cursor */
  215. }
  216.  
  217.  
  218. /***    adjustWindow - Repaint tree with minimum screen writing
  219. *
  220. *
  221. */
  222. adjustWindow (topRow, curDir, lastDir)
  223. int *topRow;
  224. Directory *curDir;
  225. Directory *lastDir;
  226. {
  227.     int botRow, cRow, lRow;
  228.  
  229.     botRow = *topRow + WINDOW_SIZE - 1;
  230.     cRow = curDir->d_row;
  231.     lRow = lastDir->d_row;
  232.     if ((*topRow <= cRow) && (cRow <= botRow)) { /* Window doesn't move */
  233.     highlightDir (*topRow, lastDir, color[nameC]);    /* Turn off old cursor */
  234.     highlightDir (*topRow, curDir, color[cursorC]); /* Turn on new cursor */
  235.     }
  236.     else if ((cRow <= *topRow - WINDOW_SIZE) ||
  237.         (botRow + WINDOW_SIZE <= cRow)) {    /* Repaint entire window */
  238.     *topRow = (cRow < LastTopRow) ? cRow : LastTopRow;
  239.     displayWindow (WINDOW_TOP,*topRow,WINDOW_SIZE);
  240.     highlightDir (*topRow, curDir, color[cursorC]);
  241.     }
  242.     else {                    /* Can do a scroll */
  243.     if (cRow < lRow)    /* Pretend scroll up */
  244.         *topRow = (cRow < LastTopRow) ? cRow : LastTopRow;
  245.     else {            /* Pretend scroll down */
  246.         cRow = cRow - WINDOW_SIZE + 1;
  247.         *topRow = cRow ? cRow : 0;
  248.     }
  249.     displayWindow (WINDOW_TOP,*topRow,WINDOW_SIZE);
  250.     highlightDir (*topRow, curDir, color[cursorC]);
  251.     }
  252. }   /* adjustWindow */
  253.  
  254.  
  255. /***    highlightDir - Highlight the currently selected directory
  256. *
  257. *
  258. */
  259. highlightDir (topRow, p, color)
  260. int topRow;
  261. Directory *p;
  262. int color;
  263. {
  264.     int dLen,cCol,cRow;
  265.     Attr a;
  266.  
  267.     cRow = WINDOW_TOP + p->d_row - topRow;
  268.     cCol = p->d_col;
  269.  
  270.     dLen = strlen(p->d_name);
  271.     a = color;
  272.     VIOWRTNATTR (afs(&a), dLen, cRow, cCol, VioHandle);
  273.  
  274. }   /* highlightDir */
  275.  
  276.  
  277. /***    displayWindow - Displaya a portion of the tree in the tree window
  278. *
  279. *
  280. */
  281. displayWindow (screenRow,imageRow,count)
  282. int screenRow,imageRow,count;
  283. {
  284.     int row;
  285.     Cell c;
  286.  
  287.     while (count-- && (imageRow <= LastRow)) {
  288.     VIOWRTCELLSTR (cefs(DisplayRow[imageRow]), N_of_Cols*sizeof(Cell),
  289.                screenRow,0, VioHandle);
  290.     screenRow++;
  291.     imageRow++;
  292.     }
  293.     c.ch = ' ';
  294.     c.at = color[blankC];
  295.     for (row=screenRow; row<N_of_Rows; row++)    /* Clear remaining lines */
  296.     VIOWRTNCELL (cefs(&c), N_of_Cols, row,0, VioHandle);
  297. }   /* displayWindow */
  298.