home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / xgif / part01 / xgif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-21  |  8.5 KB  |  328 lines

  1. /*
  2.  * xgif.c - displays GIF pictures on an X11 display
  3.  *
  4.  *  Author:    John Bradley, University of Pennsylvania
  5.  *                (bradley@cis.upenn.edu)
  6.  */
  7.  
  8. #define MAIN
  9. #include "xgif.h"
  10.  
  11.  
  12. /*******************************************/
  13. main(argc, argv)
  14.     int   argc;
  15.     char *argv[];
  16. /*******************************************/
  17. {
  18.     int        i;
  19.     char      *display, *geom, *fname;
  20.     XEvent     event;
  21.  
  22.     cmd = argv[0];
  23.     display = geom = fname = NULL;
  24.     expImage = NULL;
  25.  
  26.     expand = 1;  strip = 0;  nostrip = 0;
  27.  
  28.     /*********************Options*********************/
  29.  
  30.     for (i = 1; i < argc; i++) {
  31.         char *strind;
  32.  
  33.         if (!strncmp(argv[i],"-g",2)) {        /* geometry */
  34.             i++;
  35.             geom = argv[i];
  36.             continue;
  37.             }
  38.  
  39.         if (argv[i][0] == '=') {        /* old-style geometry */
  40.             geom = argv[i];
  41.             continue;
  42.             }
  43.  
  44.         if (!strncmp(argv[i],"-d",2)) {        /* display */
  45.             i++;
  46.             display = argv[i];
  47.             continue;
  48.             }
  49.  
  50.         strind = index(argv[i], ':');        /* old-style display */
  51.         if(strind != NULL) {
  52.             display = argv[i];
  53.             continue;
  54.             }
  55.  
  56.         if (!strcmp(argv[i],"-e")) {        /* expand */
  57.             i++;
  58.             expand=atoi(argv[i]);
  59.             continue;
  60.             }
  61.  
  62.         if (!strcmp(argv[i],"-s")) {        /* strip */
  63.             i++;
  64.             strip=atoi(argv[i]);
  65.             continue;
  66.             }
  67.  
  68.         if (!strcmp(argv[i],"-ns")) {        /* nostrip */
  69.             nostrip++;
  70.             continue;
  71.             }
  72.  
  73.         if (argv[i][0] != '-') {        /* the file name */
  74.             fname = argv[i];
  75.             continue;
  76.             }
  77.  
  78.         Syntax(cmd);
  79.     }
  80.  
  81.     if (fname==NULL) fname="-";
  82.     if (expand<1 || expand>MAXEXPAND) Syntax(cmd);
  83.     if (strip<0 || strip>7) Syntax(cmd);
  84.  
  85.     /*****************************************************/
  86.  
  87.     /* Open up the display. */
  88.  
  89.     if ( (theDisp=XOpenDisplay(display)) == NULL) {
  90.         fprintf(stderr, "%s: Can't open display\n",argv[0]);
  91.         exit(1);
  92.         }
  93.  
  94.     theScreen = DefaultScreen(theDisp);
  95.     theCmap   = DefaultColormap(theDisp, theScreen);
  96.     rootW     = RootWindow(theDisp,theScreen);
  97.     theGC     = DefaultGC(theDisp,theScreen);
  98.     fcol      = WhitePixel(theDisp,theScreen);
  99.     bcol      = BlackPixel(theDisp,theScreen);
  100.     theVisual = DefaultVisual(theDisp,theScreen);
  101.  
  102.     dispcells = DisplayCells(theDisp, theScreen);
  103.     if (dispcells<=2) 
  104.         FatalError("This program requires a color display, pref. 8 bits.");
  105.  
  106.  
  107.     /****************** Open/Read the File  *****************/
  108.     LoadGIF(fname);
  109.     iWIDE = theImage->width;  iHIGH = theImage->height;
  110.  
  111.     eWIDE = iWIDE * expand;  eHIGH = iHIGH * expand;
  112.     if (eWIDE > DisplayWidth(theDisp,theScreen)) 
  113.         eWIDE = DisplayWidth(theDisp,theScreen);
  114.     if (eHIGH > DisplayHeight(theDisp,theScreen)) 
  115.         eHIGH = DisplayHeight(theDisp,theScreen);
  116.  
  117.     /**************** Create/Open X Resources ***************/
  118.     if ((mfinfo = XLoadQueryFont(theDisp,"variable"))==NULL)
  119.        FatalError("couldn't open 'variable' font\n");
  120.     mfont=mfinfo->fid;
  121.     XSetFont(theDisp,theGC,mfont);
  122.     XSetForeground(theDisp,theGC,fcol);
  123.     XSetBackground(theDisp,theGC,bcol);
  124.  
  125.     CreateMainWindow(cmd,geom,argc,argv);
  126.     Resize(eWIDE,eHIGH);
  127.  
  128.     XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask 
  129.                                | StructureNotifyMask);
  130.     XMapWindow(theDisp,mainW);
  131.  
  132.     /**************** Main loop *****************/
  133.     while (1) {
  134.         XNextEvent(theDisp, &event);
  135.         HandleEvent(&event);
  136.         }
  137. }
  138.  
  139.  
  140.  
  141. /****************/
  142. HandleEvent(event)
  143.     XEvent *event;
  144. /****************/
  145. {
  146.     switch (event->type) {
  147.         case Expose: {
  148.             XExposeEvent *exp_event = (XExposeEvent *) event;
  149.  
  150.             if (exp_event->window==mainW) 
  151.                 DrawWindow(exp_event->x,exp_event->y,
  152.                            exp_event->width, exp_event->height);
  153.             }
  154.             break;
  155.  
  156.         case KeyPress: {
  157.             XKeyEvent *key_event = (XKeyEvent *) event;
  158.             char buf[128];
  159.             KeySym ks;
  160.             XComposeStatus status;
  161.  
  162.             XLookupString(key_event,buf,128,&ks,&status);
  163.             if (buf[0]=='q' || buf[0]=='Q') Quit();
  164.             }
  165.             break;
  166.  
  167.         case ConfigureNotify: {
  168.             XConfigureEvent *conf_event = (XConfigureEvent *) event;
  169.  
  170.             if (conf_event->window == mainW && 
  171.                  (conf_event->width != eWIDE || conf_event->height != eHIGH))
  172.                 Resize(conf_event->width, conf_event->height);
  173.             }
  174.             break;
  175.  
  176.  
  177.         case CirculateNotify:
  178.         case MapNotify:
  179.         case DestroyNotify:
  180.         case GravityNotify:
  181.         case ReparentNotify:
  182.         case UnmapNotify:       break;
  183.  
  184.         default:        /* ignore unexpected events */
  185.       break;
  186.         }  /* end of switch */
  187. }
  188.  
  189.  
  190. /***********************************/
  191. Syntax()
  192. {
  193.     printf("Usage: %s filename [[-geometry] geom] [[-display] display]\n",cmd);
  194.     printf("       [-e 1..%d] [-s 0-7] [-ns]\n",MAXEXPAND);
  195.     exit(1);
  196. }
  197.  
  198.  
  199. /***********************************/
  200. FatalError (identifier)
  201.        char *identifier;
  202. {
  203.     fprintf(stderr, "%s: %s\n",cmd, identifier);
  204.     exit(-1);
  205. }
  206.  
  207.  
  208. /***********************************/
  209. Quit()
  210. {
  211.     exit(0);
  212. }
  213.  
  214.  
  215. /***********************************/
  216. DrawWindow(x,y,w,h)
  217. {
  218.     XPutImage(theDisp,mainW,theGC,expImage,x,y,x,y,w,h);
  219. }
  220.  
  221.  
  222. /***********************************/
  223. Resize(w,h)
  224. int w,h;
  225. {
  226.     int  ix,iy,ex,ey;
  227.     byte *ximag,*ilptr,*ipptr,*elptr,*epptr;
  228.     static char *rstr = "Resizing Image.  Please wait...";
  229.  
  230.     /* warning:  this code'll only run machines where int=32-bits */
  231.  
  232.     if (w==iWIDE && h==iHIGH) {        /* very special case */
  233.         if (expImage != theImage) {
  234.             if (expImage) XDestroyImage(expImage);
  235.             expImage = theImage;
  236.             eWIDE = iWIDE;  eHIGH = iHIGH;
  237.             }
  238.         }
  239.  
  240.     else {                /* have to do some work */
  241.         /* if it's a big image, this'll take a while.  mention it */
  242.         if (w*h>(500*500)) {
  243.             XDrawImageString(theDisp,mainW,theGC,CENTERX(mfinfo,w/2,rstr),
  244.                   CENTERY(mfinfo,h/2),rstr, strlen(rstr));
  245.             XFlush(theDisp);
  246.             }
  247.  
  248.     /* first, kill the old expImage, if one exists */
  249.     if (expImage && expImage != theImage) {
  250.             free(expImage->data);  expImage->data = NULL;
  251.             XDestroyImage(expImage);
  252.             }
  253.  
  254.         /* create expImage of the appropriate size */
  255.         
  256.         eWIDE = w;  eHIGH = h;
  257.         ximag = (byte *) malloc(w*h);
  258.         expImage = XCreateImage(theDisp,theVisual,8,ZPixmap,0,ximag,
  259.                         eWIDE,eHIGH,8,eWIDE);
  260.  
  261.         if (!ximag || !expImage) {
  262.             fprintf(stderr,"ERROR: unable to create a %dx%d image\n",w,h);
  263.             exit(0);
  264.             }
  265.  
  266.         elptr = epptr = (byte *) expImage->data;
  267.  
  268.         for (ey=0;  ey<eHIGH;  ey++, elptr+=eWIDE) {
  269.             iy = (iHIGH * ey) / eHIGH;
  270.             epptr = elptr;
  271.             ilptr = (byte *) theImage->data + (iy * iWIDE);
  272.             for (ex=0;  ex<eWIDE;  ex++,epptr++) {
  273.                 ix = (iWIDE * ex) / eWIDE;
  274.                 ipptr = ilptr + ix;
  275.                 *epptr = *ipptr;
  276.                 }
  277.             }
  278.         }
  279. }
  280.                 
  281.  
  282. /***********************************/
  283. CreateMainWindow(name,geom,argc,argv)
  284.     char *name,*geom,**argv;
  285.     int   argc;
  286. {
  287.     XSetWindowAttributes xswa;
  288.     unsigned int xswamask;
  289.     XSizeHints hints;
  290.     int i,x,y,w,h;
  291.  
  292.     x=y=w=h=1;
  293.     i=XParseGeometry(geom,&x,&y,&w,&h);
  294.     if (i&WidthValue)  eWIDE = w;
  295.     if (i&HeightValue) eHIGH = h;
  296.  
  297.     if (i&XValue || i&YValue) hints.flags = USPosition;  
  298.                          else hints.flags = PPosition;
  299.  
  300.     hints.flags |= USSize;
  301.  
  302.     if (i&XValue && i&XNegative) 
  303.         x = XDisplayWidth(theDisp,theScreen)-eWIDE-abs(x);
  304.     if (i&YValue && i&YNegative) 
  305.         y = XDisplayHeight(theDisp,theScreen)-eHIGH-abs(y);
  306.  
  307.     hints.x=x;             hints.y=y;
  308.     hints.width  = eWIDE;  hints.height = eHIGH;
  309.     hints.max_width = DisplayWidth(theDisp,theScreen);
  310.     hints.max_height = DisplayHeight(theDisp,theScreen);
  311.     hints.flags |= PMaxSize;
  312.  
  313.     xswa.background_pixel = bcol;
  314.     xswa.border_pixel     = fcol;
  315.     xswamask = CWBackPixel | CWBorderPixel;
  316.  
  317.     mainW = XCreateWindow(theDisp,rootW,x,y,eWIDE,eHIGH,2,0,CopyFromParent,
  318.                           CopyFromParent, xswamask, &xswa);
  319.  
  320.     XSetStandardProperties(theDisp,mainW,"xgif","xgif",None,
  321.                             argv,argc,&hints);
  322.  
  323.     if (!mainW) FatalError("Can't open main window");
  324.  
  325. }
  326.  
  327.  
  328.