home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / space / software / unix / xanim / xanm_x11.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-04  |  15.0 KB  |  572 lines

  1.  
  2. /*
  3.  * xanim_x11.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed
  9.  * without fee provided that this copyright notice is preserved 
  10.  * intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18.  
  19. #include "xanim.h"
  20. #include <X11/Intrinsic.h>
  21. #include <X11/StringDefs.h>
  22. #include <X11/Shell.h>
  23. #include <sys/signal.h>
  24. #include <sys/times.h>
  25. #include <ctype.h>
  26. #include "xanim_x11.h"
  27.  
  28. void xanim_expose();
  29. void xanim_key();
  30. /*
  31. void xanim_quit();
  32. */
  33. void xanim_events();
  34. void X11Setup();
  35.  
  36. /*********************************** X11 stuff */
  37. Display       *theDisp;
  38. Visual        *theVisual;
  39. Colormap       theCmap;
  40. Window         mainW;
  41. GC             theGC;
  42. XImage        *theImage;
  43. XColor         defs[256];
  44. /******************************** Xt stuff */
  45. XtAppContext  theContext;
  46.  
  47. #define ACTIONTABLE_SIZE 2
  48. XtActionsRec actionTable[] = {
  49.         {"Expose", xanim_expose},
  50.         {"KeyUp", xanim_key}
  51. };
  52.  
  53. static struct _resource {
  54.   int anim;
  55. } resource;
  56.  
  57. #define offset(field)   XtOffset(struct _resource *, field)
  58.  
  59. XtResource application_resources[] = {
  60.   {"anim", "Anim", XtRBoolean, sizeof (Boolean),
  61.      offset(anim), XtRString, "False" },
  62. };
  63.  
  64. String   Translation =
  65. "<Expose>:Expose()\n\
  66. <KeyUp>:KeyUp()";
  67.  
  68. X11_Get_Shift(mask,shift,size)
  69. ULONG mask,*shift,*size;
  70. {
  71.   LONG i,j;
  72.  
  73.   i=0;
  74.   while( (i < 32) && !(mask & 0x01) ) 
  75.   {
  76.     mask >>= 1;
  77.     i++;
  78.   }
  79.   if (i >= 32)
  80.   {
  81.     fprintf(stderr,"X11_Get_Shift: wierd mask value %lx\n",mask);
  82.     i = 0;
  83.   }
  84.   *shift = i;
  85.   j=0;
  86.   while( (i < 32) && (mask & 0x01) ) 
  87.   {
  88.     mask >>= 1;
  89.     i++;
  90.     j++;
  91.   }
  92.   *size = j;
  93. }
  94.  
  95. ULONG X11_Get_True_Color(r,g,b,size)
  96. register ULONG r,g,b,size;
  97. {
  98.   register ULONG temp,temp_color;
  99.  
  100.   temp = (x11_red_size >= size)?(r << (x11_red_size - size))
  101.                                :(r >> (size - x11_red_size));
  102.   temp_color  = (temp << x11_red_shift) & x11_red_mask;
  103.  
  104.   temp = (x11_green_size >= size)?(g << (x11_green_size - size))
  105.                                  :(g >> (size - x11_green_size));
  106.   temp_color |= (temp << x11_green_shift) & x11_green_mask;
  107.  
  108.   temp = (x11_blue_size >= size)?(b << (x11_blue_size - size))
  109.                                 :(b >> (size - x11_blue_size));
  110.   temp_color |= (temp << x11_blue_shift) & x11_blue_mask;
  111.  
  112.   return(temp_color);
  113. }
  114.  
  115. void X11_Pre_Setup(argc, argv)
  116. int argc;
  117. char *argv[];
  118. {
  119.   int i,vis_num;
  120.   XVisualInfo *vis;
  121.  
  122.   XtToolkitInitialize();
  123.   theContext = XtCreateApplicationContext();
  124.   XtAppAddActions(theContext, actionTable, ACTIONTABLE_SIZE);
  125.  
  126.   i = 0;
  127.   theDisp = XtOpenDisplay(theContext, NULL, "xanim", "XAnim",NULL,0,&argc,argv);
  128.   if (theDisp==NULL) 
  129.   {
  130.     TheEnd1("Unable to open display\n"); 
  131.   }
  132.  
  133.   if (x11_verbose_flag == TRUE)
  134.   {
  135.     fprintf(stderr,"Looking Through Supported Visuals:\n");
  136.     vis = XGetVisualInfo (theDisp, VisualNoMask, NULL, &vis_num);
  137.     if ((vis == NULL) || (vis_num == 0) )
  138.     {
  139.       TheEnd1("X11: Couldn't get any Visuals\n");
  140.     }
  141.     else
  142.     {
  143.       for(i=0;i<vis_num;i++)
  144.       {
  145.         fprintf(stderr,"  visual %ld) depth= %ld  class= %ld  cmap size=%ld  ",
  146.                          i, vis[i].depth, vis[i].class, vis[i].colormap_size );
  147.         X11_OutPut_Visual_Class(vis[i].class);
  148.         fprintf(stderr,"\n");
  149.       }
  150.       fprintf(stderr,"\n");
  151.     }
  152.     XFree(vis);  
  153.   }
  154.  
  155.   theGC     = DefaultGC(theDisp,DefaultScreen(theDisp));
  156.   x11_depth = DefaultDepth(theDisp, DefaultScreen(theDisp));
  157.  
  158.   theVisual = DefaultVisual(theDisp, DefaultScreen(theDisp));
  159.   x11_class = theVisual->class;
  160.   x11_bit_order   = BitmapBitOrder(theDisp);
  161.   if (x11_bit_order == MSBFirst) x11_bit_order = X11_MSB;
  162.   else x11_bit_order = X11_LSB;
  163.   x11_bitmap_unit = BitmapUnit(theDisp);
  164.   x11_cmap_size   = DisplayCells(theDisp, DefaultScreen(theDisp));
  165.  
  166.   if ( (x11_class == PseudoColor) && (x11_depth <=8) && (x11_depth >=1) )
  167.   {
  168.     x11_bytes_pixel = 1;
  169.     x11_cmap_flag = TRUE;
  170.     x11_display_type = PSEUDO_COLOR;
  171.     if (x11_verbose_flag == TRUE)
  172.     {
  173.       fprintf(stderr,"PSEUDO_COLOR    ");
  174.       X11_OutPut_Visual_Class(x11_class); fprintf(stderr,"\n");
  175.       fprintf(stderr,"  cmap_size = %ld depth=%ld bytes_pixel=%ld\n",
  176.         x11_cmap_size,x11_depth,x11_bytes_pixel);
  177.       fprintf(stderr,"  Bit Order = %lx  bitmapunit = %lx bitmappad = %lx\n",
  178.         x11_bit_order,x11_bitmap_unit,BitmapPad(theDisp) );
  179.     }
  180.   }
  181.   else 
  182.   if (x11_class == TrueColor) 
  183.   {
  184.     if (x11_depth > 16) x11_bytes_pixel = 4;
  185.     else if (x11_depth > 8) x11_bytes_pixel = 2;
  186.     else x11_bytes_pixel = 1;
  187.     x11_cmap_flag = FALSE;
  188.     x11_display_type = TRUE_COLOR;
  189.     x11_red_mask = theVisual->red_mask;
  190.     x11_green_mask = theVisual->green_mask;
  191.     x11_blue_mask = theVisual->blue_mask;
  192.     X11_Get_Shift(x11_red_mask  , &x11_red_shift  , &x11_red_size  );
  193.     X11_Get_Shift(x11_green_mask, &x11_green_shift, &x11_green_size);
  194.     X11_Get_Shift(x11_blue_mask , &x11_blue_shift , &x11_blue_size );
  195.  
  196.     if (x11_verbose_flag == TRUE)
  197.     {
  198.       fprintf(stderr,"TRUE_COLOR    ");
  199.       X11_OutPut_Visual_Class(x11_class); fprintf(stderr,"\n");
  200.       fprintf(stderr,"  cmap_size = %ld depth=%ld bytes_pixel=%ld\n",
  201.           x11_cmap_size,x11_depth,x11_bytes_pixel);
  202.       fprintf(stderr,"  Bit Order = %lx  bitmapunit = %lx bitmappad = %lx\n",
  203.         x11_bit_order,x11_bitmap_unit,BitmapPad(theDisp) );
  204.       fprintf(stderr,"  X11 Color Masks =%lx %lx %lx\n",
  205.           x11_red_mask,x11_green_mask ,x11_blue_mask);
  206.       fprintf(stderr,"  X11 Color Shifts=%ld %ld %ld\n",
  207.           x11_red_shift, x11_green_shift, x11_blue_shift );
  208.       fprintf(stderr,"  X11 Color Sizes =%ld %ld %ld\n",
  209.           x11_red_size,x11_green_size ,x11_blue_size);
  210.     }
  211.   }
  212.   else
  213.   if (x11_depth == 1)
  214.   {
  215.     x11_display_type = MONOCHROME;
  216.     x11_bytes_pixel = 1;
  217.     x11_cmap_flag = FALSE;
  218.     x11_black = BlackPixel(theDisp,DefaultScreen(theDisp));
  219.     x11_white = WhitePixel(theDisp,DefaultScreen(theDisp));
  220.     if (x11_verbose_flag == TRUE)
  221.     {
  222.       fprintf(stderr,"MONOCHROME    ");
  223.       X11_OutPut_Visual_Class(x11_class); fprintf(stderr,"\n");
  224.       fprintf(stderr,"  cmap_size = %ld depth=%ld bytes_pixel=%ld\n",
  225.         x11_cmap_size,x11_depth,x11_bytes_pixel);
  226.       fprintf(stderr,"  Bit Order = %lx  bitmapunit = %lx bitmappad = %lx\n",
  227.         x11_bit_order,x11_bitmap_unit,BitmapPad(theDisp) );
  228.     }
  229.   }
  230.   else /* not yet supported */
  231.   {
  232.     fprintf(stderr,"Unsupported Visual class=%ld depth=%ld \n",
  233.     x11_class,x11_depth);
  234.     X11_OutPut_Visual_Class(x11_class); fprintf(stderr,"\n");
  235.     TheEnd();
  236.   }
  237.  
  238.  
  239.   if (x11_cmap_flag == TRUE)
  240.   {
  241.     cmap = (ColorReg *) malloc( x11_cmap_size * sizeof(ColorReg) );
  242.     if (cmap==0) fprintf(stderr,"X11 CMAP: couldn't malloc\n");
  243.  
  244.     for(i=0;i<x11_cmap_size;i++) 
  245.     {
  246.       defs[i].pixel = i;
  247.       defs[i].flags = DoRed | DoGreen | DoBlue;
  248.     }
  249.  
  250.     XQueryColors(theDisp,DefaultColormap(theDisp, DefaultScreen(theDisp)),
  251.                  defs,x11_cmap_size);
  252.  
  253.     for(i=0; i<x11_cmap_size; i++)
  254.     {
  255.       cmap[i].red   = (defs[i].red   >> 8) & 0xff;
  256.       cmap[i].green = (defs[i].green >> 8) & 0xff;
  257.       cmap[i].blue  = (defs[i].blue  >> 8) & 0xff;
  258.       if (x11_display_type == TRUE_COLOR)
  259.         cmap[i].map = X11_Get_True_Color(
  260.               cmap[i].red, cmap[i].green, cmap[i].blue, 8);
  261.       else cmap[i].map   = i;
  262.     }
  263.   }
  264. }
  265.  
  266. /*
  267.  * Setup X11 Display, Window and Toolkit
  268.  */
  269. void X11_Setup(max_imagex,max_imagey,startx,starty)
  270. int max_imagex,max_imagey;
  271. int startx,starty;
  272. {
  273.   int i;
  274.   Widget wg;
  275.   int n;
  276.   Arg arglist[20];
  277.   XWMHints xwm_hints;
  278.  
  279.   n = 0;
  280.   XtSetArg(arglist[n], XtNwidth, startx); n++;
  281.   XtSetArg(arglist[n], XtNheight, starty); n++;
  282.   XtSetArg(arglist[n], XtNmaxWidth, max_imagex); n++;
  283.   XtSetArg(arglist[n], XtNmaxHeight, max_imagey); n++;
  284.   wg = XtAppCreateShell("xanim", "XAnim", applicationShellWidgetClass, 
  285.                          theDisp, arglist, n);
  286.  
  287.   XtGetApplicationResources (wg, &resource, application_resources,
  288.                              XtNumber(application_resources), NULL, 0);
  289.  
  290.   XtRealizeWidget(wg);
  291.   XtOverrideTranslations(wg, XtParseTranslationTable(Translation));
  292.  
  293.   mainW = XtWindow(wg);
  294.  
  295.   if (x11_display_type == MONOCHROME)
  296.   {
  297.     i = X11_Get_Line_Size(max_imagex);
  298.     theImage = XCreateImage(theDisp,DefaultVisual(theDisp,
  299.             DefaultScreen(theDisp)),
  300.             x11_depth,XYPixmap,0,0,max_imagex,max_imagey,
  301.             x11_bytes_pixel,i);
  302.   }
  303.   else
  304.   {
  305.     theImage = XCreateImage(theDisp,DefaultVisual(theDisp,
  306.             DefaultScreen(theDisp)),
  307.             x11_depth,ZPixmap,0,0,max_imagex,max_imagey,
  308.             x11_bytes_pixel,(x11_bytes_pixel * max_imagex));
  309.   }
  310.   if (theImage == 0)
  311.     fprintf(stderr,"X11 Setup: create image failed\n");
  312.  
  313.   if (x11_cmap_flag == TRUE)
  314.   {
  315.     for(i=0; i<x11_cmap_size; i++)
  316.     {
  317.       defs[i].pixel = i;
  318.       defs[i].red   = cmap[i].red   << 8;
  319.       defs[i].green = cmap[i].green << 8;
  320.       defs[i].blue  = cmap[i].blue  << 8;
  321.       defs[i].flags = DoRed | DoGreen | DoBlue;
  322.     }
  323.     theCmap = XCreateColormap(theDisp,mainW,
  324.                               DefaultVisual(theDisp, DefaultScreen(theDisp)),
  325.                               AllocAll);
  326.     if (theCmap==0) 
  327.     {
  328.       fprintf(stderr,"cmap==0 error\n");
  329.     }
  330.     XStoreColors(theDisp,theCmap,defs,x11_cmap_size);
  331.     XInstallColormap(theDisp,theCmap);
  332.     XSetWindowColormap(theDisp, mainW, theCmap);
  333.   }
  334.  
  335.   xwm_hints.flags = InputHint;
  336.   XSetWMHints(theDisp,mainW,&xwm_hints);
  337.   XMapWindow(theDisp,mainW);
  338. /*
  339.   XSetInputFocus(theDisp,mainW,RevertToPointerRoot,CurrentTime);
  340. */
  341.   XFlush(theDisp);
  342. }
  343.  
  344. void xanim_expose(wg, event, str, np)
  345.         Widget          wg;
  346.         XExposeEvent   *event;
  347.         String         *str;
  348.         int            *np;
  349. {
  350.  if (anim_status == XA_UNSTARTED) 
  351.  {
  352.   anim_status = XA_RUN_NEXT;
  353.   anim_holdoff = TRUE;
  354.   XtAppAddTimeOut(theContext, 1, ShowAction, NULL);
  355.  }
  356.  
  357. /* need pointer to global theImage
  358.   XPutImage(theDisp,mainW,theGC,theImage,0,0,0,0,imagex,disp_y);
  359. */
  360.  
  361. }
  362.  
  363. void xanim_key(wg, event, str, np)
  364. Widget          wg;
  365. XKeyEvent      *event;
  366. String         *str;
  367. int            *np;
  368. {
  369.         char            buff[10];
  370.         KeySym          ks;
  371.         XComposeStatus  st;
  372. /* should always be KeyRelease 
  373.  if (event->type == KeyRelease)
  374.  {
  375. */
  376.         XLookupString(event, buff, 10, &ks, &st);
  377.     switch(buff[0])
  378.     {
  379.      case 'q':
  380.      case 'Q': TheEnd();
  381.            break;
  382.      case 'g':
  383.          case 'G': anim_flags &= (~ANIM_CYCLE);
  384.            break;
  385.          case 's': 
  386.          case 'S': 
  387.            if (cycle_on_flag) cycle_on_flag = 0;
  388.            else  cycle_on_flag = 1;
  389.            break;
  390.     
  391.          case 'r': 
  392.          case 'R': 
  393.            if (x11_cmap_flag == TRUE)
  394.            {
  395.             int j,c_off;
  396.  
  397.             c_off = x11_cmap_size-imagec;
  398.                     for(j=0;j<imagec;j++)
  399.                     {
  400.                      defs[j].pixel = j+c_off;
  401.                      defs[j].red   = cmap[j+c_off].red   << 8;
  402.                      defs[j].green = cmap[j+c_off].green << 8;
  403.                      defs[j].blue  = cmap[j+c_off].blue  << 8;
  404.                      defs[j].flags = DoRed | DoGreen | DoBlue;
  405.                     }
  406.                     XStoreColors(theDisp,theCmap,defs,imagec);
  407.              XFlush(theDisp);
  408.            }
  409.            break;
  410.          case '.': 
  411.            if (   (anim_status == XA_STOP_NEXT)
  412.                || (anim_status == XA_STOP_PREV) )
  413.            {
  414.              anim_status = XA_STEP_NEXT;
  415.              if (anim_holdoff == TRUE) return;
  416.              anim_holdoff = TRUE;
  417.                    XtAppAddTimeOut(theContext, 1, ShowAction, NULL);
  418.            }
  419.            else anim_status = XA_STOP_NEXT;
  420.            break;
  421.          case ',': 
  422.            if (   (anim_status == XA_STOP_NEXT)
  423.                || (anim_status == XA_STOP_PREV) )
  424.            {
  425.              anim_status = XA_STEP_PREV;
  426.              if (anim_holdoff == TRUE) return;
  427.              anim_holdoff = TRUE;
  428.                    XtAppAddTimeOut(theContext, 1, ShowAction, NULL);
  429.            }
  430.            else anim_status = XA_STOP_PREV;
  431.            break;
  432.          case '>': 
  433.            if (   (anim_status == XA_STOP_NEXT)
  434.                || (anim_status == XA_STOP_PREV) )
  435.            {
  436.              anim_status = XA_FILE_NEXT;
  437.              if (anim_holdoff == TRUE) return;
  438.              anim_holdoff = TRUE;
  439.                    XtAppAddTimeOut(theContext, 1, ShowAction, NULL);
  440.            }
  441.            else anim_status = XA_STOP_NEXT;
  442.            break;
  443.          case '<': 
  444.            if (   (anim_status == XA_STOP_NEXT)
  445.                || (anim_status == XA_STOP_PREV) )
  446.            {
  447.              anim_status = XA_FILE_PREV;
  448.              if (anim_holdoff == TRUE) return;
  449.              anim_holdoff = TRUE;
  450.                    XtAppAddTimeOut(theContext, 1, ShowAction, NULL);
  451.            }
  452.            else anim_status = XA_STOP_PREV;
  453.            break;
  454.          case ' ': 
  455.            switch(anim_status)
  456.            {
  457.             case XA_RUN_NEXT:   
  458.                     anim_status = XA_STOP_NEXT; 
  459.                     break;
  460.             case XA_RUN_PREV:   
  461.                     anim_status = XA_STOP_PREV; 
  462.                     break;
  463.             case XA_STOP_NEXT:  
  464.                     anim_status = XA_RUN_NEXT;  
  465.                          if (anim_holdoff == TRUE) return;
  466.                     anim_holdoff = TRUE;
  467.                              XtAppAddTimeOut(theContext, 1, 
  468.                             ShowAction, NULL);
  469.                     break;
  470.             case XA_STOP_PREV:  
  471.                     anim_status = XA_RUN_PREV;  
  472.                          if (anim_holdoff == TRUE) return;
  473.                     anim_holdoff = TRUE;
  474.                              XtAppAddTimeOut(theContext, 1, 
  475.                             ShowAction, NULL);
  476.                     break;
  477.             case XA_STEP_NEXT:  
  478.                     anim_status = XA_RUN_NEXT;  
  479.                     break;
  480.             case XA_STEP_PREV:  
  481.                     anim_status = XA_RUN_PREV;  
  482.                     break;
  483.             case XA_FILE_NEXT:  
  484.                     anim_status = XA_RUN_NEXT;  
  485.                     break;
  486.             case XA_FILE_PREV:  
  487.                     anim_status = XA_RUN_PREV;  
  488.                     break;
  489.             default:         anim_status = XA_STOP_NEXT; 
  490.                     break;
  491.            }
  492.            break;
  493.     }
  494. /* 
  495.  }
  496. */
  497. }
  498.  
  499. /* TEST
  500. void xanim_quit(wg, event, str, np)
  501. Widget          wg;
  502. XKeyEvent      *event;
  503. String         *str;
  504. int            *np;
  505. {
  506.  TheEnd(); 
  507. }
  508. */
  509.  
  510. void xanim_events()
  511. {
  512.  XtAppMainLoop(theContext);
  513. }
  514.  
  515. ULONG X11_Get_Line_Size(xsize)
  516. ULONG xsize;
  517. {
  518.   ULONG line_size;
  519.  
  520.   if (x11_display_type == MONOCHROME)
  521.   {
  522.     line_size = xsize / x11_bitmap_unit;
  523.     if (xsize % x11_bitmap_unit) line_size++;
  524.     line_size = (line_size * x11_bitmap_unit) / 8;
  525.   }
  526.   else line_size = xsize * x11_bytes_pixel;
  527.   return(line_size);
  528. }
  529.  
  530.  
  531.   /*
  532.    * What's this!? Direct access to X11 structures. tsch tsch.
  533.    *
  534.    * With half-height images, I fool X11 by telling it the image is
  535.    * twice as wide and half as high, then only display left half of image.
  536.    */
  537. X11_Init_Image_Struct(image,xsize,ysize,flags)
  538. XImage *image;
  539. ULONG xsize,ysize,flags;
  540. {
  541.   ULONG line_size;
  542.  
  543.   line_size = X11_Get_Line_Size(xsize);
  544.  
  545.   if (flags & ANIM_LACE)
  546.   {
  547.     image->width = 2 * xsize;
  548.     image->height = ysize/2;
  549.     image->bytes_per_line = 2 * line_size;
  550.   }
  551.   else
  552.   {
  553.     image->width = xsize;
  554.     image->height = ysize;
  555.     image->bytes_per_line = line_size;
  556.   }
  557. }
  558.  
  559. X11_OutPut_Visual_Class(vis_class)
  560. ULONG vis_class;
  561. {
  562.   switch(vis_class)
  563.   {
  564.    case GrayScale:   fprintf(stderr,"GrayScale"); break;
  565.    case StaticGray:  fprintf(stderr,"StaticGray"); break;
  566.    case PseudoColor: fprintf(stderr,"PseudoColor"); break;
  567.    case StaticColor: fprintf(stderr,"StaticColor"); break;
  568.    case DirectColor: fprintf(stderr,"DirectColor"); break;
  569.    case TrueColor:   fprintf(stderr,"TrueColor"); break;
  570.   }
  571. }
  572.