home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume10 / xv / part07 < prev    next >
Text File  |  1990-12-09  |  44KB  |  1,618 lines

  1. Path: wuarchive!julius.cs.uiuc.edu!apple!sun-barr!newstop!exodus!appserv!halibut.cis.upenn.edu
  2. From: bradley@halibut.cis.upenn.edu (John Bradley)
  3. Newsgroups: comp.sources.x
  4. Subject: v10i085: xv - display and manipulate images, Part07/10
  5. Message-ID: <323@appserv.Eng.Sun.COM>
  6. Date: 27 Nov 90 20:08:38 GMT
  7. References: <csx-10i079:xv@uunet.UU.NET>
  8. Sender: news@exodus.Eng.Sun.COM
  9. Lines: 1601
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: bradley@halibut.cis.upenn.edu (John Bradley)
  13. Posting-number: Volume 10, Issue 85
  14. Archive-name: xv/part07
  15.  
  16. #!/bin/sh
  17. # to extract, remove the header and type "sh filename"
  18. if `test ! -s ./xvbutt.c`
  19. then
  20. echo "writting ./xvbutt.c"
  21. cat > ./xvbutt.c << '\BARFOO\'
  22. /* 
  23.  * xvbutt.c - regular and 'radio' pushbuttons
  24.  *
  25.  * callable functions:
  26.  *
  27.  *   BTCreate()             -  create a button
  28.  *   BTSetActive()          -  change 'active' status of button
  29.  *   BTRedraw()             -  redraw button
  30.  *   BTTrack()              -  clicked in button.  track until mouse up
  31.  *
  32.  *   RBCreate()             -  create an RBUTT and append to supplied list
  33.  *   RBRedraw()             -  redraw one or all RBUTTs in a list
  34.  *   RBSelect()             -  change selected item in list of RBUTTs
  35.  *   RBWhich()              -  returns index of selected RBUTT in list
  36.  *   RBCount()              -  returns # of RBUTTs in list
  37.  *   RBSetActive()          -  sets active status of an RBUTT
  38.  *   RBClick()              -  finds clicked-on rb in a list
  39.  *   RBTrack()              -  tracks rb after click, until release
  40.  */
  41.  
  42. /*
  43.  * Copyright 1989, 1990 by the University of Pennsylvania
  44.  *
  45.  * Permission to use, copy, and distribute for non-commercial purposes,
  46.  * is hereby granted without fee, providing that the above copyright
  47.  * notice appear in all copies and that both the copyright notice and this
  48.  * permission notice appear in supporting documentation.
  49.  *
  50.  * The software may be modified for your own purposes, but modified versions
  51.  * may not be distributed.
  52.  *
  53.  * This software is provided "as is" without any express or implied warranty.
  54.  */
  55.  
  56.  
  57. #include "xv.h"
  58. #include "bitmaps.h"
  59.  
  60. static int    rbpixmade = 0;
  61. static Pixmap rbon, rboff, rbon1, rboff1;
  62.  
  63. #ifdef __STDC__
  64. static void drawRB(RBUTT *);
  65. #else
  66. static void drawRB();
  67. #endif
  68.  
  69. /**********************************************/
  70. void BTCreate(bp,win,x,y,w,h,str,fg,bg)
  71. BUTT         *bp;
  72. Window        win;
  73. int           x,y,w,h;
  74. char         *str;
  75. unsigned long fg,bg;
  76. {
  77.   bp->win = win;
  78.   bp->x = x;  bp->y = y;  bp->w = w;  bp->h = h;
  79.   bp->str = str;
  80.   bp->fg = fg;  bp->bg = bg;
  81.   bp->lit = 0;
  82.   bp->active = 1;
  83.   bp->toggle = 0;
  84. }
  85.  
  86.  
  87.  
  88. /**********************************************/
  89. void BTSetActive(bp,act)
  90. BUTT         *bp;
  91. int           act;
  92. {
  93.   if (bp->active != act) {
  94.     bp->active = act;
  95.     BTRedraw(bp);
  96.   }
  97. }
  98.  
  99.  
  100.  
  101. /**********************************************/
  102. void BTRedraw(bp)
  103. BUTT *bp;
  104. {
  105.   int x,y,w,h,r;
  106.   XPoint poly[9];
  107.  
  108.   x = bp->x;  y=bp->y;  w=bp->w;  h=bp->h;  r=3;
  109.  
  110.   /* set up the polygon */
  111.   poly[0].x = x;      poly[0].y = y+r;
  112.   poly[1].x = x;      poly[1].y = y+h-r;
  113.   poly[2].x = x+r;    poly[2].y = y+h;
  114.   poly[3].x = x+w-r;  poly[3].y = y+h;
  115.   poly[4].x = x+w;    poly[4].y = y+h-r;
  116.   poly[5].x = x+w;    poly[5].y = y+r;
  117.   poly[6].x = x+w-r;  poly[6].y = y;
  118.   poly[7].x = x+r;    poly[7].y = y;
  119.   poly[8].x = x;      poly[8].y = y+r;
  120.  
  121.  
  122.   if (!bp->active) bp->lit = 0;   /* sanity assertion */
  123.  
  124.   if (bp->lit) XSetForeground(theDisp, theGC, bp->fg);
  125.           else XSetForeground(theDisp, theGC, bp->bg);
  126.   XFillPolygon(theDisp,bp->win,theGC,poly,9,Convex,CoordModeOrigin);
  127.  
  128.   XSetForeground(theDisp, theGC, bp->fg);
  129.   XDrawLines(theDisp,bp->win,theGC,poly,9,CoordModeOrigin);
  130.  
  131.   if (!bp->active) {   /* stipple the text if not active */
  132.     XSetFillStyle(theDisp, theGC, FillStippled);
  133.     XSetStipple(theDisp, theGC, grayStip);
  134.   }
  135.  
  136.   if (bp->lit) XSetForeground(theDisp, theGC, bp->bg);
  137.           else XSetForeground(theDisp, theGC, bp->fg);
  138.   XDrawString(theDisp, bp->win, theGC, CENTERX(mfinfo,x+w/2,bp->str),
  139.           CENTERY(mfinfo,y+h/2), bp->str, strlen(bp->str));
  140.  
  141.   if (!bp->active) XSetFillStyle(theDisp,theGC,FillSolid);  /* back to norm */
  142. }
  143.  
  144.  
  145.  
  146. /**********************************************/
  147. int BTTrack(bp)
  148. BUTT *bp;
  149. {
  150.   /* called when we've gotten a click inside 'bp'.  returns 1 if button
  151.      was still selected lit when mouse was released. */
  152.  
  153.   Window       rW, cW;
  154.   int          x, y, rx, ry, rval, inval;
  155.   unsigned int mask;
  156.  
  157.   if (!bp->active) return 0;   /* inactive button */
  158.  
  159.   bp->lit = !bp->lit;
  160.   inval = bp->lit;
  161.  
  162.   BTRedraw(bp);  XFlush(theDisp);
  163.   Timer(75);  /* long enough for turn on to be visible */
  164.  
  165.   while (XQueryPointer(theDisp,bp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
  166.     if (!(mask & Button1Mask)) break;    /* button released */
  167.  
  168.     if (bp->lit!=inval && PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) {
  169.       bp->lit = inval;  BTRedraw(bp);  XFlush(theDisp);
  170.     }
  171.     
  172.     if (bp->lit==inval && !PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) {
  173.       bp->lit = !inval;  BTRedraw(bp);  XFlush(theDisp);
  174.     }
  175.   }
  176.  
  177.   rval = (bp->lit == inval);
  178.   
  179.   if (bp->lit && !bp->toggle) 
  180.     { bp->lit = 0;  BTRedraw(bp);  XFlush(theDisp); }
  181.  
  182.   return(rval);
  183. }
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192. /***********************************************/
  193. RBUTT *RBCreate(rblist, win, x,y,str, fg, bg)
  194.       RBUTT        *rblist;
  195.       Window        win;
  196.       int           x,y;
  197.       char         *str;
  198.       unsigned long fg,bg;
  199. {
  200.   /* mallocs an RBUTT, fills in the fields, and appends it to rblist
  201.      if rblist is NULL, this is the first rb in the list.  It will
  202.      be made the 'selected' one 
  203.  
  204.      Note: no need to check return status.  It'll fatal error if it 
  205.      can't malloc */
  206.  
  207.   RBUTT *rb, *rbptr;
  208.  
  209.   rb = (RBUTT *) malloc(sizeof(RBUTT));
  210.   if (!rb) FatalError("couldn't malloc RBUTT");
  211.  
  212.   /* fill in the fields of the structure */
  213.   rb->win      = win;
  214.   rb->x        = x;
  215.   rb->y        = y;
  216.   rb->str      = str;
  217.   rb->selected = 0;
  218.   rb->active   = 1;
  219.   rb->next     = (RBUTT *) NULL;
  220.   rb->fg       = fg;
  221.   rb->bg       = bg;
  222.  
  223.   if (rblist) {            /* append to end of list */
  224.     rbptr = rblist;
  225.     while (rbptr->next) rbptr = rbptr->next;
  226.     rbptr->next = rb;
  227.   }
  228.   else {                   /* this is the first one in the list.  select it */
  229.     rb->selected = 1;
  230.   }
  231.  
  232.  
  233.   /* and, on an unrelated note, if the RB pixmaps haven't been created yet,
  234.      do so.  We'll be needing them, y'see... */
  235.  
  236.   if (!rbpixmade) {
  237.     rbon  = XCreatePixmapFromBitmapData(theDisp, rootW, rb_on_bits,
  238.          rb_on_width, rb_on_height, fg, bg, dispDEEP);
  239.  
  240.     rboff = XCreatePixmapFromBitmapData(theDisp, rootW, rb_off_bits,
  241.          rb_off_width, rb_off_height, fg, bg, dispDEEP);
  242.     rbon1 = XCreatePixmapFromBitmapData(theDisp, rootW, rb_on1_bits,
  243.          rb_on1_width, rb_on1_height, fg, bg, dispDEEP);
  244.     rboff1= XCreatePixmapFromBitmapData(theDisp, rootW, rb_off1_bits,
  245.          rb_off1_width, rb_off1_height, fg, bg, dispDEEP);
  246.  
  247.     rbpixmade = 1;
  248.   }
  249.  
  250.   return(rb);
  251. }
  252.   
  253.  
  254.  
  255.  
  256. /***********************************************/
  257. void RBRedraw(rblist, num)
  258. RBUTT *rblist;
  259. int    num;
  260. {
  261.   /* redraws the 'num-th' RB in the list.  if num < 0, redraws entire list */
  262.  
  263.   RBUTT *rb;
  264.   int    i;
  265.  
  266.   /* point 'rb' at the appropriate RBUTT, *if* we're not drawing entire list */
  267.   if (num>=0) {
  268.     i=0;  rb=rblist;
  269.     while (i!=num && rb) { rb = rb->next;  i++; }
  270.     if (!rb) return;                     /* num is out of range.  do nothing */
  271.     drawRB(rb);
  272.   }
  273.  
  274.   else {                                 /* draw entire list */
  275.     rb = rblist;
  276.     while (rb) {
  277.       drawRB(rb);
  278.       rb = rb->next;
  279.     }
  280.   }
  281. }
  282.  
  283.  
  284. static void drawRB(rb)
  285. RBUTT *rb;
  286. {
  287.   /* draws the rb being pointed at */
  288.  
  289.   if (!rb) return;  /* rb = NULL */
  290.  
  291.   XSetForeground(theDisp, theGC, rb->fg);
  292.   XSetBackground(theDisp, theGC, rb->bg);
  293.  
  294.   if (rb->selected) 
  295.     XCopyArea(theDisp, rbon, rb->win, theGC, 0, 0, rb_on_width, rb_on_height, 
  296.           rb->x, rb->y);
  297.   else
  298.     XCopyArea(theDisp, rboff, rb->win, theGC, 0, 0, rb_on_width, rb_on_height, 
  299.           rb->x, rb->y);
  300.  
  301.   XDrawString(theDisp, rb->win, theGC, rb->x+rb_on_width+4, 
  302.           rb->y+rb_on_height/2 - CHIGH/2 + ASCENT,rb->str,strlen(rb->str));
  303.  
  304.   /* if non-active, dim button and string */
  305.   if (!rb->active) { 
  306.     /* stipple the RB by drawing 'bg' where there's 1's in the stipple */
  307.     XSetFillStyle(theDisp, theGC, FillStippled);
  308.     XSetStipple(theDisp, theGC, grayStip);
  309.     XSetForeground(theDisp, theGC, rb->bg);
  310.     XFillRectangle(theDisp,rb->win,theGC,rb->x,rb->y,rb_on_width,rb_on_height);
  311.     XFillRectangle(theDisp,rb->win,theGC, rb->x + rb_on_width+4,
  312.            rb->y+rb_on_height/2 - CHIGH/2, StringWidth(rb->str),CHIGH);
  313.     XSetFillStyle(theDisp, theGC, FillSolid);
  314.   }
  315. }
  316.  
  317.  
  318. /***********************************************/
  319. void RBSelect(rblist, n)
  320. RBUTT *rblist;
  321. int    n;
  322. {
  323.   RBUTT *rbold, *rb;
  324.   int    i;
  325.  
  326.   /* makes rb #n the selected rb in the list.  Does all redrawing.  Does
  327.      nothing if rb already selected */
  328.  
  329.   /* get pointers to the currently selected rb and the desired rb */
  330.   rbold = rblist;
  331.   while (rbold && !rbold->selected) rbold = rbold->next;
  332.   if (!rbold) return;    /* no currently selected item.  shouldn't happen */
  333.  
  334.   rb = rblist;  i=0;
  335.   while (rb && i!=n) {rb = rb->next;  i++; }
  336.   if (!rb) return;    /* 'n' is out of range */
  337.  
  338.  
  339.   if (rb == rbold) return;   /* 'n' is already selected.  do nothing */
  340.  
  341.   rbold->selected = 0;
  342.   rb->selected    = 1;
  343.   drawRB(rbold);
  344.   drawRB(rb);
  345. }
  346.  
  347.  
  348.           
  349. /***********************************************/
  350. int RBWhich(rblist)
  351. RBUTT *rblist;
  352. {
  353.   int i;
  354.  
  355.   /* returns index of currently selected rb.  if none, returns -1 */
  356.  
  357.   i = 0;
  358.   while (rblist && !rblist->selected) { rblist = rblist->next;  i++; }
  359.  
  360.   if (!rblist) return -1;             /* didn't find one */
  361.   return i;
  362. }
  363.  
  364.  
  365. /***********************************************/
  366. int RBCount(rblist)
  367. RBUTT *rblist;
  368. {
  369.   int i;
  370.  
  371.   /* returns # of rb's in the list */
  372.  
  373.   i = 0;
  374.   while (rblist) { rblist = rblist->next; i++; }
  375.   return i;
  376. }
  377.  
  378.  
  379. /***********************************************/
  380. void RBSetActive(rblist, n, act)
  381. RBUTT *rblist;
  382. int n,act;
  383. {
  384.   RBUTT *rb;
  385.   int    i;
  386.  
  387.   /* sets 'active' status of rb #n.  does redrawing */
  388.  
  389.   rb=rblist;  i=0;
  390.   while (rb && i!=n) { rb = rb->next; i++; }
  391.   if (!rb) return;                         /* n out of range.  do nothing */
  392.  
  393.   if (rb->active != act) {
  394.     rb->active = act;
  395.     drawRB(rb);
  396.   }
  397. }
  398.  
  399.  
  400. /***********************************************/
  401. int RBClick(rblist, mx, my)
  402. RBUTT *rblist;
  403. int    mx,my;
  404. {
  405.   int i;
  406.  
  407.   /* searches through rblist to see if mouse click at mx,my is in the
  408.      clickable region of any of the rb's.  If it finds one, it returns 
  409.      it's index in the list.  If not, returns -1 */
  410.  
  411.   i = 0;
  412.   while (rblist) {
  413.     if (PTINRECT(mx, my, rblist->x, rblist->y, rb_on_width, rb_on_height)) 
  414.       break;
  415.     rblist = rblist->next;
  416.     i++;
  417.   }
  418.  
  419.   if (!rblist) return -1;
  420.   return(i);
  421. }
  422.  
  423.  
  424. /***********************************************/
  425. void RBTrack(rblist, n)
  426. RBUTT *rblist;
  427. int    n;
  428. {
  429.   RBUTT       *rb;
  430.   Window       rW, cW;
  431.   int          i, x, y, rx, ry, lit;
  432.   unsigned int mask;
  433.   Pixmap litpix, darkpix;
  434.  
  435.   rb=rblist;  i=0;
  436.   while (rb && i!=n) { rb = rb->next; i++; }
  437.   if (!rb) return;                    /* n out of range */
  438.  
  439.   /* called once we've figured out that the mouse clicked in 'rb' */
  440.  
  441.   if (!rb->active) return;
  442.  
  443.   if (rb->selected) { litpix = rbon1;   darkpix = rbon; }
  444.                else { litpix = rboff1;  darkpix = rboff; }
  445.  
  446.   lit = 1;
  447.   XCopyArea(theDisp, litpix, rb->win, theGC, 0, 0, rb_on_width, rb_on_height, 
  448.           rb->x, rb->y);
  449.   XFlush(theDisp);
  450.   Timer(75);          /* give chance for 'turn on' to become visible */
  451.  
  452.   while (XQueryPointer(theDisp,rb->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
  453.     if (!(mask & Button1Mask)) break;    /* button released */
  454.  
  455.     if (!lit && PTINRECT(x, y, rb->x, rb->y, rb_on_width, rb_on_height)) {
  456.       lit=1;
  457.       XCopyArea(theDisp, litpix, rb->win, theGC, 0,0,rb_on_width,rb_on_height, 
  458.           rb->x, rb->y);
  459.       XFlush(theDisp);
  460.     }
  461.     
  462.     if (lit && !PTINRECT(x, y, rb->x, rb->y, rb_on_width, rb_on_height)) {
  463.       lit=0;
  464.       XCopyArea(theDisp, darkpix,rb->win,theGC, 0,0,rb_on_width,rb_on_height, 
  465.           rb->x, rb->y);
  466.       XFlush(theDisp);
  467.     }
  468.   }
  469.  
  470.   if (lit) {
  471.     XCopyArea(theDisp, darkpix, rb->win, theGC, 0, 0, 
  472.           rb_on_width, rb_on_height, rb->x, rb->y);
  473.     RBSelect(rblist, n);
  474.   }
  475.  
  476.   XFlush(theDisp);
  477. }
  478. \BARFOO\
  479. else
  480.   echo "will not over write ./xvbutt.c"
  481. fi
  482. if `test ! -s ./xvctrl.c`
  483. then
  484. echo "writting ./xvctrl.c"
  485. cat > ./xvctrl.c << '\BARFOO\'
  486. /* 
  487.  * xvctrl.c - Control box handling functions
  488.  *
  489.  * callable functions:
  490.  *
  491.  *   CreateCtrl(geom)       -  creates the ctrlW window.  Doesn't map it.
  492.  *   CtrlBox(vis)           -  random processing based on value of 'vis'
  493.  *                             maps/unmaps window, etc.
  494.  *   RedrawCtrl(x,y,w,h)    -  called by 'expose' events
  495.  *   ClickCtrl(x,y)
  496.  *   DrawCtrlStr()          -  called to redraw 'ISTR_INFO' string in ctrlW
  497.  *   ScrollToCurrent()      -  called when 'curname' is changed 
  498.  *
  499.  *   LSCreate()             -  creates a listbox
  500.  *   LSRedraw()             -  redraws 'namelist' box
  501.  *   LSClick()              -  operates list box
  502.  *   LSNewData()            -  called when strings or number of them change
  503.  *
  504.  */
  505.  
  506. /*
  507.  * Copyright 1989, 1990 by the University of Pennsylvania
  508.  *
  509.  * Permission to use, copy, and distribute for non-commercial purposes,
  510.  * is hereby granted without fee, providing that the above copyright
  511.  * notice appear in all copies and that both the copyright notice and this
  512.  * permission notice appear in supporting documentation.
  513.  *
  514.  * The software may be modified for your own purposes, but modified versions
  515.  * may not be distributed.
  516.  *
  517.  * This software is provided "as is" without any express or implied warranty.
  518.  */
  519.  
  520.  
  521. #include "xv.h"
  522. #include "bitmaps.h"
  523.  
  524. #define DBLCLKTIME 500             /* double-click speed in milliseconds */
  525.  
  526. #define INACTIVE(lptr, item) ((lptr)->filetypes && (lptr)->dirsonly && \
  527.                   (item) >= 0 && (item) < (lptr)->nstr && \
  528.                   (lptr)->str[(item)][0] != C_DIR && \
  529.                   (lptr)->str[(item)][0] != C_LNK)
  530.  
  531. #define NLINES 9                   /* # of lines in list control (keep odd) */
  532. #define LISTW   330
  533.  
  534. #define BUTTW   60
  535. #define BUTTH   19
  536.  
  537. static int    listh;               /* height of list/scrl controls */
  538. static int    ptop;                /* y-coord of top of button area in ctrlW */
  539.  
  540. static Pixmap fifoPix, chrPix, dirPix, blkPix, lnkPix, sockPix, regPix;
  541.  
  542. #ifdef __STDC__
  543. static void drawSel(LIST *, int);
  544. static void RedrawNList(void);
  545. #else
  546. static void drawSel(), RedrawNList();
  547. #endif
  548.  
  549.  
  550. /***************************************************/
  551. void CreateCtrl(geom)
  552. char *geom;
  553. {
  554.   int i,b2wide;
  555.  
  556.   ctrlW = CreateWindow("xv controls", geom, CTRLWIDE,CTRLHIGH,infofg,infobg);
  557.   if (!ctrlW) FatalError("can't create controls window!");
  558.  
  559.   grayTile = XCreatePixmapFromBitmapData(theDisp, ctrlW, gray25_bits,
  560.          gray25_width, gray25_height, infofg, infobg, dispDEEP);
  561.  
  562.   grayStip = XCreatePixmapFromBitmapData(theDisp, ctrlW, gray50_bits,
  563.          gray50_width, gray50_height, 1, 0, 1);
  564.   
  565.   fifoPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_fifo_bits,
  566.          i_fifo_width, i_fifo_height, 1, 0, 1);
  567.   
  568.   chrPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_chr_bits,
  569.          i_chr_width, i_chr_height, 1,0,1);
  570.   
  571.   dirPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_dir_bits,
  572.          i_dir_width, i_dir_height, 1,0,1);
  573.   
  574.   blkPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_blk_bits,
  575.          i_blk_width, i_blk_height, 1,0,1);
  576.   
  577.   lnkPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_lnk_bits,
  578.          i_lnk_width, i_lnk_height, 1,0,1);
  579.   
  580.   sockPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_sock_bits,
  581.          i_sock_width, i_sock_height, 1,0,1);
  582.   
  583.   regPix  = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_reg_bits,
  584.          i_reg_width, i_reg_height, 1,0,1);
  585.   
  586.  
  587.   XSetWindowBackgroundPixmap(theDisp, ctrlW, grayTile);
  588.  
  589.   /* create doo-wahs */
  590.   listh = LINEHIGH * NLINES;
  591.  
  592.   LSCreate(&nList, ctrlW, 10, 10+CHIGH+3, LISTW, listh, NLINES, dispnames, 
  593.        numnames, infofg, infobg, RedrawNList, 0, 0);
  594.  
  595.   ptop = CTRLHIGH - (3*BUTTH + 4*8);
  596.  
  597.   i = listh-BUTTH;
  598.  
  599.   BTCreate(&but[BNEXT], ctrlW, 368, nList.y+(i*0)/4, 60, 
  600.        BUTTH, "Next",     infofg, infobg);
  601.   BTCreate(&but[BPREV], ctrlW, 368, nList.y+(i*1)/4, 60, 
  602.        BUTTH, "Previous", infofg, infobg);
  603.   BTCreate(&but[BINFO], ctrlW, 368, nList.y+(i*2)/4, 60, 
  604.        BUTTH, "Info", infofg, infobg);
  605.   BTCreate(&but[BSAVE], ctrlW, 368, nList.y+(i*3)/4, 60, 
  606.        BUTTH, "Save", infofg, infobg);
  607.   BTCreate(&but[BQUIT], ctrlW, 368, nList.y+(i*4)/4, 60, 
  608.        BUTTH, "Quit", infofg, infobg);
  609.  
  610.   BTCreate(&but[BCROP], ctrlW, 10, ptop+8, 
  611.        BUTTW, BUTTH, "Crop", infofg, infobg);
  612.   BTCreate(&but[BUNCROP], ctrlW, 10, ptop + BUTTH + 2*8, 
  613.        BUTTW, BUTTH, "UnCrop", infofg, infobg);
  614.  
  615.   BTCreate(&but[BMAX], ctrlW, 10+(CTRLWIDE-20-BUTTW)/5, ptop+8, 
  616.        BUTTW, BUTTH, "Max Size", infofg, infobg);
  617.   BTCreate(&but[BNORM], ctrlW, 10+(CTRLWIDE-20-BUTTW)/5, ptop + BUTTH + 2*8, 
  618.        BUTTW, BUTTH, "Normal", infofg, infobg);
  619.  
  620.   BTCreate(&but[BUP2], ctrlW, 10+(2*(CTRLWIDE-20-BUTTW))/5, ptop+8, 
  621.        BUTTW, BUTTH, "Dbl Size", infofg, infobg);
  622.   BTCreate(&but[BDN2], ctrlW, 10+(2*(CTRLWIDE-20-BUTTW))/5, ptop+BUTTH+2*8, 
  623.        BUTTW, BUTTH, "Half Size", infofg, infobg);
  624.  
  625.   BTCreate(&but[BUP10], ctrlW, 10+(3*(CTRLWIDE-20-BUTTW))/5, ptop+8, 
  626.        BUTTW, BUTTH, "+10%", infofg, infobg);
  627.   BTCreate(&but[BDN10], ctrlW, 10+(3*(CTRLWIDE-20-BUTTW))/5, ptop+BUTTH+2*8, 
  628.        BUTTW, BUTTH, "-10%", infofg, infobg);
  629.  
  630.   BTCreate(&but[B4BY3], ctrlW, 10+(4*(CTRLWIDE-20-BUTTW))/5, ptop+8, 
  631.        BUTTW, BUTTH, "4x3", infofg, infobg);
  632.   BTCreate(&but[BASPECT], ctrlW, 10+(4*(CTRLWIDE-20-BUTTW))/5, ptop+BUTTH+2*8, 
  633.        BUTTW, BUTTH, "Aspect", infofg, infobg);
  634.  
  635.   BTCreate(&but[BROTL],  ctrlW, 10+(5*(CTRLWIDE-20-BUTTW))/5, ptop+8,
  636.        BUTTW, BUTTH, "Turn L", infofg, infobg);
  637.   BTCreate(&but[BROTR],  ctrlW, 10+(5*(CTRLWIDE-20-BUTTW))/5, ptop+BUTTH+2*8,
  638.        BUTTW, BUTTH, "Turn R", infofg, infobg);
  639.  
  640.   b2wide = (CTRLWIDE - 20 - 6*BUTTW)/5 + 2*BUTTW;
  641.   BTCreate(&but[BACROP], ctrlW, 10 + (0*(CTRLWIDE-20-b2wide))/2, 
  642.        ptop + 2*BUTTH + 3*8, b2wide, BUTTH, "AutoCrop", infofg, infobg);
  643.   BTCreate(&but[BMAXPECT],   ctrlW, 10 + (1*(CTRLWIDE-20-b2wide))/2, 
  644.        ptop + 2*BUTTH + 3*8, b2wide, BUTTH, "Maxpect", infofg, infobg);
  645.   BTCreate(&but[BGAMMA],    ctrlW, 10 + (2*(CTRLWIDE-20-b2wide))/2, 
  646.        ptop + 2*BUTTH + 3*8, b2wide, BUTTH, "Gamma", infofg, infobg);
  647.  
  648.   XMapSubwindows(theDisp, ctrlW);
  649. }
  650.   
  651.  
  652. /***************************************************/
  653. void CtrlBox(vis)
  654. int vis;
  655. {
  656.   if (vis) XMapRaised(theDisp, ctrlW);
  657.   else     XUnmapWindow(theDisp, ctrlW);
  658.  
  659.   ctrlUp = vis;
  660. }
  661.  
  662.  
  663. /***************************************************/
  664. void RedrawCtrl(x,y,w,h)
  665. int x,y,w,h;
  666. {
  667.   char foo[40];
  668.   int i;
  669.   XRectangle xr;
  670.  
  671.   xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
  672.   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
  673.  
  674.   XSetForeground(theDisp, theGC, infofg);
  675.   XSetBackground(theDisp, theGC, infobg);
  676.  
  677.   XDrawLine(theDisp, ctrlW, theGC, 0, ptop, CTRLWIDE, ptop);
  678.  
  679.   if (numnames>1) sprintf(foo,"%d files",numnames);
  680.   else strcpy(foo,"1 file");
  681.     
  682.   XSetForeground(theDisp, theGC, infobg);
  683.   XFillRectangle(theDisp,ctrlW, theGC, 10+1,5+1,StringWidth(foo)+4,CHIGH+2);
  684.   XSetForeground(theDisp,theGC,infofg);
  685.   XDrawRectangle(theDisp,ctrlW, theGC, 10,5,StringWidth(foo)+5,CHIGH+3);
  686.   XDrawString(theDisp, ctrlW, theGC, 10+3, 5+ASCENT+2,
  687.           foo, strlen(foo));
  688.  
  689.   for (i=0; i<NBUTTS; i++)
  690.     BTRedraw(&but[i]);
  691.  
  692.   DrawCtrlStr();
  693.  
  694.   XSetClipMask(theDisp, theGC, None);
  695. }
  696.  
  697.  
  698. /***************************************************/
  699. void DrawCtrlStr()
  700. {
  701.   int   y;
  702.   char *st;
  703.  
  704.   y = ptop - (CHIGH + 2);
  705.   st = GetISTR(ISTR_INFO);
  706.  
  707.   XSetForeground(theDisp, theGC, infobg);
  708.   XFillRectangle(theDisp, ctrlW, theGC, 0, y-1, CTRLWIDE, CHIGH+3);
  709.  
  710.   XSetForeground(theDisp, theGC, infofg);
  711.   XDrawLine(theDisp, ctrlW, theGC, 0, y-2, CTRLWIDE, y-2);
  712.  
  713.   XDrawString(theDisp, ctrlW, theGC, 10, y+ASCENT, st, strlen(st));
  714. }
  715.  
  716.  
  717. /***************************************************/
  718. int ClickCtrl(x,y)
  719. int x,y;
  720. {
  721.   BUTT *bp;
  722.   int   i;
  723.  
  724.   for (i=0; i<NBUTTS; i++) {
  725.     bp = &but[i];
  726.     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
  727.   }
  728.  
  729.   if (i<NBUTTS) {                   /* found one */
  730.     if (BTTrack(bp)) return (i);    /* and it was clicked */
  731.   }
  732.  
  733.   return -1;
  734. }
  735.  
  736.  
  737.  
  738. /***************************************************/
  739. void ScrollToCurrent()
  740. {
  741.   /* called when 'curname' is changed by anything (next/prev buttons,
  742.      wait timeout, whatever.  IF curname is already visible, just redraws
  743.      list to reflect changed selection.  If not, trys to adjust 'liststart' 
  744.      so that curname will appear in the center of the list window */
  745.  
  746.   int halfway;
  747.  
  748.   nList.selected = curname;
  749. /*  if (nList.selected >= nList.scrl.val && 
  750.       nList.selected <  nList.scrl.val + nList.nlines) LSRedraw(&nList); */
  751.  
  752.   if (nList.selected > nList.scrl.val && 
  753.       nList.selected <  nList.scrl.val + nList.nlines-1) LSRedraw(&nList);
  754.   else {
  755.     halfway = (nList.nlines)/2;   /* offset to the halfway pt. of the list */
  756.     SCSetVal(&nList.scrl, nList.selected - halfway);
  757.   }
  758. }
  759.  
  760.  
  761. /***************************************************/
  762. static void RedrawNList()
  763. {
  764.   LSRedraw(&nList);
  765. }
  766.  
  767.  
  768.  
  769.  
  770. /***************** LIST STUFF *********************/
  771.  
  772. /***************************************************/
  773. void LSCreate(lp, win, x, y, w, h, nlines, strlist, nstr, fg, bg, fptr, 
  774.           typ, donly)
  775. LIST         *lp;
  776. Window        win;
  777. int           x,y,w,h,nlines,nstr,typ,donly;
  778. unsigned long fg, bg;
  779. char        **strlist;    /* a pointer to a list of strings */
  780. void        (*fptr)();
  781. {
  782.   lp->win = XCreateSimpleWindow(theDisp,win,x,y,w,h,1,infofg,infobg);
  783.   if (!lp->win) FatalError("can't create list window!");
  784.  
  785.   lp->x = x;    lp->y = y;   
  786.   lp->w = w;    lp->h = h;
  787.   lp->fg = fg;  lp->bg = bg;
  788.   lp->str      = strlist;
  789.   lp->nstr     = nstr;
  790.   lp->selected = 0;
  791.   lp->nlines   = nlines;
  792.   lp->filetypes= typ;
  793.   lp->dirsonly = donly;
  794.  
  795.   XSelectInput(theDisp, lp->win, ExposureMask | ButtonPressMask);
  796.  
  797.   SCCreate(&lp->scrl, win, x+w, y, 1, h, 0, nstr-nlines, curname, nlines-1,
  798.        fg, bg, fptr);
  799. }
  800.  
  801.  
  802.  
  803. /***************************************************/
  804. void LSNewData(lp, strlist, nstr)
  805. LIST         *lp;
  806. char        **strlist;
  807. int           nstr;
  808. {
  809.   lp->str = strlist;
  810.   lp->nstr = nstr;
  811.   lp->selected = 0;
  812.   SCSetRange(&lp->scrl, 0, nstr - lp->nlines, 0, lp->nlines-1);
  813. }
  814.  
  815.  
  816. /***************************************************/
  817. static void drawSel(lp,j)
  818. LIST *lp;
  819. int j;
  820. {
  821.   int i, inactive;
  822.   unsigned long fg, bg;
  823.  
  824.   inactive = INACTIVE(lp,j);
  825.  
  826.   i = j - lp->scrl.val;
  827.   if (i<0 || i>=lp->nlines) return;  /* off screen */
  828.  
  829.   if (j == lp->selected && !inactive && j<lp->nstr) 
  830.        { fg = lp->bg;  bg = lp->fg; }  /* invert */
  831.   else { fg = lp->fg;  bg = lp->bg; }
  832.  
  833.   XSetForeground(theDisp, theGC, bg);
  834.   XFillRectangle(theDisp, lp->win, theGC, 0,i*LINEHIGH, lp->w, LINEHIGH);
  835.  
  836.   if (j>=0 && j<lp->nstr) {   /* only draw string if valid */
  837.     /* make non-dirs inactive, if dirsonly and filetypes */
  838.     XSetForeground(theDisp, theGC, fg);
  839.     XSetBackground(theDisp, theGC, bg);
  840.  
  841.     if (!lp->filetypes) 
  842.       XDrawString(theDisp, lp->win, theGC, 3, i*LINEHIGH + ASCENT + 1, 
  843.           lp->str[j], strlen(lp->str[j]));
  844.     else {
  845.       int ypos = i*LINEHIGH + (LINEHIGH - i_fifo_height)/2;
  846.  
  847.       if (lp->str[j][0] == C_FIFO) 
  848.     XCopyPlane(theDisp, fifoPix, lp->win, theGC, 0, 0,
  849.            i_fifo_width, i_fifo_height, 3, ypos, 1L);
  850.  
  851.       else if (lp->str[j][0] == C_CHR) 
  852.     XCopyPlane(theDisp, chrPix, lp->win, theGC, 0, 0,
  853.            i_chr_width, i_chr_height, 3, ypos, 1L);
  854.  
  855.       else if (lp->str[j][0] == C_DIR) 
  856.     XCopyPlane(theDisp, dirPix, lp->win, theGC, 0, 0,
  857.            i_dir_width, i_dir_height, 3, ypos, 1L);
  858.  
  859.       else if (lp->str[j][0] == C_BLK) 
  860.     XCopyPlane(theDisp, blkPix, lp->win, theGC, 0, 0,
  861.            i_blk_width, i_blk_height, 3, ypos, 1L);
  862.  
  863.       else if (lp->str[j][0] == C_LNK) 
  864.     XCopyPlane(theDisp, lnkPix, lp->win, theGC, 0, 0,
  865.            i_lnk_width, i_lnk_height, 3, ypos, 1L);
  866.  
  867.       else if (lp->str[j][0] == C_SOCK) 
  868.     XCopyPlane(theDisp, sockPix, lp->win, theGC, 0, 0,
  869.            i_sock_width, i_sock_height, 3, ypos, 1L);
  870.  
  871.       else  /* lp->str[j][0] == C_REG */
  872.     XCopyPlane(theDisp, regPix, lp->win, theGC, 0, 0,
  873.            i_reg_width, i_reg_height, 3, ypos, 1L);
  874.  
  875.  
  876.       XDrawString(theDisp, lp->win, theGC, 3 + i_fifo_width + 3, 
  877.           i*LINEHIGH + ASCENT + 1, 
  878.           lp->str[j]+1, strlen(lp->str[j]+1));
  879.  
  880. #ifdef STIPPLE
  881.       if (inactive) { 
  882.     /* stipple the icon by drawing 'bg' where there's 1's in the stipple */
  883.     XSetFillStyle(theDisp, theGC, FillStippled);
  884.     XSetStipple(theDisp, theGC, grayStip);
  885.     XSetForeground(theDisp, theGC, bg);
  886.     XSetBackground(theDisp, theGC, fg);
  887.     XFillRectangle(theDisp,lp->win,theGC,3,i*LINEHIGH,lp->w,LINEHIGH);
  888.     XSetForeground(theDisp, theGC, fg);
  889.     XSetFillStyle(theDisp, theGC, FillSolid);
  890.       }
  891. #endif
  892.  
  893.     }
  894.   }
  895. }
  896.  
  897.  
  898. /***************************************************/
  899. void LSRedraw(lp)
  900. LIST *lp;
  901. {
  902.   int  i;
  903.  
  904.   for (i = lp->scrl.val; i < lp->scrl.val + lp->nlines; i++) 
  905.     drawSel(lp,i);
  906. }
  907.  
  908.  
  909. /***************************************************/
  910. int LSClick(lp,ev)
  911. LIST *lp;
  912. XButtonEvent *ev;
  913. {
  914.   /* returns '-1' normally.  returns 0 -> numnames-1 for a goto */
  915.  
  916.   Window       rW, cW;
  917.   int          rx, ry, x, y, sel, oldsel;
  918.   unsigned int mask;
  919.   static Time  lasttime=0;
  920.   static int   lastsel = -1;
  921.  
  922.   x = ev->x;  y = ev->y;
  923.   sel = lp->scrl.val + y/LINEHIGH;
  924.   if (sel >= lp->nstr) sel = lp->selected;
  925.  
  926.   /* see if it's a double click */
  927.   if (ev->time - lasttime < DBLCLKTIME && sel==lastsel 
  928.       && (lp->scrl.val + y/LINEHIGH) < lp->nstr
  929.       && !INACTIVE(lp,sel)) {
  930.     return (sel);
  931.   }
  932.  
  933.   lasttime = ev->time;  lastsel = sel;
  934.  
  935.   /* if not clicked on selected, turn off selected and select new one */
  936.   if (sel != lp->selected) {
  937.     oldsel = lp->selected;
  938.     lp->selected = sel;
  939.     drawSel(lp,sel);  drawSel(lp,oldsel);
  940.     XFlush(theDisp);
  941.   }
  942.  
  943.   while (XQueryPointer(theDisp,lp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
  944.     if (!(mask & Button1Mask)) break;    /* button released */
  945.  
  946.     if (y<0) { /* scroll up in list */ 
  947.       if (lp->scrl.val > lp->scrl.min) {
  948.     lp->selected = lp->scrl.val - 1;
  949.     SCSetVal(&lp->scrl, lp->scrl.val - 1);
  950.     Timer(100);
  951.       }
  952.     }
  953.  
  954.     else if (y > lp->h) { /* scroll down in list */
  955.       if (lp->scrl.val < lp->scrl.max) {
  956.     lp->selected = lp->scrl.val + lp->nlines;
  957.     if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1;
  958.     SCSetVal(&lp->scrl, lp->scrl.val + 1);
  959.     Timer(100);
  960.       }
  961.     }
  962.  
  963.     else {
  964.       sel = lp->scrl.val + y/LINEHIGH;
  965.       if (sel >= lp->nstr) sel = lp->nstr - 1;
  966.  
  967.       if (sel != lp->selected && sel >= lp->scrl.val &&
  968.       sel < lp->scrl.val + lp->nlines) {  
  969.     /* dragged to another on current page */
  970.     oldsel = lp->selected;
  971.     lp->selected = sel;
  972.     drawSel(lp, sel);  drawSel(lp, oldsel);
  973.     XFlush(theDisp);
  974.       }
  975.     }
  976.   }
  977.  
  978.   return(-1);
  979. }
  980.  
  981.  
  982.  
  983. \BARFOO\
  984. else
  985.   echo "will not over write ./xvctrl.c"
  986. fi
  987. if `test ! -s ./xvdir.c`
  988. then
  989. echo "writting ./xvdir.c"
  990. cat > ./xvdir.c << '\BARFOO\'
  991. /* 
  992.  * xvdir.c - Directory changin', file i/o dialog box
  993.  *
  994.  * callable functions:
  995.  *
  996.  *   CreateDirW(geom,bwidth)-  creates the dirW window.  Doesn't map it.
  997.  *   DirBox(vis)            -  random processing based on value of 'vis'
  998.  *                             maps/unmaps window, etc.
  999.  *   RedrawDirW(x,y,w,h)    -  called by 'expose' events
  1000.  *   ClickDirW()            -  handles mouse clicks in DirW
  1001.  *   LoadCurrentDirectory() -  loads up current dir information for dirW
  1002.  *   DoSave()               -  calls appropriate save routines
  1003.  *   SetDirFName()          -  sets the 'save-as' filename 
  1004.  */
  1005.  
  1006. /*
  1007.  * Copyright 1989, 1990 by the University of Pennsylvania
  1008.  *
  1009.  * Permission to use, copy, and distribute for non-commercial purposes,
  1010.  * is hereby granted without fee, providing that the above copyright
  1011.  * notice appear in all copies and that both the copyright notice and this
  1012.  * permission notice appear in supporting documentation.
  1013.  *
  1014.  * The software may be modified for your own purposes, but modified versions
  1015.  * may not be distributed.
  1016.  *
  1017.  * This software is provided "as is" without any express or implied warranty.
  1018.  */
  1019.  
  1020.  
  1021. #define NEEDSDIR
  1022. #include "xv.h"
  1023.  
  1024. #define NLINES 9                   /* # of lines in list control (keep odd) */
  1025. #define LISTW  200
  1026.  
  1027. #define BUTTW   60
  1028. #define BUTTH   19
  1029. #define DDWIDE  LISTW-80+15
  1030.  
  1031. #define MAXDEEP 30    /* maximum number of directories in cwd path */
  1032. #define MAXFNLEN 40   /* max length of filename being entered */
  1033.  
  1034. #define DEFFILENAME ""   /* default filename filled in when program starts */
  1035.  
  1036. #ifdef __STDC__
  1037. static void RedrawDList(void);
  1038. static int  dnamcmp(char **, char **);
  1039. #else
  1040. static void RedrawDList();
  1041. static int  dnamcmp();
  1042. #endif
  1043.  
  1044. static int    listh;
  1045. static char  *dirnames[MAXNAMES];
  1046. static int    numdirnames = 0, ndirs = 0;
  1047. static char   path[MAXPATHLEN+1];
  1048. static char  *dirs[MAXDEEP];            /* list of directory names */
  1049. static char  *lastdir;                  /* name of the directory we're in */
  1050. static char   filename[MAXFNLEN];       /* filename being entered */
  1051. static RBUTT *formatRB, *colorRB, *sizeRB;
  1052.  
  1053.  
  1054. /***************************************************/
  1055. void CreateDirW(geom)
  1056. char *geom;
  1057. {
  1058.   int y;
  1059.  
  1060.   listh = LINEHIGH * NLINES;
  1061.  
  1062.   dirW = CreateWindow("xv save dialog",geom,DIRWIDE, DIRHIGH, infofg, infobg);
  1063.   if (!dirW) FatalError("couldn't create 'save' window!");
  1064.  
  1065.   /* create doo-wah's */
  1066.   ddirW = XCreateSimpleWindow(theDisp, dirW, 40, 5, DDWIDE, LINEHIGH,
  1067.                   2, infofg, infobg);
  1068.   if (!ddirW) FatalError("can't create path window");
  1069.   XSelectInput(theDisp, ddirW, ExposureMask | ButtonPressMask);
  1070.  
  1071.   dnamW = XCreateSimpleWindow(theDisp, dirW, 80, listh+75-ASCENT-4, 
  1072.                   200, LINEHIGH+4, 1, infofg, infobg);
  1073.   if (!dnamW) FatalError("can't create name window");
  1074.   XSelectInput(theDisp, dnamW, ExposureMask);
  1075.  
  1076.  
  1077.   LSCreate(&dList, dirW, 10, 14+LINEHIGH, LISTW, listh, NLINES,
  1078.        dirnames, numdirnames,
  1079.        infofg, infobg, RedrawDList, 1, 0);
  1080.  
  1081.   BTCreate(&dbut[S_BOPEN], dirW, 233, dList.y-9+listh/5, 60, BUTTH, 
  1082.        "Open", infofg, infobg);
  1083.   BTCreate(&dbut[S_BSAVE], dirW, 233, dList.y-9+(listh*2)/5, 60, BUTTH, 
  1084.        "Save", infofg, infobg);
  1085.   BTCreate(&dbut[S_BCANC], dirW, 233, dList.y-9+(listh*3)/5, 60, BUTTH, 
  1086.        "Cancel", infofg, infobg);
  1087.   BTCreate(&dbut[S_BQUIT], dirW, 233, dList.y-9+(listh*4)/5, 60, BUTTH, 
  1088.        "Quit", infofg, infobg);
  1089.  
  1090.   y = listh + 110;
  1091.   formatRB = RBCreate(NULL, dirW, 26, y, "GIF", infofg, infobg);
  1092.   RBCreate(formatRB, dirW, 26, y+18, "PM", infofg, infobg);
  1093.   RBCreate(formatRB, dirW, 26, y+36, "PBM (raw)", infofg, infobg);
  1094.   RBCreate(formatRB, dirW, 26, y+54, "PBM (ascii)", infofg, infobg);
  1095.   RBCreate(formatRB, dirW, 26, y+72, "X11 Bitmap", infofg, infobg);
  1096.  
  1097.   colorRB = RBCreate(NULL, dirW, DIRWIDE/2, y, "Full Color", infofg, infobg);
  1098.   RBCreate(colorRB, dirW, DIRWIDE/2, y+18, "Greyscale", infofg, infobg);
  1099.   RBCreate(colorRB, dirW, DIRWIDE/2, y+36, "B/W Dithered", infofg, infobg);
  1100.  
  1101.   y = y + 115;
  1102.   sizeRB = RBCreate(NULL, dirW, 26, y, "Normal Size", infofg, infobg);
  1103.   RBCreate(sizeRB, dirW, 26, y+18, "At Current Expansion", infofg, infobg);
  1104.  
  1105.   SetDirFName(DEFFILENAME);
  1106.  
  1107.   LoadCurrentDirectory();
  1108.  
  1109.   XMapSubwindows(theDisp, dirW);
  1110. }
  1111.   
  1112.  
  1113. /***************************************************/
  1114. void DirBox(vis)
  1115. int vis;
  1116. {
  1117.   if (vis) XMapRaised(theDisp, dirW);
  1118.   else     XUnmapWindow(theDisp, dirW);
  1119.  
  1120.   BTSetActive(&but[BSAVE], !vis);
  1121.  
  1122.   dirUp = vis;
  1123. }
  1124.  
  1125.  
  1126. /***************************************************/
  1127. void RedrawDirW(x,y,w,h)
  1128. int x,y,w,h;
  1129. {
  1130.   int  i,ypos;
  1131.   char foo[30];
  1132.   XRectangle xr;
  1133.  
  1134.   xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
  1135.   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
  1136.  
  1137.   if (dList.nstr==1) strcpy(foo,"1 file");
  1138.                 else sprintf(foo,"%d files",dList.nstr);
  1139.  
  1140.   ypos = dList.y + dList.h + 5 + ASCENT;
  1141.   XSetForeground(theDisp, theGC, infobg);
  1142.   XFillRectangle(theDisp, dirW, theGC, 10, ypos-ASCENT, DIRWIDE, CHIGH);
  1143.   XSetForeground(theDisp, theGC, infofg);
  1144.   XDrawString(theDisp, dirW, theGC, 10, ypos, foo, strlen(foo));
  1145.  
  1146.   XDrawString(theDisp, dirW, theGC, 10, dList.h+75, "File name:",10);
  1147.  
  1148.   for (i=0; i<S_NBUTTS; i++) BTRedraw(&dbut[i]);
  1149.  
  1150.   RBRedraw(formatRB, -1);
  1151.   RBRedraw(colorRB, -1);
  1152.   RBRedraw(sizeRB, -1);
  1153.  
  1154.   ULineString(dirW, "Format", formatRB->x-16, formatRB->y-3-DESCENT);
  1155.   ULineString(dirW, "Colors", colorRB->x-16,  colorRB->y-3-DESCENT);
  1156.   ULineString(dirW, "Size",   sizeRB->x-16,   sizeRB->y-3-DESCENT);
  1157.  
  1158.   XSetClipMask(theDisp, theGC, None);
  1159. }
  1160.  
  1161.  
  1162. /***************************************************/
  1163. void RedrawDDirW()
  1164. {
  1165.   XSetForeground(theDisp, theGC, infofg);
  1166.   XSetBackground(theDisp, theGC, infobg);
  1167.  
  1168.   XClearWindow(theDisp, ddirW);
  1169.   XDrawString(theDisp, ddirW, theGC, 3, ASCENT + 1,
  1170.               lastdir, strlen(lastdir));
  1171. }
  1172.  
  1173.  
  1174. /***************************************************/
  1175. int ClickDirW(x,y)
  1176. int x,y;
  1177. {
  1178.   BUTT  *bp;
  1179.   int    bnum;
  1180.  
  1181.  
  1182.   /* check the RBUTTS first, since they don't DO anything */
  1183.   if ( (bnum=RBClick(formatRB, x,y)) >= 0) { 
  1184.     RBTrack(formatRB, bnum);
  1185.     if (RBWhich(formatRB)==4) {  /* turn off FULLCOLOR + GRAYSCALE */
  1186.       RBSetActive(colorRB,0,0);
  1187.       RBSetActive(colorRB,1,0);
  1188.       RBSelect(colorRB,2);
  1189.     }
  1190.     else {                       /* turn on FULLCOLOR + GRAYSCALE */
  1191.       RBSetActive(colorRB,0,1);
  1192.       RBSetActive(colorRB,1,1);
  1193.     }
  1194.     return -1;
  1195.   }
  1196.  
  1197.   if ( (bnum=RBClick(colorRB, x,y)) >= 0) 
  1198.     { RBTrack(colorRB, bnum);  return -1; }
  1199.  
  1200.   if ( (bnum=RBClick(sizeRB, x,y)) >= 0) 
  1201.     { RBTrack(sizeRB, bnum);  return -1; }
  1202.  
  1203.   for (bnum=0; bnum<S_NBUTTS; bnum++) {
  1204.     bp = &dbut[bnum];
  1205.     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
  1206.   }
  1207.  
  1208.   if (bnum<S_NBUTTS) {   /* found one */
  1209.     if (BTTrack(bp)) return (bnum);
  1210.   }
  1211.  
  1212.   return -1;
  1213. }
  1214.  
  1215.  
  1216. /***************************************************/
  1217. void SelectDir(n)
  1218. int n;
  1219. {
  1220.   int pend;
  1221.  
  1222.   /* called when entry #n in the dir list was selected/double-clicked */
  1223.  
  1224.   if (dList.str[n][0] == C_DIR || 
  1225.       dList.str[n][0] == C_LNK) {  /* it's cool, it's (possibly) a directory */
  1226.     pend = strlen(path);
  1227.     strcat(path,dList.str[n]+1);   /* add to pathname */
  1228.     if (chdir(path)) {
  1229.       fprintf(stderr,"unable to cd to '%s'\n",path);
  1230.       path[pend] = '\0';           /* undo path modification */
  1231.     }
  1232.     else 
  1233.       LoadCurrentDirectory();
  1234.   }
  1235.  
  1236.   else {  /* not a directory */
  1237.     /* copy the clicked-on filename into the 'save-as' filename */
  1238.     SetDirFName(dList.str[n]+1);
  1239.   }
  1240. }
  1241.  
  1242.  
  1243. /***************************************************/
  1244. void TrackDDirW(x,y)
  1245. int x,y;
  1246. {
  1247.   Window        menuW, rW, cW;
  1248.   int           rx, ry, i,j, sel, lastsel;
  1249.   unsigned int  mask;
  1250.  
  1251.   XSetForeground(theDisp, theGC, infofg);
  1252.   XSetBackground(theDisp, theGC, infobg);
  1253.  
  1254.   menuW = XCreateSimpleWindow(theDisp, dirW, 40, 5, DDWIDE, ndirs*LINEHIGH,
  1255.                   2, infofg, infobg);
  1256.   if (!menuW) FatalError("can't create path window");
  1257.  
  1258.   XMapRaised(theDisp, menuW);
  1259.  
  1260.   for (i=ndirs-1, j=0; i>=0; i--,j++)
  1261.     XDrawString(theDisp, menuW, theGC, 3, j*LINEHIGH + ASCENT + 1,
  1262.         dirs[i], dirs[i+1]-dirs[i]);
  1263.  
  1264.   XFlush(theDisp);
  1265.   XSetFunction(theDisp, theGC, GXinvert);
  1266.   XSetPlaneMask(theDisp, theGC, infofg ^ infobg);
  1267.   lastsel = -1;  sel = 0;
  1268.  
  1269.   while (XQueryPointer(theDisp, menuW, &rW, &cW, &rx, &ry, &x, &y, &mask)) {
  1270.     if (!(mask & Button1Mask)) break;
  1271.  
  1272.     /* see if mouse has left window */
  1273.  
  1274.     sel = y / LINEHIGH;
  1275.     if (sel>=ndirs) sel = ndirs-1;
  1276.     if (sel<0) sel = 0;
  1277.     if (sel != lastsel) {
  1278.       XFillRectangle(theDisp,menuW,theGC,0,lastsel*LINEHIGH,DDWIDE,LINEHIGH);
  1279.       XFillRectangle(theDisp,menuW,theGC,0,sel*LINEHIGH,DDWIDE,LINEHIGH);
  1280.       lastsel = sel;
  1281.     }
  1282.   }
  1283.  
  1284.   XSetFunction(theDisp, theGC, GXcopy);
  1285.   XSetPlaneMask(theDisp, theGC, AllPlanes);
  1286.   XDestroyWindow(theDisp, menuW);
  1287.  
  1288.   if (sel!=0) { /* changed directories */
  1289.     /* end 'path' by changing trailing '/' (of dir name) to a '\0' */
  1290.     *(dirs[(ndirs-1)-sel + 1] - 1) = '\0';
  1291.  
  1292.     /* special case:  if cd to '/', fix path (it's currently "") */
  1293.     if (path[0] == '\0') strcpy(path,"/");
  1294.  
  1295.     if (chdir(path)) {
  1296.       fprintf(stderr,"unable to cd to '%s'\n",path);
  1297.     }
  1298.     else 
  1299.       LoadCurrentDirectory();   
  1300.   }
  1301. }
  1302.  
  1303.  
  1304. /***************************************************/
  1305. static void RedrawDList()
  1306. {
  1307.   LSRedraw(&dList);
  1308. }
  1309.  
  1310.  
  1311. /***************************************************/
  1312. void LoadCurrentDirectory()
  1313. {
  1314.   DIR           *dirp;
  1315. #ifdef DIRENT
  1316.   struct dirent *dp;
  1317. #else
  1318.   struct direct *dp;
  1319. #endif
  1320.   int            i, ftype;
  1321.   struct stat    st;
  1322.   char          *dbeg, *dend;
  1323.  
  1324.   /* get rid of previous file names */
  1325.   for (i=0; i<numdirnames; i++) free(dirnames[i]);
  1326.  
  1327.   numdirnames = 0;
  1328.  
  1329. #ifdef SYSV
  1330.   getcwd(path, sizeof(path));
  1331. #else
  1332.   getwd(path);
  1333. #endif
  1334.   if (path[strlen(path)-1] != '/')
  1335.     strcat(path,"/");   /* tack on a trailing '/' to make path consistent */
  1336.  
  1337.   /* path will be something like: "/u3/bradley/src/weiner/whatever/" */
  1338.   /* parse path into individual directory names */
  1339.   dbeg = dend = path;
  1340.   for (i=0; i<MAXDEEP && dend; i++) {
  1341.     dend = strchr(dbeg,'/');  /* find next '/' char */
  1342.     dirs[i] = dbeg;
  1343.     dbeg = dend+1;
  1344.   }
  1345.   ndirs = i-1;
  1346.  
  1347.   lastdir = dirs[ndirs-1];
  1348.   RedrawDDirW();
  1349.  
  1350.   dirp = opendir(".");
  1351.   if (!dirp) {
  1352.     fprintf(stderr,"unable to open current directory");
  1353.     return;
  1354.   }
  1355.  
  1356.   i=0;
  1357.   while ( (dp = readdir(dirp)) != NULL) {
  1358.     if (strcmp(dp->d_name, ".")==0 || strcmp(dp->d_name, "..")==0) {
  1359.       /* skip over '.' and '..' */
  1360.     }
  1361.     else {
  1362. #ifdef DIRENT
  1363. #ifdef i386
  1364.       /* Not 100% sure d_reclen is correct, but it works...  MWS 10/18/90 */
  1365.       dirnames[i] = (char *) malloc(dp->d_reclen + 2); /* filetype + '\0'*/
  1366. #else
  1367.       dirnames[i] = (char *) malloc(strlen(dp->d_name) + 3);
  1368. #endif
  1369. #else
  1370.       dirnames[i] = (char *) malloc(dp->d_namlen + 2); /* +2=filetype + '\0'*/
  1371. #endif
  1372.       if (!dirnames[i]) FatalError("malloc error while reading directory");
  1373.       strcpy(dirnames[i]+1, dp->d_name);
  1374.  
  1375.       /* figure out what type of file the beastie is */
  1376.       dirnames[i][0] = C_REG;   /* default to normal file, if lstat fails */
  1377.  
  1378. #if defined(i386) || defined (SYSV)
  1379.       if (stat(dirnames[i]+1, &st)==0) {
  1380. #else
  1381.       if (lstat(dirnames[i]+1, &st)==0) {
  1382. #endif
  1383.     ftype = st.st_mode & S_IFMT;   /* mask off uninteresting bits */
  1384.     if      (ftype == S_IFDIR)  dirnames[i][0] = C_DIR;
  1385.     else if (ftype == S_IFCHR)  dirnames[i][0] = C_CHR;
  1386.     else if (ftype == S_IFBLK)  dirnames[i][0] = C_BLK;
  1387.  
  1388. #ifdef S_IFIFO
  1389.     else if (ftype == S_IFIFO)  dirnames[i][0] = C_FIFO;
  1390. #endif
  1391.  
  1392. #ifdef S_IFLNK
  1393.     else if (ftype == S_IFLNK)  dirnames[i][0] = C_LNK;
  1394. #endif
  1395.  
  1396. #ifdef S_IFSOCK
  1397.         else if (ftype == S_IFSOCK) dirnames[i][0] = C_SOCK;
  1398. #endif
  1399.       }
  1400.       else {
  1401.     /* fprintf(stderr,"problems 'stat-ing' files\n");*/
  1402.     dirnames[i][0] = C_REG;
  1403.       }
  1404.       i++;
  1405.     }
  1406.   }
  1407.  
  1408.   closedir(dirp);
  1409.  
  1410.   numdirnames = i;
  1411.  
  1412.   qsort((char *) dirnames, numdirnames, sizeof(char *), dnamcmp);
  1413.   LSNewData(&dList, dirnames, numdirnames);
  1414.   DirOpenActive();
  1415.   RedrawDirW(0,0,DIRWIDE,DIRHIGH);
  1416. }
  1417.  
  1418.  
  1419. /***************************************************/
  1420. static int dnamcmp(s1,s2)
  1421. char **s1, **s2;
  1422. {
  1423.   /* sort so that directories are at beginning of list */
  1424.  
  1425.   /* if both dirs or both not dirs, sort on name */
  1426.   if ( (**s1 == C_DIR && **s2 == C_DIR) || (**s1 != C_DIR && **s2 != C_DIR))
  1427.     return (strcmp((*s1)+1, (*s2)+1));
  1428.  
  1429.   else if (**s1==C_DIR) return -1;  /* s1 is first */
  1430.   else return 1;                    /* s2 is first */
  1431. }
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437. /***************************************************/
  1438. int DirKey(c)
  1439. int c;
  1440. {
  1441.   /* got keypress in dirW.  stick on end of filename */
  1442.   int len;
  1443.  
  1444.   len = strlen(filename);
  1445.   
  1446.   if (c>' ' && c<'\177') {              /* printable characters */
  1447.     if (c=='/') return(-1);             /* no directories in filename */
  1448.     if (len >= MAXFNLEN-1) return(-1);  /* max length of string */
  1449.     filename[len]=c;  filename[len+1]='\0';
  1450.   }
  1451.  
  1452.   else if (c=='\010' || c=='\177') {    /* BS or DEL */
  1453.     if (len==0) return(-1);             /* string already empty */
  1454.     filename[len-1]='\0';
  1455.   }
  1456.  
  1457.   else if (c=='\025' || c=='\013') {    /* ^U or ^K clear line */
  1458.     filename[0] = '\0';
  1459.   }
  1460.  
  1461.   else if (c=='\012' || c=='\015') {    /* CR or LF */
  1462.     FakeButtonPress(&dbut[S_BSAVE]);
  1463.   }
  1464.  
  1465.   else return(-1);                      /* unhandled character */
  1466.  
  1467.   SetDirFName(filename);
  1468.   return(0);
  1469. }
  1470.  
  1471.  
  1472. /***************************************************/
  1473. void RedrawDNamW()
  1474. {
  1475.   int width, len;
  1476.  
  1477.   len = strlen(filename);
  1478.   XSetForeground(theDisp, theGC, infofg);
  1479.   XDrawString(theDisp, dnamW, theGC, 3, ASCENT+3, filename, len);
  1480.   width = StringWidth(filename);
  1481.   XDrawLine(theDisp, dnamW, theGC, 3+width+1, 3, 3+width+1, 
  1482.         3+CHIGH);
  1483. }
  1484.  
  1485.  
  1486. /***************************************************/
  1487. void DirOpenActive()
  1488. {
  1489.   if (dList.selected>=dList.nstr || dList.selected<0) 
  1490.     BTSetActive(&dbut[S_BOPEN],0);
  1491.  
  1492.   else if (dList.str[dList.selected][0] == C_DIR ||
  1493.       dList.str[dList.selected][0] == C_LNK) 
  1494.     BTSetActive(&dbut[S_BOPEN],1);
  1495.  
  1496.   else
  1497.     BTSetActive(&dbut[S_BOPEN],0);
  1498.  
  1499.   XFlush(theDisp);
  1500. }
  1501.  
  1502.  
  1503.  
  1504. /***************************************************/
  1505. int DoSave()
  1506. {
  1507.   FILE *fp;
  1508.   byte *thepic, *bwpic;
  1509.   int   w,h,rv,i;
  1510.  
  1511.   /* opens file, does appropriate color pre-processing, calls save routine
  1512.      based on chosen format.  Returns '0' if successful */
  1513.  
  1514.   WaitCursor();
  1515.  
  1516.   bwpic = NULL;
  1517.  
  1518.   if (RBWhich(sizeRB)==1) { thepic = epic;  w = eWIDE;  h = eHIGH; }
  1519.                      else { thepic = cpic;  w = cWIDE;  h = cHIGH; }
  1520.  
  1521.   if (RBWhich(colorRB)==2) {
  1522.     /* generate a FSDithered 1-byte per pixel image */
  1523.     bwpic = (byte *) malloc(w*h);
  1524.     if (!bwpic) FatalError("unable to malloc dithered picture (DoSave)");
  1525.     FSDither(thepic, w, h, bwpic);
  1526.     thepic = bwpic;
  1527.   }
  1528.  
  1529.   /* open file */
  1530.   fp = fopen(filename, "w");
  1531.   if (!fp) {
  1532.     SetISTR(ISTR_INFO,"Can't create '%s' -  %s",filename,sys_errlist[errno]);
  1533.     Warning();
  1534.     if (bwpic) free(bwpic);
  1535.     SetCursors(-1);
  1536.     return -1;
  1537.   }
  1538.  
  1539.   if ((mono || ncols==0) && RBWhich(colorRB)==0) {
  1540.     /* if we're saving color, but we're viewing B/W we have to NOT do
  1541.        the 'monofication' of the colormap ... */
  1542.     for (i=0; i<numcols; i++) {
  1543.       r[i] = rorg[i];  g[i] = gorg[i];  b[i] = borg[i];  /* original */
  1544.       
  1545.       if (revvideo) {
  1546.     r[i] = 255-r[i];  g[i] = 255-g[i];  b[i] = 255-b[i];
  1547.       }
  1548.    } 
  1549.  
  1550.     GammifyColors();
  1551.   }
  1552.       
  1553.   rv = 0;
  1554.   i = RBWhich(formatRB);
  1555.   switch (i) {
  1556.   case 0:  rv = WriteGIF(fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB));
  1557.            break;
  1558.   case 1:  rv = WritePM (fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB)); 
  1559.            break;
  1560.   case 2:  rv = WritePBM(fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB),1);
  1561.            break;
  1562.   case 3:  rv = WritePBM(fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB),0);
  1563.            break;
  1564.   case 4:  rv = WriteXBM(fp,thepic,w, h, filename);
  1565.            break;
  1566.   }
  1567.  
  1568.   fclose(fp);
  1569.   if (rv) unlink(filename);   /* couldn't properly write file:  delete it */
  1570.  
  1571.   if (!rv) {
  1572.     SetISTR(ISTR_INFO,"Successfully wrote '%s'",filename);
  1573.     LoadCurrentDirectory();   /* wrote file: rescan directory */
  1574.   }
  1575.  
  1576.   if (bwpic) free(bwpic);
  1577.  
  1578.   if ((mono || ncols==0) && RBWhich(colorRB)==0) {
  1579.     /* restore normal colormap */
  1580.     DoMonoAndRV();
  1581.     GammifyColors();
  1582.   }
  1583.  
  1584.   SetCursors(-1);
  1585.  
  1586.   return rv;
  1587. }
  1588.  
  1589.  
  1590.  
  1591. /***************************************************/
  1592. void SetDirFName(st)
  1593. char *st;
  1594. {
  1595.   strncpy(filename, st, MAXFNLEN-1);
  1596.   filename[MAXFNLEN-1] = '\0';  /* make sure it's terminated */
  1597.   XClearWindow(theDisp, dnamW);
  1598.   RedrawDNamW();
  1599.   BTSetActive(&dbut[S_BSAVE], strlen(filename)!=0);
  1600. }
  1601.  
  1602. \BARFOO\
  1603. else
  1604.   echo "will not over write ./xvdir.c"
  1605. fi
  1606. echo "Finished archive 7 of 10"
  1607. exit
  1608.  
  1609. dan
  1610. ----------------------------------------------------
  1611. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1612. Opinions expressed reflect those of the author only.
  1613. --
  1614. dan
  1615. ----------------------------------------------------
  1616. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1617. Opinions expressed reflect those of the author only.
  1618.