home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xv310a / xvctrl.c < prev    next >
C/C++ Source or Header  |  1995-06-12  |  27KB  |  889 lines

  1. /* 
  2.  * xvctrl.c - Control box handling functions
  3.  *
  4.  * callable functions:
  5.  *
  6.  *   CreateCtrl(geom)       -  creates the ctrlW window.  Doesn't map it.
  7.  *   CtrlBox(vis)           -  random processing based on value of 'vis'
  8.  *                             maps/unmaps window, etc.
  9.  *   RedrawCtrl(x,y,w,h)    -  called by 'expose' events
  10.  *   ClickCtrl(x,y)
  11.  *   DrawCtrlStr()          -  called to redraw 'ISTR_INFO' string in ctrlW
  12.  *   ScrollToCurrent()      -  called when list selection is changed 
  13.  *
  14.  *   LSCreate()             -  creates a listbox
  15.  *   LSRedraw()             -  redraws 'namelist' box
  16.  *   LSClick()              -  operates list box
  17.  *   LSChangeData()         -  like LSNewData(), but tries not to repos list
  18.  *   LSNewData()            -  called when strings or number of them change
  19.  *   LSKey()                -  called to handle page up/down, arrows
  20.  *
  21.  */
  22.  
  23. #include "copyright.h"
  24.  
  25. #include "xv.h"
  26.  
  27. #include "bits/gray25"
  28. #include "bits/gray50"
  29. #include "bits/i_fifo"
  30. #include "bits/i_chr"
  31. #include "bits/i_dir"
  32. #include "bits/i_blk"
  33. #include "bits/i_lnk"
  34. #include "bits/i_sock"
  35. #include "bits/i_exe"
  36. #include "bits/i_reg"
  37. #include "bits/h_rotl"
  38. #include "bits/h_rotr"
  39. #include "bits/fliph"
  40. #include "bits/flipv"
  41. #include "bits/p10"
  42. #include "bits/m10"
  43. #include "bits/cut"
  44. #include "bits/copy"
  45. #include "bits/clear"
  46. #include "bits/paste"
  47. #include "bits/padimg"
  48. #include "bits/annot"
  49. #include "bits/uicon"
  50. #include "bits/oicon1"
  51. #include "bits/oicon2"
  52. #include "bits/icon"
  53.  
  54. #define CTRLWIDE 440               /* (fixed) size of control window */
  55. #define CTRLHIGH 348 /* 379 */
  56.  
  57. #define DBLCLKTIME 500             /* double-click speed in milliseconds */
  58.  
  59. #define INACTIVE(lptr, item) ((lptr)->filetypes && (lptr)->dirsonly && \
  60.                   (item) >= 0 && (item) < (lptr)->nstr && \
  61.                   (lptr)->str[(item)][0] != C_DIR && \
  62.                   (lptr)->str[(item)][0] != C_LNK)
  63.  
  64. #define NLINES  11                 /* # of lines in list control (keep odd) */
  65.  
  66. #define BUTTW   71                 /* keep odd for 'half' buttons to work   */
  67. #define BUTTH   24
  68. #define SBUTTH  21
  69.  
  70. static int    ptop;                /* y-coord of top of button area in ctrlW */
  71.  
  72. static Pixmap fifoPix, chrPix, dirPix, blkPix, lnkPix, sockPix, exePix, regPix;
  73. static Pixmap rotlPix, rotrPix, fliphPix, flipvPix, p10Pix, m10Pix;
  74. static Pixmap cutPix, copyPix, pastePix, clearPix, oiconPix, uiconPix;
  75. static Pixmap padPix, annotPix;
  76.  
  77. static XRectangle butrect;
  78.  
  79. /* NOTE: make these string arrays match up with their respective #defines
  80.    in xv.h */
  81.  
  82.  
  83. static char *dispMList[] = { "Raw\tr", 
  84.                  "Dithered\td",
  85.                  "Smooth\ts",
  86.                  MBSEP,
  87.                  "Read/Write Colors",
  88.                  MBSEP,
  89.                  "Normal Colors",
  90.                  "Perfect Colors",
  91.                  "Use Own Colormap",
  92.                  "Use Std. Colormap" };
  93.  
  94. static char *rootMList[] = { "Window", 
  95.                  "Root: tiled",
  96.                  "Root: integer tiled",
  97.                  "Root: mirrored",
  98.                  "Root: integer mirrored",
  99.                  "Root: center tiled",
  100.                  "Root: centered",
  101.                  "Root: centered, warp",
  102.                  "Root: centered, brick",
  103.                          "Root: symmetrical tiled",
  104.                  "Root: symmetrical mirrored" };
  105.  
  106. static char *conv24MList[] = { "8-bit mode\t\2448",
  107.                    "24-bit mode\t\2448",
  108.                    MBSEP,
  109.                    "Lock current mode",
  110.                    MBSEP,
  111.                                "Quick 24->8",
  112.                    "Slow 24->8",
  113.                    "Best 24->8" };
  114.  
  115. static char *algMList[]    = { "Undo All\t\244u",
  116.                    MBSEP,
  117.                     "Blur...\t\244b",
  118.                    "Sharpen...\t\244s",
  119.                    "Edge Detect\t\244e",
  120.                    "Emboss\t\244m",
  121.                    "Oil Painting\t\244o",
  122.                    "Blend\t\244B",
  123.                    "Copy Rotate...\t\244t",
  124.                    "Clear Rotate...\t\244T",
  125.                    "Pixelize...\t\244p",
  126.                    "Spread...\t\244S",
  127.                    "DeSpeckle...\t\244k"};
  128.  
  129. static char *sizeMList[]   = { "Normal\tn",
  130.                    "Max Size\tm",
  131.                    "Maxpect\tM",
  132.                    "Double Size\t>",
  133.                    "Half Size\t<",
  134.                    "10% Larger\t.",
  135.                    "10% Smaller\t,",
  136.                    MBSEP,
  137.                    "Set Size\tS",
  138.                    "Re-Aspect\ta",
  139.                    "4x3\t4",
  140.                    "Int. Expand\tI" };
  141.  
  142. static char *windowMList[] = { "Visual Schnauzer\t^v",
  143.                    "Color Editor\te",
  144.                    "Image Info\ti",
  145.                    "Image Comments\t^c",
  146.                    "Text View\t^t",
  147.                    MBSEP,
  148.                    "About XV\t^a",
  149.                    "XV Keyboard Help"};
  150.  
  151.  
  152.  
  153. static void drawSel      PARM((LIST *, int));
  154. static void RedrawNList  PARM((int, SCRL *));
  155. static void ls3d         PARM((LIST *));
  156.  
  157.  
  158. /***************************************************/
  159. void CreateCtrl(geom)
  160.      char *geom;
  161. {
  162.   int i, listh, topskip;
  163.   double skip;
  164.   XSetWindowAttributes xswa;
  165.   Pixmap oicon1Pix, oicon2Pix;
  166.  
  167.   ctrlW = CreateWindow("xv controls", "XVcontrols", geom, 
  168.                CTRLWIDE, CTRLHIGH, infofg, infobg, 0);
  169.   if (!ctrlW) FatalError("can't create controls window!");
  170.  
  171. #ifdef BACKING_STORE
  172.   xswa.backing_store = WhenMapped;
  173.   XChangeWindowAttributes(theDisp, ctrlW, CWBackingStore, &xswa);
  174. #endif
  175.  
  176.   grayTile = XCreatePixmapFromBitmapData(theDisp, rootW, (char *) gray25_bits,
  177.            gray25_width, gray25_height, infofg, infobg, dispDEEP);
  178.  
  179.   dimStip  = MakePix1(ctrlW, gray50_bits, gray50_width, gray50_height);
  180.   fifoPix  = MakePix1(ctrlW, i_fifo_bits, i_fifo_width, i_fifo_height);
  181.   chrPix   = MakePix1(ctrlW, i_chr_bits,  i_chr_width,  i_chr_height);
  182.   dirPix   = MakePix1(ctrlW, i_dir_bits,  i_dir_width,  i_dir_height);
  183.   blkPix   = MakePix1(ctrlW, i_blk_bits,  i_blk_width,  i_blk_height);
  184.   lnkPix   = MakePix1(ctrlW, i_lnk_bits,  i_lnk_width,  i_lnk_height);
  185.   sockPix  = MakePix1(ctrlW, i_sock_bits, i_sock_width, i_sock_height);
  186.   exePix   = MakePix1(ctrlW, i_exe_bits,  i_exe_width,  i_exe_height);
  187.   regPix   = MakePix1(ctrlW, i_reg_bits,  i_reg_width,  i_reg_height);
  188.   rotlPix  = MakePix1(ctrlW, h_rotl_bits, h_rotl_width, h_rotl_height);
  189.   rotrPix  = MakePix1(ctrlW, h_rotr_bits, h_rotr_width, h_rotr_height);
  190.   fliphPix = MakePix1(ctrlW, fliph_bits,  fliph_width,  fliph_height);
  191.   flipvPix = MakePix1(ctrlW, flipv_bits,  flipv_width,  flipv_height);
  192.   p10Pix   = MakePix1(ctrlW, p10_bits,    p10_width,    p10_height);
  193.   m10Pix   = MakePix1(ctrlW, m10_bits,    m10_width,    m10_height);
  194.   cutPix   = MakePix1(ctrlW, cut_bits,    cut_width,    cut_height);
  195.   copyPix  = MakePix1(ctrlW, copy_bits,   copy_width,   copy_height);
  196.   pastePix = MakePix1(ctrlW, paste_bits,  paste_width,  paste_height);
  197.   clearPix = MakePix1(ctrlW, clear_bits,  clear_width,  clear_height);
  198.   uiconPix = MakePix1(ctrlW, uicon_bits,  uicon_width,  uicon_height);
  199.   padPix   = MakePix1(ctrlW, padimg_bits, padimg_width, padimg_height);
  200.   annotPix = MakePix1(ctrlW, annot_bits,  annot_width,  annot_height);
  201.  
  202.   /* make multi-plane oiconPix pixmap */
  203.   oiconPix = XCreatePixmap(theDisp,rootW,oicon1_width,oicon1_height,dispDEEP);
  204.   oicon1Pix = MakePix1(ctrlW, oicon1_bits,  oicon1_width,  oicon1_height);
  205.   oicon2Pix = MakePix1(ctrlW, oicon2_bits,  oicon2_width,  oicon2_height);
  206.  
  207.   if (!grayTile  || !dimStip  || !fifoPix   || !chrPix    || !dirPix    ||
  208.       !blkPix    || !lnkPix   || !regPix    || !rotlPix   || !fliphPix  || 
  209.       !flipvPix  || !p10Pix   || !m10Pix    || !cutPix    || !copyPix   ||
  210.       !pastePix  || !clearPix || !uiconPix  || !oiconPix  || !oicon1Pix ||
  211.       !oicon2Pix || !padPix   || !annotPix) 
  212.     FatalError("unable to create all pixmaps in CreateCtrl()\n");
  213.  
  214.  
  215.   /* build multi-color XV pixmap */
  216.   XSetForeground(theDisp, theGC, infobg);
  217.   XFillRectangle(theDisp, oiconPix, theGC, 0,0,oicon1_width,oicon1_height);
  218.   XSetFillStyle(theDisp, theGC, FillStippled);
  219.   XSetStipple(theDisp, theGC, oicon1Pix);
  220.   XSetForeground(theDisp, theGC, (ctrlColor) ? locol : infofg);
  221.   XFillRectangle(theDisp, oiconPix, theGC, 0,0,oicon1_width,oicon1_height);
  222.   XSetStipple(theDisp, theGC, oicon2Pix);
  223.   XSetForeground(theDisp, theGC, (ctrlColor) ? infofg : infofg);
  224.   XFillRectangle(theDisp, oiconPix, theGC, 0,0,oicon1_width,oicon1_height);
  225.   XSetFillStyle(theDisp, theGC, FillSolid);
  226.   XFreePixmap(theDisp, oicon1Pix);
  227.   XFreePixmap(theDisp, oicon2Pix);
  228.  
  229.   
  230.  
  231.   if (ctrlColor) XSetWindowBackground(theDisp, ctrlW, locol);
  232.             else XSetWindowBackgroundPixmap(theDisp, ctrlW, grayTile);
  233.  
  234.   listh = LINEHIGH * NLINES;
  235.  
  236.   LSCreate(&nList, ctrlW, 5, 52, (CTRLWIDE-BUTTW-18),
  237.        LINEHIGH*NLINES, NLINES, dispnames, numnames, 
  238.        infofg, infobg, hicol, locol, RedrawNList, 0, 0);
  239.   nList.selected = 0;  /* default to first name selected */
  240.  
  241.  
  242. #define BCLS infofg, infobg, hicol, locol
  243.  
  244.   /* expressions for positioning right-side buttons */
  245.  
  246.   topskip = nList.y;
  247.   skip =  ((double) (nList.h - (CHIGH+5))) / 6.0;
  248.   if (skip > SBUTTH+8) {  
  249.     skip = SBUTTH + 7;  
  250.     topskip = nList.y + (nList.h - (6*skip + (CHIGH+5))) / 2;
  251.   }
  252.  
  253. #define R_BW1 BUTTW
  254. #define R_BX0 (CTRLWIDE - R_BW1 - 1 - 5)
  255. #define R_BY0 (topskip)
  256. #define R_BY1 (topskip + (int)(1*skip))
  257. #define R_BY2 (topskip + (int)(2*skip))
  258. #define R_BY3 (topskip + (int)(3*skip))
  259. #define R_BY4 (topskip + (int)(4*skip))
  260. #define R_BY5 (topskip + (int)(5*skip))
  261.   
  262.   BTCreate(&but[BNEXT],    ctrlW, R_BX0, R_BY0, R_BW1, SBUTTH, "Next",   BCLS);
  263.   BTCreate(&but[BPREV],    ctrlW, R_BX0, R_BY1, R_BW1, SBUTTH, "Prev",   BCLS);
  264.   BTCreate(&but[BLOAD],    ctrlW, R_BX0, R_BY2, R_BW1, SBUTTH, "Load",   BCLS);
  265.   BTCreate(&but[BSAVE],    ctrlW, R_BX0, R_BY3, R_BW1, SBUTTH, "Save",   BCLS);
  266.   BTCreate(&but[BPRINT],   ctrlW, R_BX0, R_BY4, R_BW1, SBUTTH, "Print",  BCLS);
  267.   BTCreate(&but[BDELETE],  ctrlW, R_BX0, R_BY5, R_BW1, SBUTTH, "Delete", BCLS);
  268.  
  269.  
  270.   /* expressions for positioning bottom buttons (6x2 array) */
  271.  
  272. #define BXSPACE (BUTTW+1)
  273. #define BYSPACE (BUTTH+1)
  274.  
  275.   ptop = CTRLHIGH - (2*BYSPACE + 5 + 4);
  276.  
  277. #define BX0 ((CTRLWIDE - (BXSPACE*6))/2)
  278. #define BX1 (BX0 + BXSPACE)
  279. #define BX2 (BX0 + BXSPACE*2)
  280. #define BX3 (BX0 + BXSPACE*3)
  281. #define BX4 (BX0 + BXSPACE*4)
  282. #define BX5 (BX0 + BXSPACE*5)
  283. #define BY0 (ptop+5)
  284. #define BY1 (BY0 + BYSPACE)
  285.  
  286.   butrect.x = BX0-1;  butrect.y = BY0-1;
  287.   butrect.width = 6*BXSPACE + 1;
  288.   butrect.height = 2*BYSPACE + 1;
  289.  
  290.   BTCreate(&but[BCOPY],  ctrlW,BX0,            BY0,BUTTW/2,BUTTH, "",    BCLS);
  291.   BTCreate(&but[BCUT],   ctrlW,BX0+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH, "",    BCLS);
  292.   BTCreate(&but[BPASTE], ctrlW,BX1,            BY0,BUTTW/2,BUTTH, "",    BCLS);
  293.   BTCreate(&but[BCLEAR], ctrlW,BX1+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH, "",    BCLS);
  294.   BTCreate(&but[BDN10],  ctrlW,BX2,            BY0,BUTTW/2,BUTTH, "",    BCLS);
  295.   BTCreate(&but[BUP10],  ctrlW,BX2+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH, "",    BCLS);
  296.   BTCreate(&but[BROTL],  ctrlW,BX3,            BY0,BUTTW/2,BUTTH, "",    BCLS);
  297.   BTCreate(&but[BROTR],  ctrlW,BX3+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH, "",    BCLS);
  298.   BTCreate(&but[BFLIPH], ctrlW,BX4,            BY0,BUTTW/2,BUTTH, "",    BCLS);
  299.   BTCreate(&but[BFLIPV], ctrlW,BX4+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH, "",    BCLS);
  300.   BTCreate(&but[BGRAB],  ctrlW,BX5,            BY0,BUTTW,  BUTTH, "Grab",BCLS);
  301.  
  302.  
  303.   BTCreate(&but[BPAD],    ctrlW,BX0,          BY1,BUTTW/2,BUTTH,"",BCLS);
  304.   BTCreate(&but[BANNOT],  ctrlW,BX0+BUTTW/2+1,BY1,BUTTW/2,BUTTH,"",BCLS);
  305.  
  306.   BTCreate(&but[BCROP],   ctrlW,BX1,  BY1,BUTTW,BUTTH,"Crop",    BCLS);
  307.   BTCreate(&but[BUNCROP], ctrlW,BX2,  BY1,BUTTW,BUTTH,"UnCrop",  BCLS);
  308.   BTCreate(&but[BACROP],  ctrlW,BX3,  BY1,BUTTW,BUTTH,"AutoCrop",BCLS);
  309.   BTCreate(&but[BABOUT],  ctrlW,BX4,  BY1,BUTTW,BUTTH,"About XV",BCLS);
  310.   BTCreate(&but[BQUIT],   ctrlW,BX5,  BY1,BUTTW,BUTTH,"Quit",    BCLS);
  311.  
  312.   BTCreate(&but[BXV],     ctrlW,5,5, 100, (u_int) nList.y - 5 - 2 - 5, 
  313.        "", BCLS);
  314.  
  315.   SetButtPix(&but[BCOPY],  copyPix,  copy_width,   copy_height);
  316.   SetButtPix(&but[BCUT],   cutPix,   cut_width,    cut_height);
  317.   SetButtPix(&but[BPASTE], pastePix, paste_width,  paste_height);
  318.   SetButtPix(&but[BCLEAR], clearPix, clear_width,  clear_height);
  319.   SetButtPix(&but[BUP10],  p10Pix,   p10_width,    p10_height);
  320.   SetButtPix(&but[BDN10],  m10Pix,   m10_width,    m10_height);
  321.   SetButtPix(&but[BROTL],  rotlPix,  h_rotl_width, h_rotl_height);
  322.   SetButtPix(&but[BROTR],  rotrPix,  h_rotr_width, h_rotr_height);
  323.   SetButtPix(&but[BFLIPH], fliphPix, fliph_width,  fliph_height);
  324.   SetButtPix(&but[BFLIPV], flipvPix, flipv_width,  flipv_height);
  325.   SetButtPix(&but[BPAD],   padPix,   padimg_width, padimg_height);
  326.   SetButtPix(&but[BANNOT], annotPix, annot_width,  annot_height);
  327.  
  328. #ifdef REGSTR
  329.   if (ctrlColor) {
  330.     SetButtPix(&but[BXV], oiconPix, oicon1_width,  oicon1_height);
  331.     but[BXV].colorpix = 1;
  332.   } 
  333.   else SetButtPix(&but[BXV], iconPix, icon_width,  icon_height);
  334. #else
  335.   SetButtPix(&but[BXV], uiconPix, uicon_width,  uicon_height);
  336. #endif
  337.  
  338.   XMapSubwindows(theDisp, ctrlW);
  339.  
  340.  
  341.   /* have to create menu buttons after XMapSubWindows, as we *don't* want 
  342.      the popup menus mapped */
  343.  
  344.   MBCreate(&dispMB,   ctrlW, CTRLWIDE - 8 - 112 - 2*(112+2), 5,112,19, 
  345.        "Display",    dispMList,   DMB_MAX,    BCLS);
  346.   MBCreate(&conv24MB, ctrlW, CTRLWIDE - 8 - 112 - (112+2),   5,112,19, 
  347.        "24/8 Bit",   conv24MList, CONV24_MAX, BCLS);
  348.   MBCreate(&algMB,    ctrlW, CTRLWIDE - 8 - 112,             5,112,19, 
  349.        "Algorithms", algMList,    ALG_MAX,    BCLS);
  350.  
  351.   MBCreate(&rootMB,   ctrlW, CTRLWIDE - 8 - 112 - 2*(112+2), 5+21,112,19, 
  352.        "Root",       rootMList,   RMB_MAX,    BCLS);
  353.   MBCreate(&windowMB, ctrlW, CTRLWIDE - 8 - 112 - (112+2),   5+21,112,19, 
  354.        "Windows",    windowMList, WMB_MAX,    BCLS);
  355.   MBCreate(&sizeMB,   ctrlW, CTRLWIDE - 8 - 112,             5+21,112,19, 
  356.        "Image Size", sizeMList,   SZMB_MAX,   BCLS);
  357.  
  358.  
  359.  
  360. #undef BCLS
  361.  
  362.  
  363.   /* set up initial state for various controls */
  364.  
  365.   but[BXV].w = dispMB.x - 5 - but[BXV].x;
  366.  
  367.   dispMB.flags[DMB_COLRW] = (allocMode == AM_READWRITE);
  368.   dispMB.flags[colorMapMode + DMB_COLNORM - CM_NORMAL] = 1;
  369.  
  370.   conv24MB.flags[conv24] = 1;
  371.  
  372.   if (!useroot) dispMode = RMB_WINDOW;
  373.            else dispMode = rootMode + (RMB_ROOT - RM_NORMAL);
  374.   rootMB.flags[dispMode] = 1;
  375.  
  376.   windowMB.dim[WMB_TEXTVIEW] = (numnames<1);
  377.  
  378.   BTSetActive(&but[BDELETE], (numnames>=1));
  379. }
  380.  
  381. /***************************************************/
  382. void SetButtPix(bp, pix, w,h)
  383.      BUTT *bp;
  384.      Pixmap pix;
  385.      int    w,h;
  386. {
  387.   if (!bp) return;
  388.   bp->pix = pix;  bp->pw = w;  bp->ph = h;
  389. }
  390.  
  391.  
  392. /***************************************************/
  393. Pixmap MakePix1(win, bits, w, h)
  394.      Window win;
  395.      byte *bits;
  396.      int   w,h;
  397. {
  398.   return XCreatePixmapFromBitmapData(theDisp, win, (char *) bits, 
  399.                      (u_int) w, (u_int) h, 1L,0L,1);
  400. }
  401.  
  402.  
  403. /***************************************************/
  404. void CtrlBox(vis)
  405. int vis;
  406. {
  407.   if (vis) XMapRaised(theDisp, ctrlW);  
  408.   else     XUnmapWindow(theDisp, ctrlW);
  409.  
  410.   ctrlUp = vis;
  411. }
  412.  
  413.  
  414. /***************************************************/
  415. void RedrawCtrl(x,y,w,h)
  416. int x,y,w,h;
  417. {
  418.   int i;
  419.   XRectangle xr;
  420.  
  421.   RANGE(w, 0, CTRLWIDE);
  422.   RANGE(h, 0, CTRLHIGH);
  423.  
  424. #ifdef CLIPRECT
  425.   xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
  426.   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
  427. #endif
  428.  
  429.   DrawCtrlNumFiles();
  430.  
  431.   XSetForeground(theDisp,theGC,infofg);
  432.   XDrawRectangles(theDisp, ctrlW, theGC, &butrect, 1);
  433.  
  434.   for (i=0; i<NBUTTS; i++)
  435.     BTRedraw(&but[i]);
  436.  
  437.   MBRedraw(&dispMB);
  438.   MBRedraw(&conv24MB);
  439.   MBRedraw(&algMB);
  440.   MBRedraw(&rootMB);
  441.   MBRedraw(&windowMB);
  442.   MBRedraw(&sizeMB);
  443.  
  444.   DrawCtrlStr();
  445.  
  446. #ifdef CLIPRECT
  447.   XSetClipMask(theDisp, theGC, None);
  448. #endif
  449. }
  450.  
  451.  
  452. /***************************************************/
  453. void DrawCtrlNumFiles()
  454. {
  455.   int x,y,w,h;
  456.   char foo[40];
  457.  
  458.   x  = but[BNEXT].x;
  459.   y  = nList.y + nList.h - (CHIGH+5);
  460.   w  = but[BNEXT].w;
  461.  
  462.   XSetForeground(theDisp, theGC, infofg);
  463.   XSetBackground(theDisp, theGC, infobg);
  464.  
  465.   sprintf(foo, "%d file%s", numnames, (numnames==1) ? "" : "s");
  466.     
  467.   XSetForeground(theDisp, theGC, infobg);
  468.   XFillRectangle(theDisp,ctrlW, theGC, x+1,y+1, (u_int) w-1, (u_int) CHIGH+5);
  469.  
  470.   XSetForeground(theDisp,theGC,infofg);
  471.   XDrawRectangle(theDisp,ctrlW, theGC, x,y,     (u_int) w,   (u_int) CHIGH+6);
  472.  
  473.   Draw3dRect(ctrlW, x+1,y+1,                    (u_int) w-2, (u_int) CHIGH+4, 
  474.          R3D_IN, 2, hicol, locol, infobg);
  475.  
  476.   XSetForeground(theDisp,theGC,infofg);
  477.   CenterString(ctrlW, x+w/2, y+(CHIGH+6)/2, foo);
  478. }
  479.  
  480.  
  481. /***************************************************/
  482. void DrawCtrlStr()
  483. {
  484.   int   y;
  485.   char *st,*st1;
  486.  
  487.   y = ptop - (CHIGH + 4)*2 - 2;
  488.   st  = GetISTR(ISTR_INFO);
  489.   st1 = GetISTR(ISTR_WARNING);
  490.  
  491.   XSetForeground(theDisp, theGC, infobg);
  492.   XFillRectangle(theDisp, ctrlW, theGC, 0, y+1, 
  493.          CTRLWIDE, (u_int)((CHIGH+4)*2+1));
  494.  
  495.   XSetForeground(theDisp, theGC, infofg);
  496.   XDrawLine(theDisp, ctrlW, theGC, 0, y,   CTRLWIDE, y);
  497.   XDrawLine(theDisp, ctrlW, theGC, 0, y+CHIGH+4, CTRLWIDE, y+CHIGH+4);
  498.   XDrawLine(theDisp, ctrlW, theGC, 0, y+(CHIGH+4)*2, CTRLWIDE, y+(CHIGH+4)*2);
  499.  
  500.   if (ctrlColor) {
  501.     XSetForeground(theDisp, theGC, locol);
  502.     XDrawLine(theDisp, ctrlW, theGC, 0, y+1,   CTRLWIDE, y+1);
  503.     XDrawLine(theDisp, ctrlW, theGC, 0, y+CHIGH+5, CTRLWIDE, y+CHIGH+5);
  504.     XDrawLine(theDisp, ctrlW, theGC, 0, y+(CHIGH+4)*2+1, 
  505.           CTRLWIDE, y+(CHIGH+4)*2+1);
  506.   }
  507.  
  508.   if (ctrlColor) XSetForeground(theDisp, theGC, hicol);
  509.   XDrawLine(theDisp, ctrlW, theGC, 0, y+2, CTRLWIDE, y+2);
  510.   XDrawLine(theDisp, ctrlW, theGC, 0, y+CHIGH+6, CTRLWIDE, y+CHIGH+6);
  511.   if (ctrlColor) XSetForeground(theDisp, theGC, infobg);
  512.   XDrawLine(theDisp, ctrlW, theGC, 0, ptop, CTRLWIDE, ptop);
  513.  
  514.   XSetForeground(theDisp, theGC, infofg);
  515.   DrawString(ctrlW, 10, y+ASCENT+3,       st);
  516.   DrawString(ctrlW, 10, y+ASCENT+CHIGH+7, st1);
  517. }
  518.  
  519.  
  520. /***************************************************/
  521. int ClickCtrl(x,y)
  522. int x,y;
  523. {
  524.   BUTT *bp;
  525.   int   i;
  526.  
  527.   for (i=0; i<NBUTTS; i++) {
  528.     bp = &but[i];
  529.     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
  530.   }
  531.  
  532.   if (i<NBUTTS) {                   /* found one */
  533.     if (BTTrack(bp)) return (i);    /* and it was clicked */
  534.   }
  535.  
  536.   return -1;
  537. }
  538.  
  539.  
  540.  
  541. /***************************************************/
  542. void ScrollToCurrent(lst)
  543. LIST *lst;
  544. {
  545.   /* called when selected item on list is changed.  Makes the selected 
  546.      item visible.  If it already is, nothing happens.  Otherwise, it
  547.      attempts to scroll so that the selection appears in the middle of 
  548.      the list window */
  549.  
  550.   int halfway;
  551.  
  552.   if (lst->selected < 0) return;  /* no selection, do nothing */
  553.  
  554.   if (lst->selected > lst->scrl.val && 
  555.       lst->selected <  lst->scrl.val + lst->nlines-1) LSRedraw(lst, 0);
  556.   else {
  557.     halfway = (lst->nlines)/2;   /* offset to the halfway pt. of the list */
  558.     if (!SCSetVal(&lst->scrl, lst->selected - halfway)) LSRedraw(lst, 0);
  559.   }
  560. }
  561.  
  562.  
  563. /***************************************************/
  564. static void RedrawNList(delta, sptr)
  565.      int delta;
  566.      SCRL *sptr;
  567. {
  568.   LSRedraw(&nList, delta);
  569. }
  570.  
  571.  
  572.  
  573.  
  574. /***************** LIST STUFF *********************/
  575.  
  576. /***************************************************/
  577. void LSCreate(lp, win, x, y, w, h, nlines, strlist, nstr, fg, bg, hi, lo,
  578.           fptr, typ, donly)
  579. LIST         *lp;
  580. Window        win;
  581. int           x,y,w,h,nlines,nstr,typ,donly;
  582. unsigned long fg, bg, hi, lo;
  583. char        **strlist;    /* a pointer to a list of strings */
  584.  
  585. void        (*fptr)PARM((int,SCRL *));
  586.  
  587. {
  588.   if (ctrlColor) h += 4;
  589.  
  590.   lp->win = XCreateSimpleWindow(theDisp,win,x,y,(u_int) w, (u_int) h,1,fg,bg);
  591.   if (!lp->win) FatalError("can't create list window!");
  592.  
  593.   lp->x = x;    lp->y = y;   
  594.   lp->w = w;    lp->h = h;
  595.   lp->fg = fg;  lp->bg = bg;
  596.   lp->hi = hi;  lp->lo = lo;
  597.   lp->str      = strlist;
  598.   lp->nstr     = nstr;
  599.   lp->selected = -1;   /* no initial selection */
  600.   lp->nlines   = nlines;
  601.   lp->filetypes= typ;
  602.   lp->dirsonly = donly;
  603.  
  604.   XSelectInput(theDisp, lp->win, ExposureMask | ButtonPressMask);
  605.  
  606.   SCCreate(&lp->scrl, lp->win, w-20, -1, 1, h, 0, 
  607.        nstr-nlines, 0, nlines-1, fg, bg, hi, lo, fptr);
  608.  
  609.   XMapSubwindows(theDisp, lp->win);
  610. }
  611.  
  612.  
  613.  
  614. /***************************************************/
  615. void LSChangeData(lp, strlist, nstr)
  616. LIST         *lp;
  617. char        **strlist;
  618. int           nstr;
  619. {
  620.   /* tries to keep list selection and scrollbar in same place, if possible */
  621.  
  622.   lp->str = strlist;
  623.   lp->nstr = nstr;
  624.   if (lp->selected >= nstr) lp->selected = -1;
  625.  
  626.   RANGE(lp->scrl.val, 0, nstr - lp->nlines);
  627.   SCSetRange(&lp->scrl, 0, nstr - lp->nlines, lp->scrl.val, lp->nlines-1);
  628. }
  629.  
  630.  
  631. /***************************************************/
  632. void LSNewData(lp, strlist, nstr)
  633. LIST         *lp;
  634. char        **strlist;
  635. int           nstr;
  636. {
  637.   lp->str = strlist;
  638.   lp->nstr = nstr;
  639.   lp->selected = -1;   /* no initial selection */
  640.   SCSetRange(&lp->scrl, 0, nstr - lp->nlines, 0, lp->nlines-1);
  641. }
  642.  
  643.  
  644. /***************************************************/
  645. static void ls3d(lp)
  646. LIST *lp;
  647. {
  648.   /* redraws lists 3d-effect, which can be trounced by drawSel() */
  649.   Draw3dRect(lp->win, 0, 0, lp->w-1, lp->h-1, R3D_IN, 2, 
  650.          lp->hi, lp->lo, lp->bg);
  651. }
  652.  
  653.  
  654. /***************************************************/
  655. static void drawSel(lp,j)
  656. LIST *lp;
  657. int j;
  658. {
  659.   int i, inactive, x0,y0,wide, selected;
  660.   unsigned long fg, bg;
  661.  
  662.   x0 = 0;  y0 = 0;  wide = lp->w;
  663.   if (ctrlColor) { x0 = y0 = 2;  wide -= 6; }
  664.  
  665.   inactive = INACTIVE(lp,j);
  666.  
  667.   i = j - lp->scrl.val;
  668.   if (i<0 || i>=lp->nlines) return;  /* off screen */
  669.  
  670.   selected = (j == lp->selected && !inactive && j<lp->nstr);
  671.   if (selected) {  /* inverse colors */
  672.     if (ctrlColor) { fg = lp->fg;  bg = lp->lo; }
  673.               else { fg = lp->bg;  bg = lp->fg; }
  674.   }
  675.   else { fg = lp->fg;  bg = lp->bg; }
  676.  
  677.   XSetForeground(theDisp, theGC, bg);
  678.   XFillRectangle(theDisp, lp->win, theGC, x0, y0+i*LINEHIGH, 
  679.          (u_int) wide+1, (u_int) LINEHIGH);
  680.  
  681.   if (j>=0 && j<lp->nstr) {   /* only draw string if valid */
  682.     XSetForeground(theDisp, theGC, fg);
  683.     XSetBackground(theDisp, theGC, bg);
  684.  
  685.     if (!lp->filetypes) 
  686.       DrawString(lp->win, x0+3, y0+i*LINEHIGH + ASCENT + 1, lp->str[j]);
  687.     else {
  688.       int ypos = y0 + i*LINEHIGH + (LINEHIGH - i_fifo_height)/2;
  689.  
  690.       if (lp->str[j][0] == C_FIFO) 
  691.     XCopyPlane(theDisp, fifoPix, lp->win, theGC, 0, 0,
  692.            i_fifo_width, i_fifo_height, x0+3, ypos, 1L);
  693.  
  694.       else if (lp->str[j][0] == C_CHR) 
  695.     XCopyPlane(theDisp, chrPix, lp->win, theGC, 0, 0,
  696.            i_chr_width, i_chr_height, x0+3, ypos, 1L);
  697.  
  698.       else if (lp->str[j][0] == C_DIR) 
  699.     XCopyPlane(theDisp, dirPix, lp->win, theGC, 0, 0,
  700.            i_dir_width, i_dir_height, x0+3, ypos, 1L);
  701.  
  702.       else if (lp->str[j][0] == C_BLK) 
  703.     XCopyPlane(theDisp, blkPix, lp->win, theGC, 0, 0,
  704.            i_blk_width, i_blk_height, x0+3, ypos, 1L);
  705.  
  706.       else if (lp->str[j][0] == C_LNK) 
  707.     XCopyPlane(theDisp, lnkPix, lp->win, theGC, 0, 0,
  708.            i_lnk_width, i_lnk_height, x0+3, ypos, 1L);
  709.  
  710.       else if (lp->str[j][0] == C_SOCK) 
  711.     XCopyPlane(theDisp, sockPix, lp->win, theGC, 0, 0,
  712.            i_sock_width, i_sock_height, x0+3, ypos, 1L);
  713.  
  714.       else if (lp->str[j][0] == C_EXE) 
  715.     XCopyPlane(theDisp, exePix, lp->win, theGC, 0, 0,
  716.            i_exe_width, i_exe_height, x0+3, ypos, 1L);
  717.  
  718.       else  /* lp->str[j][0] == C_REG */
  719.     XCopyPlane(theDisp, regPix, lp->win, theGC, 0, 0,
  720.            i_reg_width, i_reg_height, x0+3, ypos, 1L);
  721.  
  722.  
  723.       DrawString(lp->win, x0+3 + i_fifo_width + 3, 
  724.           y0+i*LINEHIGH + ASCENT + 1, 
  725.           lp->str[j]+1);
  726.     }
  727.   }
  728. }
  729.  
  730.  
  731. /***************************************************/
  732. void LSRedraw(lp, delta)
  733. LIST *lp;
  734. int   delta;
  735. {
  736.   int  i;
  737.  
  738.   for (i = lp->scrl.val; i < lp->scrl.val + lp->nlines; i++) 
  739.     drawSel(lp,i);
  740.   ls3d(lp);
  741. }
  742.  
  743.  
  744. /***************************************************/
  745. int LSClick(lp,ev)
  746. LIST *lp;
  747. XButtonEvent *ev;
  748. {
  749.   /* returns '-1' normally.  returns 0 -> numnames-1 for a goto */
  750.  
  751.   Window       rW, cW;
  752.   int          rx, ry, x, y, sel, oldsel, y0, high;
  753.   unsigned int mask;
  754.   static Time  lasttime=0;
  755.   static int   lastsel = -1;
  756.  
  757.   y0   = (ctrlColor) ? 2 : 0;
  758.   high = (ctrlColor) ? lp->h - 4 : lp->h;
  759.  
  760.   x = ev->x;  y = ev->y;
  761.   sel = lp->scrl.val + (y-y0)/LINEHIGH;
  762.   if (sel >= lp->nstr) sel = lp->selected;
  763.  
  764.   /* see if it's a double click */
  765.   if (ev->time - lasttime < DBLCLKTIME && sel==lastsel 
  766.       && (lp->scrl.val + (y-y0)/LINEHIGH) < lp->nstr
  767.       && !INACTIVE(lp,sel)) {
  768.     return (sel);
  769.   }
  770.  
  771.   lasttime = ev->time;  lastsel = sel;
  772.  
  773.   /* if not clicked on selected, turn off selected and select new one */
  774.   if (sel != lp->selected) {
  775.     oldsel = lp->selected;
  776.     lp->selected = sel;
  777.     drawSel(lp,sel);  drawSel(lp,oldsel);
  778.     ls3d(lp);
  779.     XFlush(theDisp);
  780.   }
  781.  
  782.   while (XQueryPointer(theDisp,lp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
  783.     if (!(mask & Button1Mask)) break;    /* button released */
  784.  
  785.     if (y<y0) { /* scroll up in list */ 
  786.       if (lp->scrl.val > lp->scrl.min) {
  787.     lp->selected = lp->scrl.val - 1;
  788.     SCSetVal(&lp->scrl, lp->scrl.val - 1);
  789.     Timer(100);
  790.       }
  791.     }
  792.  
  793.     else if (y>high) { /* scroll down in list */
  794.       if (lp->scrl.val < lp->scrl.max) {
  795.     lp->selected = lp->scrl.val + lp->nlines;
  796.     if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1;
  797.     SCSetVal(&lp->scrl, lp->scrl.val + 1);
  798.     Timer(100);
  799.       }
  800.     }
  801.  
  802.     else {
  803.       sel = lp->scrl.val + (y-y0)/LINEHIGH;
  804.       if (sel >= lp->nstr) sel = lp->nstr - 1;
  805.  
  806.       if (sel != lp->selected && sel >= lp->scrl.val &&
  807.       sel < lp->scrl.val + lp->nlines) {  
  808.     /* dragged to another on current page */
  809.     oldsel = lp->selected;
  810.     lp->selected = sel;
  811.     drawSel(lp, sel);  drawSel(lp, oldsel);
  812.     ls3d(lp);
  813.     XFlush(theDisp);
  814.       }
  815.     }
  816.   }
  817.  
  818.   return(-1);
  819. }
  820.  
  821.  
  822.  
  823. /***************************************************/
  824. void LSKey(lp, key)
  825.      LIST         *lp;
  826.      int           key;
  827. {
  828.   if      (key==LS_PAGEUP)   SCSetVal(&lp->scrl,lp->scrl.val - (lp->nlines-1));
  829.   else if (key==LS_PAGEDOWN) SCSetVal(&lp->scrl,lp->scrl.val + (lp->nlines-1));
  830.   else if (key==LS_HOME)     SCSetVal(&lp->scrl,lp->scrl.min);
  831.   else if (key==LS_END)      SCSetVal(&lp->scrl,lp->scrl.max);
  832.   
  833.   else if (key==LS_LINEUP)   {
  834.     /* if the selected item visible, but not the top line */
  835.     if (lp->selected > lp->scrl.val && 
  836.     lp->selected <= lp->scrl.val + lp->nlines - 1) {
  837.       /* then just move it */
  838.       lp->selected--;
  839.       drawSel(lp, lp->selected);  drawSel(lp, lp->selected+1);
  840.       ls3d(lp);
  841.     }
  842.     
  843.     /* if it's the top line... */
  844.     else if (lp->selected == lp->scrl.val) {
  845.       if (lp->selected > 0) {
  846.     lp->selected--;
  847.     SCSetVal(&lp->scrl, lp->selected);
  848.       }
  849.     }
  850.     
  851.     /* if it's not visible, put it on the bottom line */
  852.     else {
  853.       lp->selected = lp->scrl.val + lp->nlines - 1;
  854.       if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1;
  855.       drawSel(lp, lp->selected);
  856.       ls3d(lp);
  857.     }
  858.   }
  859.   
  860.   else if (key==LS_LINEDOWN)   {
  861.     /* if the selected item visible, but not the bottom line */
  862.     if (lp->selected >= lp->scrl.val && 
  863.     lp->selected < lp->scrl.val + lp->nlines - 1) {
  864.       if (lp->selected < lp->nstr-1) {
  865.     /* then just move it */
  866.     lp->selected++;
  867.     drawSel(lp, lp->selected);  drawSel(lp, lp->selected-1);
  868.     ls3d(lp);
  869.       }
  870.     }
  871.     
  872.     /* if it's the bottom line... */
  873.     else if (lp->selected == lp->scrl.val + lp->nlines - 1) {
  874.       if (lp->selected < lp->nstr-1) {
  875.     lp->selected++;
  876.     SCSetVal(&lp->scrl, lp->scrl.val+1);
  877.       }
  878.     }
  879.     
  880.     /* if it's not visible, put it on the top line */
  881.     else {
  882.       lp->selected = lp->scrl.val;
  883.       drawSel(lp, lp->selected);
  884.       ls3d(lp);
  885.     }
  886.   }
  887. }
  888.  
  889.