home *** CD-ROM | disk | FTP | other *** search
/ Dream 44 / Amiga_Dream_44.iso / Linux / Apps / xanim.tgz / xanim / xanim27064 / xa_x11.c < prev    next >
C/C++ Source or Header  |  1997-01-26  |  82KB  |  2,750 lines

  1.  
  2. /*
  3.  * xa_x11.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993,1994,1995,1996,1997 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved 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. /****************
  20.  * Rev History
  21.  *
  22.  * 12Feb95 - fixed calling params of Callbacks and Actions.
  23.  * 22Jun95 - Translations added to Remote Control Window as well so
  24.  *           now all keyboards commands should work there as well.
  25.  *******************************/
  26.  
  27.  
  28. #include "xanim.h"
  29. #include <Intrinsic.h>
  30. #include <StringDefs.h>
  31. #include <Shell.h>
  32. #include <Xatom.h>
  33.  
  34. #ifdef XA_ATHENA
  35. #include <Xaw/Form.h>
  36. #include <Xaw/Command.h>
  37. #endif
  38.  
  39. #ifdef XA_MOTIF
  40. #include <Xm/Xm.h>
  41. #include <Xm/Form.h>
  42. #include <Xm/PushB.h>
  43. #endif
  44.  
  45. #include <sys/signal.h>
  46. #ifndef VMS
  47. #include <sys/times.h>
  48. #endif
  49. #include <ctype.h>
  50.  
  51. #ifdef XSHM
  52. #include <sys/ipc.h>
  53. #include <sys/shm.h>
  54. #include <X11/extensions/XShm.h>
  55. #endif /*XSHM*/
  56. #ifdef XMBUF
  57. #include <X11/extensions/multibuf.h>
  58. #endif
  59.  
  60.  
  61. #include "xa_x11.h"
  62.  
  63. #include "xa_ipc.h"
  64.  
  65. extern xaULONG shm;
  66. extern xaULONG mbuf;
  67. extern XA_AUD_FLAGS *vaudiof;
  68. extern xaLONG xa_pingpong_flag;
  69.  
  70.  
  71. #include "xa_ipc_cmds.h"
  72. extern xaULONG xa_forkit;
  73.  
  74. /* These are the default X,Y Positions of the Main Window and the
  75.  * RemoteControl Window.
  76.  */
  77. #define XA_REMW_XPOS    20
  78. #define XA_REMW_YPOS    20
  79. #define XA_MAINW_XPOS   (XA_REMW_XPOS + 120)
  80. #define XA_MAINW_YPOS   20
  81.  
  82. extern XA_CHDR *xa_chdr_first;
  83. extern xaULONG x11_shared_flag;
  84. extern xaULONG x11_multibuf_flag;
  85. extern xaULONG x11_expose_flag;
  86. extern xaLONG x11_error_possible;
  87. extern xaULONG xa_speed_change;
  88. extern xaLONG xa_remote_ready;
  89. xaLONG xa_remote_realized = xaFALSE;
  90. xaLONG xa_remote_busy = xaFALSE;
  91.  
  92. /* SMR 8 */
  93. /* externs from xanim.c covering playing into another app's window */
  94. extern xaLONG xa_window_x;
  95. extern xaLONG xa_window_y;
  96. extern xaULONG xa_window_id;
  97. extern char *xa_window_propname;
  98. extern xaULONG xa_window_center_flag;
  99. extern xaULONG xa_window_prepare_flag;
  100. extern xaULONG xa_window_refresh_flag;
  101. extern xaULONG xa_window_resize_flag;
  102. /* end SMR 8 */
  103.  
  104. int XA_Error_Handler();
  105.  
  106. void xanim_expose();
  107. void xanim_key();
  108. void xanim_button();
  109. void xanim_resize();
  110. void xanim_events();
  111. void X11Setup();
  112. void X11_Show_Visuals();
  113. void X11_OutPut_Visual_Class();
  114. void X11_Init_Image_Struct();
  115. void X11_Get_Shift();
  116. void X11_Init();
  117. void X11_Pre_Setup();
  118. void X11_Setup_Window();
  119. void X11_Map_Window();
  120. void X11_Make_Nice_CHDR();
  121. void X11_Get_Colormap();
  122. void XA_Free_CMAP();
  123.  
  124. #ifdef XA_REMOTE_CONTROL
  125.  
  126. Widget play_widget,audio_widget,norm_widget;
  127. Widget remote_widget,last_widget;
  128.  
  129. void XA_Create_Remote();
  130. void XA_Realize_Remote();
  131. void XA_Unrealize_Remote();
  132. void XA_Remote_Free();
  133.  
  134. void XA_Remote_Pause();
  135. void XA_Remote_PlayNext();
  136. void XA_Remote_PlayPrev();
  137. void XA_Remote_PlayStop();
  138. void XA_Remote_StepPrev();
  139. void XA_Remote_StepNext();
  140. void XA_Remote_AudioOff();
  141. void XA_Remote_AudioOn();
  142. void XA_Remote_SpeedNorm();
  143. void XA_Remote_SpeedDiff();
  144. void XA_Remote_Adj_Volume();
  145. #endif
  146.  
  147. void XA_Install_CMAP();
  148. void IFF_Buffer_HAM6();
  149. void IFF_Buffer_HAM8();
  150. void UTIL_Mapped_To_Bitmap();
  151. void UTIL_Mapped_To_Mapped();
  152. xaULONG CMAP_Find_Closest();
  153. void XA_Store_Title();
  154.  
  155.  
  156.  
  157. /*********************************** X11 stuff */
  158. Display       *theDisp;
  159. int           theScreen;
  160. Visual        *theVisual;
  161. Colormap       theCmap = 0;
  162. Window         mainW;
  163.  
  164. #ifdef XMBUF
  165. Window        mainWreal;       /* actual main window */
  166. Window        mainWbuffers[2]; /* two buffers for the main window */
  167. int        mainWbufIndex;   /* which buffer is actually visible */
  168. #endif
  169.  
  170. GC             theGC = 0;
  171. XImage        *theImage = 0;
  172. XColor         defs[256];
  173. Widget           theWG;
  174.  
  175. GC             remoteGC = 0;
  176. Window         remoteW;
  177. /******************************** Xt stuff */
  178. extern XA_CHDR *xa_chdr_now;
  179. extern XA_ANIM_HDR *cur_file;
  180. extern xaULONG xa_title_flag;
  181. extern xaULONG xa_anim_flags;
  182. extern xaULONG x11_window_x,x11_window_y;
  183. extern xaULONG xa_buff_x,xa_buff_y;
  184. extern xaULONG xa_allow_resizing;
  185. extern xaULONG xa_allow_nice;
  186. extern xaULONG xa_speed_scale;
  187.  
  188. extern XA_AUD_FLAGS *AUD;
  189.  
  190. extern xaULONG xa_audio_newvol;
  191. extern xaLONG xa_audio_volume;
  192. extern xaULONG xa_audio_mute;
  193.  
  194.  
  195.  
  196. XtAppContext  theContext;
  197.  
  198. /*
  199.  * gf: Forward definitions of action procedures:
  200.  */
  201. static void xanim_step_prev_action(),xanim_step_next_action();
  202. static void xact_playnext(), xact_playprev(), xact_playstop();
  203. static void xanim_toggle_action(),xanim_quit_action();
  204. static void xanim_resize_action();
  205. static void xanim_install_cmap_action(),xanim_stop_cmap_action();
  206. static void xanim_restore_cmap_action();
  207. static void xanim_faster_action(),xanim_slower_action();
  208. static void xanim_speed_reset_action(); 
  209. static void xanim_next_anim_action(),xanim_prev_anim_action();
  210. static void xanim_step_prev_int_action(),xanim_step_next_int_action();
  211. static void xanim_dec_audio_5(),xanim_dec_audio_1();
  212. static void xanim_inc_audio_5(),xanim_inc_audio_1(),xanim_mute_audio();
  213. static void xanim_speaker_tog(),xanim_headphone_tog();
  214. static void xanim_realize_remote();
  215. static void xanim_set_volume();
  216. static void xanim_set_pingpong();
  217.  
  218. /*
  219.  * gf: Replace KeyUp() and ButtonPress() with more specific actions
  220.  */
  221.  
  222. #define ACTIONTABLE_SIZE 29
  223. XtActionsRec actionTable[] = {
  224.         {"Expose", xanim_expose},
  225.         {"Configure", xanim_resize},
  226.     {"StepPrev", xanim_step_prev_action},
  227.     {"StepNext", xanim_step_next_action},
  228.     {"RunStop", xanim_toggle_action},
  229.     {"Quit", xanim_quit_action},
  230.     {"Resize", xanim_resize_action},
  231.     {"InstallCmap", xanim_install_cmap_action},
  232.     {"RealizeRemote", xanim_realize_remote},
  233.     {"StopCmap", xanim_stop_cmap_action},
  234.     {"RestoreCmap", xanim_restore_cmap_action},
  235.     {"Slower", xanim_slower_action},
  236.     {"Faster", xanim_faster_action},
  237.     {"SpeedReset", xanim_speed_reset_action},
  238.     {"NextAnim", xanim_next_anim_action},
  239.     {"PrevAnim", xanim_prev_anim_action},
  240.     {"StepNextInt", xanim_step_next_int_action},
  241.     {"StepPrevInt", xanim_step_prev_int_action},
  242.     {"DecAudio5", xanim_dec_audio_5},
  243.     {"DecAudio1", xanim_dec_audio_1},
  244.     {"IncAudio5", xanim_inc_audio_5},
  245.     {"IncAudio1", xanim_inc_audio_1},
  246.     {"AudioMute", xanim_mute_audio},
  247.     {"SpeakerTog",xanim_speaker_tog},
  248.     {"HDPhoneTog",xanim_headphone_tog},
  249.     {"PlayNext",xact_playnext},
  250.     {"PlayPrev",xact_playprev},
  251.     {"PingPong",xanim_set_pingpong},
  252.     {"PlayStop",xact_playstop}
  253. };
  254.  
  255. typedef struct {
  256.   int anim;
  257.   int remote_xpos;
  258.   int remote_ypos;
  259.   int window_xpos;
  260.   int window_ypos;
  261.   int audio_volume;
  262. } xanim_resources;
  263.  
  264. xanim_resources xa_resources;
  265.  
  266. #define offset(field)   XtOffsetOf(xanim_resources, field)
  267.  
  268. XtResource application_resources[] = {
  269.   {"anim", "Anim", XtRBoolean, sizeof(Boolean),
  270.      offset(anim), XtRString, "False" },
  271.   {"remote_xpos", "XAnim_Var", XtRInt, sizeof(int),
  272.      offset(remote_xpos), XtRImmediate, (XtPointer)XA_REMW_XPOS },
  273.   {"remote_ypos", "XAnim_Var", XtRInt, sizeof(int),
  274.      offset(remote_ypos), XtRImmediate, (XtPointer)XA_REMW_YPOS },
  275.   {"window_xpos", "XAnim_Var", XtRInt, sizeof(int),
  276.      offset(window_xpos), XtRImmediate, (XtPointer)XA_MAINW_XPOS },
  277.   {"window_ypos", "XAnim_Var", XtRInt, sizeof(int),
  278.      offset(window_ypos), XtRImmediate, (XtPointer)XA_MAINW_YPOS },
  279.   {"audio_volume", "XAnim_Var", XtRInt, sizeof(int),
  280.      offset(audio_volume), XtRImmediate, (XtPointer)10 }
  281. };
  282.  
  283. String   Translation =
  284.   "<Expose>:        Expose()\n\
  285.    <Configure>:        Configure()\n\
  286.    <Btn1Down>,<Btn1Up>:    StepPrev()\n\
  287.    <Btn2Down>,<Btn2Up>:    RunStop()\n\
  288.    <Btn3Down>,<Btn3Up>:    StepNext()\n\
  289.    <Key>1:        DecAudio5()\n\
  290.    <Key>2:        DecAudio1()\n\
  291.    <Key>3:        IncAudio1()\n\
  292.    <Key>4:        IncAudio5()\n\
  293.    <Key>8:        SpeakerTog()\n\
  294.    <Key>9:        HDPhoneTog()\n\
  295.    <Key>s:        AudioMute()\n\
  296.    <Key>q:        Quit()\n\
  297.    <Key>w:        Resize()\n\
  298.    <Key>F:        InstallCmap()\n\
  299.    <Key>z:        RealizeRemote()\n\
  300.    <Key>g:        StopCmap()\n\
  301.    <Key>p:        PingPong()\n\
  302.    <Key>r:        RestoreCmap()\n\
  303.    <Key>-:        Slower()\n\
  304.    <Key>=:        Faster()\n\
  305.    <Key>0:        SpeedReset()\n\
  306.    <Key>.:        StepNext()\n\
  307.    <Key>comma:        StepPrev()\n\
  308.    <Key>greater:    NextAnim()\n\
  309.    <Key>less:        PrevAnim()\n\
  310.    <Key>/:        StepNextInt()\n\
  311.    <Key>m:        StepPrevInt()\n\
  312.    <Key>space:        RunStop()";
  313.  
  314. void X11_Get_Shift(mask,shift,size)
  315. xaULONG mask,*shift,*size;
  316. {
  317.   xaLONG i,j;
  318.  
  319.   i=0;
  320.   while( (i < 32) && !(mask & 0x01) ) 
  321.   {
  322.     mask >>= 1;
  323.     i++;
  324.   }
  325.   if (i >= 32)
  326.   {
  327.     fprintf(stderr,"X11_Get_Shift: wierd mask value %x\n",mask);
  328.     i = 0;
  329.   }
  330.   *shift = i;
  331.   j=0;
  332.   while( (i < 32) && (mask & 0x01) ) 
  333.   {
  334.     mask >>= 1;
  335.     i++;
  336.     j++;
  337.   }
  338.   *size = j;
  339. }
  340.  
  341. xaULONG X11_Get_True_Color(r,g,b,bits)
  342. register xaULONG r,g,b,bits;
  343. {
  344.   register xaULONG temp,temp_color;
  345.  
  346.   temp = (x11_red_bits >= bits)?(r << (x11_red_bits - bits))
  347.                                :(r >> (bits - x11_red_bits));
  348.   temp_color  = (temp << x11_red_shift) & x11_red_mask;
  349.  
  350.   temp = (x11_green_bits >= bits)?(g << (x11_green_bits - bits))
  351.                                  :(g >> (bits - x11_green_bits));
  352.   temp_color |= (temp << x11_green_shift) & x11_green_mask;
  353.  
  354.   temp = (x11_blue_bits >= bits)?(b << (x11_blue_bits - bits))
  355.                                 :(b >> (bits - x11_blue_bits));
  356.   temp_color |= (temp << x11_blue_shift) & x11_blue_mask;
  357.  
  358. /*
  359. temp = temp_color;
  360. temp_color  = ((temp >> 24) & 0xff) ;
  361. temp_color |= ((temp >> 16) & 0xff) <<  8;
  362. temp_color |= ((temp >>  8) & 0xff) << 16;
  363. temp_color |= ((temp      ) & 0xff) << 24;
  364. */
  365.   return(temp_color);
  366. }
  367.  
  368.  
  369. /****************************************************
  370.  * Initialize X11 Display, etc.
  371.  *
  372.  *
  373.  ****************/
  374. void X11_Init(argcp, argv)
  375. int *argcp;
  376. char *argv[];
  377. {
  378.   XtToolkitInitialize();
  379.   theContext = XtCreateApplicationContext();
  380.   XtAppAddActions(theContext, actionTable, ACTIONTABLE_SIZE);
  381.  
  382.   theDisp = XtOpenDisplay(theContext, NULL, "xanim", "XAnim",NULL,0,argcp,argv);
  383.   if (theDisp == NULL)
  384.   {
  385.     TheEnd1("Unable to open display\n");
  386.   }
  387.  
  388.   XSetErrorHandler(XA_Error_Handler);
  389. }
  390.  
  391. /****************************************************
  392.  *
  393.  ****************/
  394. void X11_Pre_Setup(xa_user_visual,xa_user_class)
  395. xaLONG xa_user_visual;
  396. xaLONG xa_user_class;
  397. { int i,vis_num,vis_i;
  398.   XVisualInfo *vis;
  399.  
  400.  
  401.   shm = 0;
  402. #ifdef XSHM
  403.   if ( (XShmQueryExtension(theDisp)) && (x11_shared_flag == xaTRUE)) shm = 1;
  404. #endif
  405.  
  406. /* SMR 9 */
  407. /* Use visual from window id user specified. */
  408.   if (xa_window_id != 0)
  409.   {
  410.     XWindowAttributes wAttributes;
  411.     XVisualInfo vis_template;
  412. /* catch events while preparing movie */
  413.     XSelectInput(theDisp, (Window)xa_window_id,
  414.                  StructureNotifyMask | PropertyChangeMask);
  415.     XGetWindowAttributes(theDisp, (Window)xa_window_id, &wAttributes);
  416.     vis_template.visualid = XVisualIDFromVisual(wAttributes.visual);
  417.     vis_template.screen = DefaultScreen(theDisp);
  418.     vis = XGetVisualInfo (theDisp, VisualIDMask | VisualScreenMask,
  419.                           &vis_template, &vis_num);
  420.     xa_user_visual = 0;
  421.   } /* end SMR 9 */
  422.   else if (xa_user_class >= 0) /* only attempt to use select visuals */
  423.   { XVisualInfo vis_template;
  424.     vis_template.class  = xa_user_class;
  425.     vis_template.screen = DefaultScreen(theDisp);
  426.     vis = XGetVisualInfo (theDisp, (VisualClassMask | VisualScreenMask), 
  427.                         &vis_template, &vis_num);
  428.     if ((vis == NULL) || (vis_num == 0) )
  429.     TheEnd1("X11: Couldn't get any Visuals of the desired class.");
  430.   }
  431.   else  /* look at them all (for the screen in question) */
  432.   { XVisualInfo vis_template;
  433.     vis_template.screen = DefaultScreen(theDisp);
  434.     vis = XGetVisualInfo (theDisp, VisualScreenMask, &vis_template, &vis_num);
  435.     if ((vis == NULL) || (vis_num == 0) )
  436.         TheEnd1("X11: Couldn't get any Visuals.");
  437.   }
  438.  
  439.   vis_i = xa_user_visual;
  440.   if (vis_i >= vis_num) TheEnd1("X11: Couldn't get requested Visual.");
  441.   if (vis_i < 0)
  442.   { int screen;
  443.     xaLONG max_csize,max_depth,max_class;
  444.  
  445.     max_class = -1;
  446.     max_depth = 0;
  447.     max_csize = 0;
  448.     screen = DefaultScreen(theDisp);
  449.  
  450.     /* look through visuals a choose a good one */
  451.     for(i=0;i<vis_num;i++)
  452.     { if (vis[i].screen != screen) continue; /* Visual for a diff screen */
  453.       if (vis[i].depth > max_depth)
  454.       { max_depth = vis[i].depth;
  455.     max_class = vis[i].class;
  456.     max_csize = vis[i].colormap_size;
  457.     vis_i = i;
  458.       }
  459.       else if (vis[i].depth == max_depth)
  460.       { if (vis[i].class > max_class) 
  461.     { if (   (vis[i].class < 4)    /* pseudo or less */
  462.           || (vis[i].depth > 8) )
  463.       { max_class = vis[i].class;
  464.         max_csize = vis[i].colormap_size;
  465.         vis_i = i;
  466.       }
  467.     }
  468.     else if (vis[i].class == max_class)
  469.     { if (vis[i].colormap_size > max_csize)
  470.       { max_csize = vis[i].colormap_size;
  471.         vis_i = i;
  472.       } 
  473.     } /* end same class */
  474.       } /* end same depth */
  475.     } /* end of vis loop */
  476.   } /* no valid user visuals */
  477.  
  478.   /* setup up X11 variables */
  479.  
  480.   theScreen = vis[vis_i].screen;
  481.   theVisual = vis[vis_i].visual;
  482.   x11_depth = vis[vis_i].depth;
  483.   x11_class = vis[vis_i].class;
  484.   x11_cmap_size   = vis[vis_i].colormap_size;
  485.   /* POD - For testing purposes only */
  486.   if ( (pod_max_colors > 0) && (pod_max_colors < x11_cmap_size) )
  487.         x11_cmap_size = pod_max_colors;
  488.   theGC  = DefaultGC(theDisp,theScreen);
  489.  
  490.   /* Make sure x11_cmap_size is power of two */
  491.   { xaULONG size;
  492.     size = 0x01; x11_disp_bits = 0;
  493.     while(size <= x11_cmap_size) { size <<= 1; x11_disp_bits++; }
  494.     size >>=1; x11_disp_bits--;
  495.     x11_cmap_size = 0x01 << x11_disp_bits;
  496.   }
  497.  
  498.   x11_bit_order   = BitmapBitOrder(theDisp);
  499.   if (x11_bit_order == MSBFirst) x11_bit_order = X11_MSB;
  500.   else x11_bit_order = X11_LSB;
  501.   x11_bitmap_unit = BitmapUnit(theDisp);
  502.   x11_depth_mask = (0x01 << x11_depth) - 1;
  503.   x11_cmap_type = 0;
  504.  
  505.   XFree( (void *)vis);  
  506.  
  507.   if (x11_depth == 1)
  508.   { x11_display_type = XA_MONOCHROME;
  509.     x11_bytes_pixel = 1; x11_bitmap_pad = x11_bitmap_unit; 
  510.     x11_cmap_flag = xaFALSE;
  511.     x11_black = BlackPixel(theDisp,DefaultScreen(theDisp));
  512.     x11_white = WhitePixel(theDisp,DefaultScreen(theDisp));
  513.     x11_bits_per_pixel = 1;
  514.     x11_byte_order = x11_bit_order;
  515.   }
  516.   else 
  517.   { if (x11_depth > 16)
  518.         { x11_bytes_pixel = 4; x11_bitmap_pad = 32; }
  519.     else if (x11_depth > 8)
  520.         { x11_bytes_pixel = 2; x11_bitmap_pad = 16; }
  521.     else { x11_bytes_pixel = 1; x11_bitmap_pad = 8; }
  522.  
  523.     theImage = XCreateImage(theDisp,theVisual,
  524.             x11_depth,ZPixmap,0,0,7,7,
  525.             x11_bitmap_pad,0);
  526.     if (theImage != 0)
  527.     { x11_bits_per_pixel = theImage->bits_per_pixel;
  528.       x11_byte_order = theImage->byte_order;
  529.       if (x11_byte_order == MSBFirst) x11_byte_order = X11_MSB;
  530.       else x11_byte_order = X11_LSB;
  531.       if (x11_verbose_flag == xaTRUE)
  532.       { fprintf(stderr,"bpp=%d   bpl=%d   byteo=%d  bito=%d\n",
  533.         x11_bits_per_pixel,theImage->bytes_per_line,
  534.         x11_byte_order,theImage->bitmap_bit_order);
  535.       }
  536.       XDestroyImage(theImage); theImage = NULL;
  537.     } else x11_bits_per_pixel = x11_depth;
  538.  
  539.     switch(x11_class)
  540.     { case StaticGray:
  541.     x11_display_type = XA_STATICGRAY;
  542.     x11_cmap_flag = xaFALSE;
  543.     break;
  544.       case GrayScale:
  545.     x11_display_type = XA_GRAYSCALE;
  546.     x11_cmap_flag = xaTRUE;
  547.     break;
  548.       case StaticColor:
  549.     x11_display_type = XA_STATICCOLOR;
  550.     x11_cmap_flag = xaFALSE;
  551.     break;
  552.       case PseudoColor:
  553.     x11_display_type = XA_PSEUDOCOLOR;
  554.     x11_cmap_flag = xaTRUE;
  555.     break;
  556.       case TrueColor:
  557.     x11_display_type = XA_TRUECOLOR;
  558.     x11_cmap_flag = xaFALSE;
  559.     break;
  560.       case DirectColor:
  561.     x11_display_type = XA_DIRECTCOLOR;
  562.     x11_cmap_flag = xaFALSE;
  563.     break;
  564.       default:
  565.     fprintf(stderr,"Unkown x11_class %x\n",x11_class);
  566.     TheEnd();
  567.     }
  568.   }
  569.  
  570.   if (x11_display_type & XA_X11_TRUE)
  571.   {
  572.     x11_red_mask = theVisual->red_mask;
  573.     x11_green_mask = theVisual->green_mask;
  574.     x11_blue_mask = theVisual->blue_mask;
  575.     X11_Get_Shift(x11_red_mask  , &x11_red_shift  , &x11_red_bits  );
  576.     X11_Get_Shift(x11_green_mask, &x11_green_shift, &x11_green_bits);
  577.     X11_Get_Shift(x11_blue_mask , &x11_blue_shift , &x11_blue_bits );
  578.   }
  579.   else if ( (x11_depth == 24) && (x11_cmap_size <= 256) ) x11_cmap_type = 1;
  580.  
  581.   xa_cmap = (ColorReg *) malloc( x11_cmap_size * sizeof(ColorReg) );
  582.   if (xa_cmap==0) fprintf(stderr,"X11 CMAP: couldn't malloc\n");
  583.  
  584.   if (x11_verbose_flag == xaTRUE)
  585.   {
  586.     fprintf(stderr,"Selected Visual:  ");
  587.     X11_OutPut_Visual_Class(x11_class);
  588.     fprintf(stderr," (%x) \n",x11_display_type);
  589.     fprintf(stderr,"  depth= %d  class= %d  cmap size=%d(%d) bytes_pixel=%d\n",
  590.         x11_depth, x11_class, x11_cmap_size, x11_disp_bits, x11_bytes_pixel );
  591.     if (x11_display_type & XA_X11_TRUE)
  592.     {
  593.       fprintf(stderr,"  X11 Color Masks =%x %x %x\n",
  594.                   x11_red_mask,x11_green_mask ,x11_blue_mask);
  595.       fprintf(stderr,"  X11 Color Shifts=%d %d %d\n",
  596.                   x11_red_shift, x11_green_shift, x11_blue_shift );
  597.       fprintf(stderr,"  X11 Color Sizes =%d %d %d\n",
  598.                   x11_red_bits,x11_green_bits ,x11_blue_bits);
  599.     }
  600.     else if (x11_display_type == XA_MONOCHROME)
  601.     { fprintf(stderr,"  Bit Order = %x  bitmapunit = %x bitmappad = %x\n",
  602.                 x11_bit_order,x11_bitmap_unit,BitmapPad(theDisp) );
  603.     }
  604.     fprintf(stderr,"\n");
  605.   }
  606.  
  607.   if (   (theVisual != DefaultVisual(theDisp,theScreen))
  608.       || (x11_display_type & XA_X11_TRUE)
  609.       || (x11_display_type == XA_MONOCHROME) ) xa_allow_nice = xaFALSE;
  610.   else xa_allow_nice = xaTRUE;
  611.  
  612.   /* kludges */
  613.   if (   (!(x11_display_type & XA_X11_TRUE))
  614.       && (x11_depth == 24) && (x11_cmap_size <= 256) ) x11_kludge_1 = xaTRUE;
  615.   XSync(theDisp,False);
  616. }
  617.  
  618. /*
  619.  * Setup X11 Display, Window and Toolkit
  620.  */
  621.  
  622. void X11_Setup_Window(max_imagex,max_imagey,startx,starty)
  623. xaLONG max_imagex,max_imagey;
  624. xaLONG startx,starty;
  625. { xaLONG n;
  626.   Arg arglist[20];
  627.   XWMHints xwm_hints;
  628.  
  629. /* SMR 10 */
  630. /* Use cmap from window id user specified. */
  631.   if (xa_window_id != 0)
  632.   {
  633.      XWindowAttributes wAttributes;
  634.  
  635.      XGetWindowAttributes(theDisp, (Window)xa_window_id, &wAttributes);
  636.      theCmap = wAttributes.colormap;
  637.   }
  638. /* end SMR 10 */
  639.   else if (   (   (theVisual == DefaultVisual(theDisp,theScreen))
  640.           && !(   (cmap_play_nice == xaFALSE) 
  641.                && (x11_display_type & XA_X11_CMAP)
  642.               )
  643.          ) 
  644.       || (x11_display_type == XA_MONOCHROME)
  645.      )
  646.   { DEBUG_LEVEL1 fprintf(stderr,"using default cmap\n");
  647.     theCmap = DefaultColormap(theDisp,theScreen);
  648.     x11_cmap_flag = xaFALSE; /* if nice */
  649.   }
  650.   else
  651.   { DEBUG_LEVEL1 fprintf(stderr,"creating new cmap\n");
  652.     if (x11_display_type & XA_X11_STATIC)
  653.     { theCmap = XCreateColormap(theDisp,RootWindow(theDisp,theScreen),
  654.                             theVisual, AllocNone);
  655.     }
  656.     else if (   (x11_display_type == XA_DIRECTCOLOR)
  657.              && (theVisual != DefaultVisual(theDisp,theScreen))  )
  658.     {     /* Fake Direct Color, usually on top of a PseudoColor */
  659.       xaULONG i,r_scale,g_scale,b_scale;
  660.       xaULONG rmsk,gmsk,bmsk;
  661.  
  662.  
  663.       theCmap = XCreateColormap(theDisp,RootWindow(theDisp,theScreen),
  664.                             theVisual, AllocAll);
  665.       r_scale = cmap_scale[x11_red_bits];
  666.       g_scale = cmap_scale[x11_green_bits];
  667.       b_scale = cmap_scale[x11_blue_bits];
  668.       rmsk = (0x01 << x11_red_bits)   - 1;
  669.       gmsk = (0x01 << x11_green_bits) - 1;
  670.       bmsk = (0x01 << x11_blue_bits)  - 1;
  671.       for(i=0; i < x11_cmap_size; i++)
  672.       {
  673.         defs[i].pixel  =  (i << x11_red_shift)   & x11_red_mask;
  674.         defs[i].pixel |=  (i << x11_green_shift) & x11_green_mask;
  675.         defs[i].pixel |=  (i << x11_blue_shift)  & x11_blue_mask;
  676.         defs[i].red   = (i & rmsk) * r_scale;
  677.         defs[i].green = (i & gmsk) * g_scale;
  678.         defs[i].blue  = (i & bmsk) * b_scale;
  679.         defs[i].flags = DoRed | DoGreen | DoBlue;
  680.       }
  681.       XStoreColors(theDisp,theCmap,defs,x11_cmap_size);
  682.     }
  683.     else   /* re-instate here */
  684.     {  xaULONG i,csize;
  685.        theCmap = XCreateColormap(theDisp,RootWindow(theDisp,theScreen),
  686.                             theVisual, AllocAll);
  687.        if (theCmap == 0) TheEnd1("X11_Setup_Window: create cmap err");
  688.  
  689.        csize = CellsOfScreen(DefaultScreenOfDisplay(theDisp));
  690.        if (csize > x11_cmap_size) csize = x11_cmap_size;
  691.        for(i=0;i<csize;i++)
  692.        { if (x11_display_type & XA_X11_TRUE)
  693.          { xaULONG d;
  694.            d  =  (i << x11_red_shift)   & x11_red_mask;
  695.            d |=  (i << x11_green_shift) & x11_green_mask;
  696.            d |=  (i << x11_blue_shift)  & x11_blue_mask;
  697.            defs[i].pixel =  d;
  698.          } else defs[i].pixel = i;
  699.          defs[i].flags = DoRed | DoGreen | DoBlue; 
  700.        }
  701.        XQueryColors(theDisp,DefaultColormap(theDisp,theScreen),defs,csize);
  702.        for(i=0;i<csize;i++)
  703.        { xaULONG r,g,b;
  704.          r = xa_cmap[i].red   = defs[i].red;
  705.          g = xa_cmap[i].green = defs[i].green;
  706.          b = xa_cmap[i].blue  = defs[i].blue;
  707.          xa_cmap[i].gray = (xaUSHORT)( ( (r * 11) + (g * 16) + (b * 5) ) >> 5 );
  708.          if (x11_display_type & XA_X11_GRAY)
  709.          { defs[i].red   = xa_cmap[i].gray;
  710.            defs[i].green = xa_cmap[i].gray;
  711.            defs[i].blue  = xa_cmap[i].gray;
  712.          }
  713.          defs[i].pixel = i; /* probably redundant */
  714.          defs[i].flags = DoRed | DoGreen | DoBlue;
  715.       }
  716.       XStoreColors(theDisp,theCmap,defs,csize);
  717.     }
  718.   }
  719.  
  720.   n = 0;
  721. #ifdef XtNvisual
  722.   XtSetArg(arglist[n], XtNvisual, theVisual); n++;
  723. #endif
  724.   XtSetArg(arglist[n], XtNcolormap, theCmap); n++;
  725.   XtSetArg(arglist[n], XtNdepth, x11_depth); n++;
  726.   XtSetArg(arglist[n], XtNforeground, WhitePixel(theDisp,theScreen)); n++;
  727.   XtSetArg(arglist[n], XtNbackground, BlackPixel(theDisp,theScreen)); n++;
  728.   XtSetArg(arglist[n], XtNborderColor, WhitePixel(theDisp,theScreen)); n++;
  729.   XtSetArg(arglist[n], XtNwidth, startx); n++;
  730.   XtSetArg(arglist[n], XtNheight, starty); n++;
  731.   XtSetArg(arglist[n], XtNx, XA_MAINW_XPOS); n++;
  732.   XtSetArg(arglist[n], XtNy, XA_MAINW_YPOS); n++;
  733.   if (xa_allow_resizing==xaTRUE)
  734.   {
  735.     XtSetArg(arglist[n], XtNallowShellResize, True); n++;
  736.   }
  737.   else
  738.   {
  739.     XtSetArg(arglist[n], XtNmaxWidth, max_imagex); n++;
  740.     XtSetArg(arglist[n], XtNmaxHeight, max_imagey); n++;
  741.   }
  742.   XtSetArg(arglist[n], XtNtranslations, 
  743.             XtParseTranslationTable(Translation)); n++;
  744.   theWG = XtAppCreateShell("xanim", "XAnim", applicationShellWidgetClass, 
  745.                          theDisp, arglist, n);
  746.  
  747. /* SMR 11 */
  748. /* Fake mainW to be user specified window instead of widget window.
  749.    Note that shell window is never realized. */
  750.   if (xa_window_id != 0)
  751.   {
  752.     mainW = (Window)xa_window_id;
  753.   }
  754.   else
  755.   {
  756.     XtGetApplicationResources (theWG, &xa_resources, application_resources,
  757.                                XtNumber(application_resources), NULL, 0);
  758.  
  759.     XtRealizeWidget(theWG);
  760.     mainW = XtWindow(theWG);
  761.   }
  762. /* end SMR 11 */
  763.  
  764. #ifdef XMBUF
  765.   mainWreal = mainW;
  766.   if (mbuf) {
  767.     DEBUG_LEVEL1 fprintf(stderr, "Creating multiple buffers\n");
  768.     if (XmbufCreateBuffers(theDisp, mainW, 2,
  769.       MultibufferUpdateActionBackground, MultibufferUpdateHintFrequent,
  770.       mainWbuffers) < 2) {
  771.       fprintf(stderr,"X11 Setup: creating multiple buffers failed\n");
  772.       mbuf = 0;
  773.     } else
  774.       mainW = mainWbuffers[mainWbufIndex = 0];
  775.   }
  776. #endif
  777.  
  778.  
  779.   /* Need to Create New GC for Visuals that have a different depth than
  780.    * the default GC
  781.    */
  782.   {
  783.     xaULONG gc_mask;
  784.     XGCValues gc_init;
  785.  
  786.     gc_mask = 0;
  787.     gc_init.function = GXcopy;                          gc_mask |= GCFunction;
  788.     gc_init.foreground = WhitePixel(theDisp,theScreen); gc_mask |= GCForeground;
  789.     gc_init.background = BlackPixel(theDisp,theScreen); gc_mask |= GCBackground;
  790.     gc_init.graphics_exposures = False;         gc_mask |= GCGraphicsExposures;
  791.     theGC  = XCreateGC(theDisp,mainW,gc_mask,&gc_init);
  792.  
  793. XSetFunction(theDisp, theGC, GXcopy);
  794. XSetPlaneMask(theDisp, theGC, ~0L);
  795.  
  796.   }
  797.  
  798.  
  799.   if (x11_display_type == XA_MONOCHROME)
  800.   { xaULONG line_size;
  801.     line_size = X11_Get_Line_Size(max_imagex);
  802.     theImage = XCreateImage(theDisp,theVisual,
  803.             x11_depth,XYPixmap,0,0,max_imagex,max_imagey,
  804.             x11_bitmap_pad,line_size);
  805.     if (theImage == 0)
  806.     {
  807.       fprintf(stderr,"X11 Setup: create XY image failed\n");
  808.       TheEnd();
  809.     }
  810.   }
  811.   else
  812.   { xaULONG line_size;
  813.     line_size = X11_Get_Line_Size(x11_bytes_pixel * max_imagex);
  814.     if (x11_bits_per_pixel==2) line_size = (line_size + 3) / 4;
  815.     else if (x11_bits_per_pixel==4) line_size = (line_size + 1) / 2;
  816.  
  817.     theImage = XCreateImage(theDisp,theVisual,
  818.             x11_depth,ZPixmap,0,0,max_imagex,max_imagey,
  819.             x11_bitmap_pad,line_size);
  820.     if (theImage == 0)
  821.     {
  822.       fprintf(stderr,"X11 Setup: create Z image failed\n");
  823.       TheEnd();
  824.     }
  825.   }
  826.  
  827.   xwm_hints.input = True;    /* ask for keyboard input */
  828. /*xwm_hints.icon_pixmap = ???;      Eventually have a icon pixmap */
  829.   xwm_hints.flags = InputHint;   /* IconPixmapHint */
  830.   XSetWMHints(theDisp,mainW,&xwm_hints);
  831.   XSync(theDisp,False);
  832. }
  833.  
  834. void X11_Map_Window()
  835. {
  836.   XMapWindow(theDisp,mainW);
  837.   XSync(theDisp,False);
  838.  
  839.   if (x11_cmap_flag == xaFALSE) /* static or monochrome displays */
  840.   {
  841.     xaULONG i;
  842.     for(i=0;i<x11_cmap_size;i++)
  843.     { 
  844.       if (x11_display_type & XA_X11_TRUE)
  845.       {
  846.         xaULONG d;
  847.         d  =  (i << x11_red_shift)   & x11_red_mask;
  848.         d |=  (i << x11_green_shift) & x11_green_mask;
  849.         d |=  (i << x11_blue_shift)  & x11_blue_mask;
  850.         defs[i].pixel =  d;
  851.       }
  852.       else defs[i].pixel = i;
  853.       defs[i].flags = DoRed | DoGreen | DoBlue; 
  854.     }
  855.     XQueryColors(theDisp,theCmap,defs,x11_cmap_size);
  856.     for(i=0;i<x11_cmap_size;i++)
  857.     {
  858.       xaULONG r,g,b;
  859.       r = xa_cmap[i].red   = defs[i].red;
  860.       g = xa_cmap[i].green = defs[i].green;
  861.       b = xa_cmap[i].blue  = defs[i].blue;
  862.       xa_cmap[i].gray = (xaUSHORT)( ( (r * 11) + (g * 16) + (b * 5) ) >> 5 );
  863.     }
  864.   }
  865. /* Copy Default Colormap into new one */
  866.   else  if (!(x11_display_type & XA_X11_TRUE))
  867.   {
  868.     xaULONG i,csize;
  869.  
  870.     csize = CellsOfScreen(DefaultScreenOfDisplay(theDisp));
  871.     if (csize > x11_cmap_size) csize = x11_cmap_size;
  872.     for(i=0; i<csize; i++)
  873.     {   /* POD eventually removed this when it's determined to be fixed */
  874.       if (x11_display_type & XA_X11_TRUE)
  875.       { xaULONG d;
  876.         d  =  (i << x11_red_shift)   & x11_red_mask;
  877.         d |=  (i << x11_green_shift) & x11_green_mask;
  878.         d |=  (i << x11_blue_shift)  & x11_blue_mask;
  879.         defs[i].pixel =  d;
  880.       }
  881.       else defs[i].pixel = i;
  882.       defs[i].flags = DoRed | DoGreen | DoBlue;
  883.     }
  884.     XQueryColors(theDisp,theCmap,defs,csize);
  885.     for(i=0; i<csize; i++)
  886.     { xaULONG r,g,b;
  887.       r = xa_cmap[i].red   = defs[i].red;
  888.       g = xa_cmap[i].green = defs[i].green;
  889.       b = xa_cmap[i].blue  = defs[i].blue;
  890.       xa_cmap[i].gray = (xaUSHORT)( ( (r * 11) + (g * 16) + (b * 5) ) >> 5 );
  891.       if (x11_display_type & XA_X11_GRAY)
  892.       { defs[i].red   = xa_cmap[i].gray;
  893.         defs[i].green = xa_cmap[i].gray;
  894.         defs[i].blue  = xa_cmap[i].gray;
  895.       }
  896.       defs[i].pixel = i; /* probably redundant */
  897.       defs[i].flags = DoRed | DoGreen | DoBlue;
  898.     }
  899.     XStoreColors(theDisp,theCmap,defs,csize);
  900.   }
  901.   XSetWindowColormap(theDisp, mainW, theCmap);
  902.  
  903.   XInstallColormap(theDisp,theCmap);
  904.   XSync(theDisp,False);
  905. /*
  906. #ifndef NO_INSTALL_CMAP
  907.   XInstallColormap(theDisp,theCmap);
  908. #endif
  909.   XSync(theDisp,False);
  910. */
  911.  
  912. }
  913.  
  914. void xanim_resize(wg, event, str, np)
  915. Widget        wg;
  916. XConfigureEvent    *event;
  917. String        *str;
  918. int        *np;
  919. {
  920.   if (xa_anim_status == XA_UNSTARTED)  return;
  921. #ifdef XMBUF
  922.   if (event->window == mainWreal)
  923. #else
  924.   if (event->window == mainW)
  925. #endif
  926.   {
  927.     x11_window_x = event->width;
  928.     x11_window_y = event->height;
  929.     DEBUG_LEVEL1 
  930.     fprintf(stderr,"X11 RESIZE %dx%d\n",x11_window_x,x11_window_y);
  931.   }
  932. }
  933.  
  934.  
  935. static void xanim_realize_remote(wg, event, str, np)
  936. Widget          wg;
  937. XExposeEvent   *event;
  938. String         *str;
  939. int            *np;
  940. {
  941.   if (xa_remote_ready != xaTRUE) return;
  942.   if (xa_remote_busy == xaTRUE) return;
  943. #ifdef XA_REMOTE_CONTROL
  944.   if (xa_remote_realized == xaFALSE)
  945.   {
  946.     xa_remote_busy = xaTRUE;
  947.     XA_Realize_Remote(remote_widget);
  948.     xa_remote_busy = xaFALSE;
  949.   }
  950.   else
  951.   {
  952.     xa_remote_busy = xaTRUE;
  953.     XA_Unrealize_Remote(remote_widget);
  954.     xa_remote_busy = xaFALSE;
  955.   }
  956. #endif
  957. }
  958.  
  959.  
  960.  
  961. void xanim_expose(wg, event, str, np)
  962. Widget        wg;
  963. XExposeEvent    *event;
  964. String        *str;
  965. int        *np;
  966. {
  967.  x11_expose_flag = xaTRUE;
  968.  if (xa_anim_status == XA_UNSTARTED) 
  969.  {
  970.   xa_anim_status = XA_BEGINNING;
  971.   xa_anim_holdoff = xaTRUE;
  972.   XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped,
  973.                         (XtPointer)(XA_SHOW_NORM));
  974.  }
  975. }
  976.  
  977. /*    -       -       -       -       -       -       -       -       */
  978. /*
  979.  * gf: Broke xanim_button() and xanim_key() into more specific action
  980.  *     procedures.
  981.  */
  982. #define ACTION_PROC(NAME)     static void NAME(w,event,params,num_params) \
  983.                                       Widget w; \
  984.                                       XEvent *event; \
  985.                                       String *params; \
  986.                                       Cardinal *num_params;
  987.  
  988. ACTION_PROC(xanim_step_prev_action)
  989. { if (xa_anim_status & XA_STOP_MASK) /* if stopped */
  990.   { xa_anim_status = XA_STEP_PREV;
  991.     if (xa_anim_holdoff == xaTRUE) return;
  992.     xa_anim_holdoff = xaTRUE;
  993.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  994.                         (XtPointer)XA_SHOW_NORM);
  995.   }
  996.   else xa_anim_status = XA_STOP_PREV;
  997. #ifdef XA_REMOTE_CONTROL
  998.   XA_Remote_StepPrev();
  999. #endif
  1000. }
  1001.  
  1002. ACTION_PROC(xanim_step_next_action)
  1003. { if (xa_anim_status & XA_STOP_MASK) /* if stopped */
  1004.   { xa_anim_status = XA_STEP_NEXT;
  1005.     if (xa_anim_holdoff == xaTRUE) return;
  1006.     xa_anim_holdoff = xaTRUE;
  1007.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  1008.                         (XtPointer)XA_SHOW_NORM);
  1009.   }
  1010.   else xa_anim_status = XA_STOP_NEXT;
  1011. #ifdef XA_REMOTE_CONTROL
  1012.   XA_Remote_StepNext();
  1013. #endif
  1014. }
  1015.  
  1016. ACTION_PROC(xanim_toggle_action)
  1017. { int button; /* <0 PlayNext> <1 PlayPrev> <2 PlayStop> */
  1018.   switch(xa_anim_status)
  1019.   {
  1020.     case XA_RUN_PREV:  /* if running, then stop */
  1021.     case XA_RUN_NEXT:
  1022.       button = 2;
  1023.       xa_anim_status &= XA_CLEAR_MASK;
  1024.       xa_anim_status |= XA_STOP_MASK;
  1025.       xa_anim_flags &= ~(ANIM_CYCLE);
  1026.       break;
  1027.     case XA_STOP_PREV: /* if stopped, then run */
  1028.     case XA_STOP_NEXT:
  1029.       button = (xa_anim_status & XA_NEXT_MASK)?(0):(1);
  1030.       xa_anim_status &= XA_CLEAR_MASK;
  1031.       xa_anim_status |= XA_RUN_MASK;
  1032.       if (xa_anim_holdoff == xaTRUE) return;
  1033.       xa_anim_holdoff = xaTRUE;
  1034.       XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  1035.                         (XtPointer)XA_SHOW_NORM);
  1036.       break;
  1037.     case XA_STEP_PREV: /* if single stepping then run */
  1038.     case XA_STEP_NEXT:
  1039.     case XA_ISTP_PREV:
  1040.     case XA_ISTP_NEXT:
  1041.     case XA_FILE_PREV:
  1042.     case XA_FILE_NEXT:
  1043.       button = (xa_anim_status & XA_NEXT_MASK)?(0):(1);
  1044.       xa_anim_status &= XA_CLEAR_MASK;
  1045.       xa_anim_status |= XA_RUN_MASK;
  1046.       break;
  1047.     default:
  1048.       button = 2;
  1049.       if (xa_anim_status & XA_NEXT_MASK) xa_anim_status = XA_STOP_NEXT;
  1050.       else                 xa_anim_status = XA_STOP_PREV;
  1051.       break;
  1052.   }
  1053.   /* change Play Widget pixmap */
  1054. #ifdef XA_REMOTE_CONTROL
  1055.   if (button==0)    XA_Remote_PlayNext();
  1056.   else if (button==1)    XA_Remote_PlayPrev();
  1057.   else            XA_Remote_PlayStop();
  1058. #endif
  1059.   if ( (xa_title_flag == XA_TITLE_FILE) && (xa_anim_status & XA_RUN_MASK))
  1060.                 XA_Store_Title(cur_file,0,xa_title_flag);
  1061. }
  1062.  
  1063. ACTION_PROC(xact_playnext)
  1064. { if ((xa_anim_status == XA_STOP_PREV) || (xa_anim_status == XA_STOP_NEXT))
  1065.   { if (xa_anim_holdoff == xaTRUE) return;
  1066.     xa_anim_holdoff = xaTRUE;
  1067.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped,
  1068.                             (XtPointer)XA_SHOW_NORM);
  1069.   }
  1070.   xa_anim_status = XA_RUN_NEXT;
  1071. #ifdef XA_REMOTE_CONTROL
  1072.   XA_Remote_PlayNext();
  1073. #endif
  1074.   if (xa_title_flag == XA_TITLE_FILE) XA_Store_Title(cur_file,0,xa_title_flag);
  1075. }
  1076.  
  1077. ACTION_PROC(xact_playprev)
  1078. { if ((xa_anim_status == XA_STOP_PREV) || (xa_anim_status == XA_STOP_NEXT))
  1079.   { if (xa_anim_holdoff == xaTRUE) return;
  1080.     xa_anim_holdoff = xaTRUE;
  1081.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped,
  1082.                             (XtPointer)XA_SHOW_NORM);
  1083.   }
  1084.   xa_anim_status = XA_RUN_PREV;
  1085. #ifdef XA_REMOTE_CONTROL
  1086.   XA_Remote_PlayPrev();
  1087. #endif
  1088.   if (xa_title_flag == XA_TITLE_FILE) XA_Store_Title(cur_file,0,xa_title_flag);
  1089. }
  1090.  
  1091. ACTION_PROC(xact_playstop)
  1092. { xa_anim_status = (xa_anim_status & XA_NEXT_MASK)?(XA_STOP_NEXT)
  1093.                           :(XA_STOP_PREV); 
  1094.   xa_anim_flags &= ~(ANIM_CYCLE);
  1095. #ifdef XA_REMOTE_CONTROL
  1096.   XA_Remote_PlayStop();
  1097. #endif
  1098. }
  1099.  
  1100. ACTION_PROC(xanim_quit_action)
  1101. {
  1102.   TheEnd();
  1103. }
  1104.  
  1105. ACTION_PROC(xanim_resize_action)
  1106. {
  1107.   if ( (xa_buff_x != 0) && (xa_buff_y != 0) )
  1108.     XResizeWindow(theDisp,mainW,xa_buff_x,xa_buff_y);
  1109. }
  1110.  
  1111. ACTION_PROC(xanim_install_cmap_action)
  1112. {
  1113.   XInstallColormap(theDisp,theCmap);
  1114. }
  1115.  
  1116. ACTION_PROC(xanim_stop_cmap_action)
  1117. {
  1118.   xa_anim_flags &= ~(ANIM_CYCLE);
  1119. }
  1120.  
  1121. ACTION_PROC(xanim_restore_cmap_action)
  1122. {
  1123.   if (xa_chdr_now != 0) XA_Install_CMAP(xa_chdr_now);
  1124. }
  1125.  
  1126. /* decrease speed scale, but not to zero */
  1127. ACTION_PROC(xanim_slower_action)
  1128. {
  1129. #ifdef XA_REMOTE_CONTROL
  1130.   if (xa_speed_scale==XA_SPEED_NORM) XA_Remote_SpeedNorm();
  1131. #endif
  1132.   xa_speed_change = 1;
  1133.   if (xa_speed_scale > XA_SPEED_MIN) xa_speed_scale >>= 1;
  1134.   xa_speed_change = 2;
  1135. #ifdef XA_REMOTE_CONTROL
  1136.   if (xa_speed_scale==XA_SPEED_NORM) XA_Remote_SpeedDiff();
  1137. #endif
  1138. }
  1139.  
  1140. /* increase speed scale, but not more than 1000 */
  1141. ACTION_PROC(xanim_faster_action)
  1142. #ifdef XA_REMOTE_CONTROL
  1143.   if (xa_speed_scale==XA_SPEED_NORM) XA_Remote_SpeedNorm();
  1144. #endif
  1145.   xa_speed_change = 1;
  1146.   if (xa_speed_scale < XA_SPEED_MAX) xa_speed_scale <<= 1;
  1147.   xa_speed_change = 2;
  1148. #ifdef XA_REMOTE_CONTROL
  1149.   if (xa_speed_scale==XA_SPEED_NORM) XA_Remote_SpeedDiff();
  1150. #endif
  1151. }
  1152.  
  1153. /* increase speed scale, but not more than 1000 */
  1154. ACTION_PROC(xanim_set_pingpong)
  1155.   xa_pingpong_flag = (xa_pingpong_flag == xaTRUE)?(xaFALSE):(xaTRUE);
  1156. }
  1157.  
  1158.  
  1159. /*******************************
  1160.  * set speed to that at startup
  1161.  *******************************/
  1162. ACTION_PROC(xanim_speed_reset_action)
  1163. {
  1164. #ifdef XA_REMOTE_CONTROL
  1165.   if (xa_speed_scale != XA_SPEED_NORM) XA_Remote_SpeedDiff();
  1166. #endif
  1167.   xa_speed_change = 1;
  1168.   xa_speed_scale = XA_SPEED_NORM;
  1169.   xa_speed_change = 2;
  1170. }
  1171.  
  1172. /*******************************
  1173.  * single step across anims
  1174.  *******************************/
  1175. ACTION_PROC(xanim_next_anim_action)
  1176. { if (xa_anim_status & XA_STOP_MASK) /* if stopped */
  1177.   { xa_anim_status = XA_FILE_NEXT;
  1178.     if (xa_anim_holdoff == xaTRUE) return;
  1179.     xa_anim_holdoff = xaTRUE;
  1180.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  1181.                         (XtPointer)XA_SHOW_NORM);
  1182.   }
  1183.   else xa_anim_status = XA_FILE_NEXT;
  1184. #ifdef XA_REMOTE_CONTROL
  1185.   XA_Remote_StepNext();
  1186. #endif
  1187. }
  1188.  
  1189. /*******************************
  1190.  * single step across anims
  1191.  *******************************/
  1192. ACTION_PROC(xanim_prev_anim_action)
  1193. { if (xa_anim_status & XA_STOP_MASK) /* if stopped */
  1194.   { xa_anim_status = XA_FILE_PREV;
  1195.     if (xa_anim_holdoff == xaTRUE) return;
  1196.     xa_anim_holdoff = xaTRUE;
  1197.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  1198.                         (XtPointer)XA_SHOW_NORM);
  1199.   }
  1200.   else xa_anim_status = XA_FILE_PREV;
  1201. #ifdef XA_REMOTE_CONTROL
  1202.   XA_Remote_StepPrev();
  1203. #endif
  1204. }
  1205.  
  1206. /*******************************
  1207.  * single step within anim 
  1208.  *******************************/
  1209. ACTION_PROC(xanim_step_next_int_action)
  1210. { if (xa_anim_status & XA_STOP_MASK) /* if stopped */
  1211.   { xa_anim_status = XA_ISTP_NEXT;
  1212.     if (xa_anim_holdoff == xaTRUE) return;
  1213.     xa_anim_holdoff = xaTRUE;
  1214.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  1215.                         (XtPointer)XA_SHOW_NORM);
  1216.   }
  1217.   else xa_anim_status = XA_STOP_NEXT;
  1218. #ifdef XA_REMOTE_CONTROL
  1219.   XA_Remote_StepNext();
  1220. #endif
  1221. }
  1222.  
  1223. /*******************************
  1224.  * single step within anim 
  1225.  *******************************/
  1226. ACTION_PROC(xanim_step_prev_int_action)
  1227. { if (xa_anim_status & XA_STOP_MASK) /* if stopped */
  1228.   { xa_anim_status = XA_ISTP_PREV;
  1229.     if (xa_anim_holdoff == xaTRUE) return;
  1230.     xa_anim_holdoff = xaTRUE;
  1231.     XtAppAddTimeOut(theContext, 1, (XtTimerCallbackProc)XAnim_Looped, 
  1232.                         (XtPointer)XA_SHOW_NORM);
  1233.   }
  1234.   else xa_anim_status = XA_STOP_PREV;
  1235. #ifdef XA_REMOTE_CONTROL
  1236.   XA_Remote_StepPrev();
  1237. #endif
  1238. }
  1239.  
  1240. /*******************************
  1241.  * decrement xa_audio_volume by 5
  1242.  *******************************/
  1243. ACTION_PROC(xanim_dec_audio_5)
  1244. { vaudiof->volume -= 5; if (vaudiof->volume < 0) vaudiof->volume = 0;
  1245.   vaudiof->newvol = xaTRUE;
  1246.   XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1247. #ifdef XA_REMOTE_CONTROL
  1248.   XA_Remote_Adj_Volume(vaudiof->volume,XA_AUDIO_MAXVOL);
  1249. #endif
  1250. }
  1251.  
  1252. /*******************************
  1253.  * decrement xa_audio_volume by 1 
  1254.  *******************************/
  1255. ACTION_PROC(xanim_dec_audio_1)
  1256. { vaudiof->volume -= 1; if (vaudiof->volume < 0) vaudiof->volume = 0;
  1257.   vaudiof->newvol = xaTRUE;
  1258.   XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1259. #ifdef XA_REMOTE_CONTROL
  1260.   XA_Remote_Adj_Volume(vaudiof->volume,XA_AUDIO_MAXVOL);
  1261. #endif
  1262. }
  1263.  
  1264. /*******************************
  1265.  * increment xa_audio_volume by 5 
  1266.  *******************************/
  1267. ACTION_PROC(xanim_inc_audio_5)
  1268. { vaudiof->volume += 5;
  1269.   if (vaudiof->volume > XA_AUDIO_MAXVOL) vaudiof->volume = XA_AUDIO_MAXVOL;
  1270.   vaudiof->newvol = xaTRUE;
  1271.   XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1272. #ifdef XA_REMOTE_CONTROL
  1273.   XA_Remote_Adj_Volume(vaudiof->volume,XA_AUDIO_MAXVOL);
  1274. #endif
  1275. }
  1276.  
  1277. /*******************************
  1278.  * increment xa_audio_volume by 1
  1279.  *******************************/
  1280. ACTION_PROC(xanim_inc_audio_1)
  1281. { vaudiof->volume += 1;
  1282.   if (vaudiof->volume > XA_AUDIO_MAXVOL) vaudiof->volume = XA_AUDIO_MAXVOL;
  1283.   vaudiof->newvol = xaTRUE;
  1284.   XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1285. #ifdef XA_REMOTE_CONTROL
  1286.   XA_Remote_Adj_Volume(vaudiof->volume,XA_AUDIO_MAXVOL);
  1287. #endif
  1288. }
  1289.  
  1290. /*******************************
  1291.  * mute audio 
  1292.  *******************************/
  1293. ACTION_PROC(xanim_mute_audio)
  1294. { vaudiof->mute = (vaudiof->mute==xaTRUE)?(xaFALSE):(xaTRUE);
  1295.   vaudiof->newvol = xaTRUE;
  1296.   XA_AUDIO_SET_MUTE(vaudiof->mute);
  1297. #ifdef XA_REMOTE_CONTROL
  1298.   if (vaudiof->mute==xaTRUE)    XA_Remote_AudioOn();
  1299.   else                XA_Remote_AudioOff();
  1300. #endif
  1301. }
  1302.  
  1303. /*******************************
  1304.  * toggle speaker 
  1305.  *******************************/
  1306. ACTION_PROC(xanim_speaker_tog)
  1307. {
  1308.   XA_SPEAKER_TOG(2);
  1309. }
  1310.  
  1311. /*******************************
  1312.  * toggle headphone 
  1313.  *******************************/
  1314. ACTION_PROC(xanim_headphone_tog)
  1315. {
  1316.   XA_HEADPHONE_TOG(2);
  1317. }
  1318.  
  1319.  
  1320. /*******************************
  1321.  * Would you believe the main loop?
  1322.  *******************************/
  1323. void xanim_events()
  1324. {
  1325. /* SMR 12 */
  1326. /* If external window has been supplied, watch the properties on that
  1327.    window to determine what action to take. */
  1328.   if (xa_window_id == 0)    XtAppMainLoop(theContext);
  1329.   else
  1330.   {
  1331.     XEvent event;
  1332.     char *command = "";
  1333.     XDestroyWindowEvent *devent = (XDestroyWindowEvent *)&event;
  1334.     XConfigureEvent *cevent = (XConfigureEvent *)&event;
  1335.     XPropertyEvent *pevent = (XPropertyEvent *)&event;
  1336.     xaULONG window_atom = XInternAtom(theDisp, xa_window_propname, False);
  1337.     XChangeProperty(theDisp, mainW, window_atom, XA_STRING, 8,
  1338.             PropModeReplace, (unsigned char *)command, 1);
  1339.     if (xa_window_prepare_flag == xaFALSE)
  1340.       xanim_expose(theWG, event, NULL, 0);
  1341.     while (1)
  1342.     {
  1343.       XtAppNextEvent(theContext, &event);
  1344.  
  1345. /* POD NOTE:  eventually make these into Event Handlers that are
  1346.  * conditionally fired base on "xa_window_id" or some other option.
  1347.  */
  1348.       if (event.type == DestroyNotify && devent->window == mainW)
  1349.       {
  1350.     TheEnd();
  1351.       }
  1352.       else if (event.type == ConfigureNotify && cevent->window == mainW)
  1353.       {
  1354.     x11_window_x = cevent->width;
  1355.     x11_window_y = cevent->height;
  1356.       }
  1357.       else if (event.type == PropertyNotify && pevent->window == mainW)
  1358.       {
  1359.     if (pevent->atom == window_atom)
  1360.     {
  1361.       Atom type;
  1362.       int format;
  1363.       long unsigned int nitems;
  1364.       unsigned long extra;
  1365.       char *command;
  1366.       if (pevent->state == PropertyDelete) TheEnd();
  1367.       XGetWindowProperty(theDisp, pevent->window, pevent->atom, 0,
  1368.                  4, False, AnyPropertyType,
  1369.                  &type, &format, &nitems, &extra,
  1370.                  (unsigned char **)&command);
  1371.       switch (*command)
  1372.       {
  1373.       case 'q':
  1374.         XDeleteProperty(theDisp, pevent->window, pevent->atom);
  1375.         TheEnd();
  1376.         break;
  1377.       case ' ':
  1378.         if (xa_anim_status == XA_UNSTARTED) 
  1379.           xanim_expose(theWG, event, NULL, 0);
  1380.         else xanim_toggle_action(theWG, event, NULL, 0);
  1381.         break;
  1382.       case ',':
  1383.         xanim_step_prev_action(theWG, event, NULL, 0);
  1384.         break;
  1385.       case '.':
  1386.         xanim_step_next_action(theWG, event, NULL, 0);
  1387.         break;
  1388.       case 'm':
  1389.         xanim_step_prev_int_action(theWG, event, NULL, 0);
  1390.         break;
  1391.       case '/':
  1392.         xanim_step_next_int_action(theWG, event, NULL, 0);
  1393.         break;
  1394.       case '-':
  1395.         xanim_faster_action(theWG, event, NULL, 0);
  1396.         break;
  1397.       case '=':
  1398.         xanim_slower_action(theWG, event, NULL, 0);
  1399.         break;
  1400.       case '0':
  1401.         xanim_speed_reset_action(theWG, event, NULL, 0);
  1402.         break;
  1403.       case '1':
  1404.         xanim_dec_audio_5(theWG, event, NULL, 0);
  1405.         break;
  1406.       case '2':
  1407.         xanim_dec_audio_1(theWG, event, NULL, 0);
  1408.         break;
  1409.       case '3':
  1410.         xanim_inc_audio_1(theWG, event, NULL, 0);
  1411.         break;
  1412.       case '4':
  1413.         xanim_inc_audio_5(theWG, event, NULL, 0);
  1414.         break;
  1415.       case 's':
  1416.         xanim_mute_audio(theWG, event, NULL, 0);
  1417.         break;
  1418.       case '8':
  1419.         xanim_speaker_tog(theWG, event, NULL, 0);
  1420.         break;
  1421.       case '9':
  1422.         xanim_headphone_tog(theWG, event, NULL, 0);
  1423.         break;
  1424.       case 'v':
  1425.         vaudiof->volume = atoi(command + 1);
  1426.         if (vaudiof->volume < 0)
  1427.           vaudiof->volume = 0;
  1428.         if (vaudiof->volume > XA_AUDIO_MAXVOL)
  1429.           vaudiof->volume = XA_AUDIO_MAXVOL;
  1430.         vaudiof->newvol = xaTRUE;
  1431.         XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1432.         break;
  1433.       case 'e':
  1434.         x11_expose_flag = xaTRUE;
  1435. /* Need a function to redraw window here! */
  1436.         break;
  1437.       default:
  1438.         break;
  1439.       }
  1440.       XFree(command);
  1441.     }
  1442.       }
  1443.       else XtDispatchEvent(&event);
  1444.     }
  1445.   }
  1446. /* end SMR 12 */
  1447. }
  1448.  
  1449. /* PODNOTE:
  1450.  * macro this
  1451.  */
  1452. xaULONG X11_Get_Line_Size(xsize)
  1453. xaULONG xsize;
  1454. {
  1455.   xaULONG line_size;
  1456.  
  1457.   if (x11_display_type == XA_MONOCHROME)
  1458.        line_size = X11_Get_Bitmap_Width(xsize) / 8;
  1459.   else line_size = xsize * x11_bytes_pixel;
  1460.   return(line_size);
  1461. }
  1462.  
  1463. /*
  1464.  * What's this!? Direct access to X11 structures. tsch tsch.
  1465.  */
  1466. void X11_Init_Image_Struct(image,xsize,ysize)
  1467. XImage *image;
  1468. xaULONG xsize,ysize;
  1469. {
  1470.   xaULONG line_size;
  1471.   line_size = X11_Get_Line_Size(xsize);
  1472.   /*PACK*/
  1473.   if (x11_bits_per_pixel==2) line_size = (line_size + 3) / 4;
  1474.   else if (x11_bits_per_pixel==4) line_size = (line_size + 1) / 2;
  1475.   image->width = xsize;
  1476.   image->height = ysize;
  1477.   image->bytes_per_line = line_size;
  1478. DEBUG_LEVEL2 fprintf(stderr," InitImage %x <%d,%d>\n", (xaULONG)(image),xsize,ysize );
  1479. }
  1480.  
  1481.  
  1482. void X11_OutPut_Visual_Class(vis_class)
  1483. xaULONG vis_class;
  1484. {
  1485.   switch(vis_class)
  1486.   {
  1487.    case StaticGray:  fprintf(stderr,"StaticGray"); break;
  1488.    case GrayScale:   fprintf(stderr,"GrayScale"); break;
  1489.    case StaticColor: fprintf(stderr,"StaticColor"); break;
  1490.    case PseudoColor: fprintf(stderr,"PseudoColor"); break;
  1491.    case TrueColor:   fprintf(stderr,"TrueColor"); break;
  1492.    case DirectColor: fprintf(stderr,"DirectColor"); break;
  1493.   }
  1494. }
  1495.  
  1496. void X11_Show_Visuals()
  1497. { int i,vis_num;
  1498.   XVisualInfo *vis;
  1499.  
  1500.   vis = XGetVisualInfo (theDisp, VisualNoMask, NULL, &vis_num);
  1501.   if ((vis == NULL) || (vis_num == 0) )
  1502.   {
  1503.     fprintf(stderr,"X11: Couldn't get any Visuals\n");
  1504.     return;
  1505.   }
  1506.   else
  1507.   {
  1508.     for(i=0;i<vis_num;i++)
  1509.     {
  1510.       fprintf(stderr,"  visual %d) depth= %d  class= %d  cmap size=%d  ",
  1511.                        i, vis[i].depth, vis[i].class, vis[i].colormap_size );
  1512.       X11_OutPut_Visual_Class(vis[i].class);
  1513.       fprintf(stderr,"\n");
  1514.     }
  1515.   }
  1516. }
  1517.  
  1518. void X11_Get_Colormap(chdr)
  1519. XA_CHDR *chdr;
  1520. {
  1521.   ColorReg *cmap;
  1522.   xaULONG i,*map;
  1523.  
  1524.   /* grab the current cmap and lay it down */
  1525.   for(i=0;i<x11_cmap_size;i++)
  1526.   {
  1527.     if (x11_display_type & XA_X11_TRUE)
  1528.     {
  1529.       xaULONG d;
  1530.       d  =  (i << x11_red_shift)   & x11_red_mask;
  1531.       d |=  (i << x11_green_shift) & x11_green_mask;
  1532.       d |=  (i << x11_blue_shift)  & x11_blue_mask;
  1533.       defs[i].pixel =  d;
  1534.     }
  1535.     else defs[i].pixel = i;
  1536.     defs[i].flags = DoRed | DoGreen | DoBlue;
  1537.   }
  1538.   XQueryColors(theDisp,theCmap,defs,x11_cmap_size);
  1539.   
  1540.   cmap = chdr->cmap;
  1541.   map = chdr->map;
  1542.   if (cmap == 0) TheEnd1("X11_Get_Colormap: cmap = 0");
  1543.   if (map == 0) TheEnd1("X11_Get_Colormap: map = 0");
  1544. DEBUG_LEVEL2 fprintf(stderr,"X11_Get_Colormap:\n");
  1545.   for(i=0;i<x11_cmap_size;i++)
  1546.   {
  1547.     xaULONG r,g,b;
  1548.     r = cmap[i].red   = (xaUSHORT)defs[i].red; 
  1549.     g = cmap[i].green = (xaUSHORT)defs[i].green; 
  1550.     b = cmap[i].blue  = (xaUSHORT)defs[i].blue; 
  1551.     cmap[i].gray =  (xaUSHORT)( ((r * 11) + (g * 16) + (b * 5)) >> 5 ); 
  1552.     map[i] = i;
  1553.     DEBUG_LEVEL2 fprintf(stderr,"   %d) <%x %x %x> %x\n",i,r,g,b,chdr->cmap[i].gray);
  1554.   }
  1555. }
  1556.  
  1557. void X11_Make_Nice_CHDR(chdr)
  1558. XA_CHDR *chdr;
  1559. {
  1560.   ColorReg *old_cmap,*new_cmap;
  1561.   xaULONG i,*old_map,*new_map;
  1562.   xaULONG old_csize,old_msize;
  1563.  
  1564.   if ( !(x11_display_type & XA_X11_CMAP)) return;
  1565.   
  1566.   old_cmap = chdr->cmap;
  1567.   old_map  = chdr->map;
  1568.   old_csize = chdr->csize;
  1569.   old_msize = chdr->msize;
  1570.  
  1571.   /* try allocating colors */
  1572.   for(i=0;i<old_csize;i++)
  1573.   {
  1574.     if (x11_display_type & XA_X11_GRAY)
  1575.     {
  1576.       defs[i].red = defs[i].green = defs[i].blue = old_cmap[i].gray;
  1577.     }
  1578.     else
  1579.     {
  1580.       defs[i].red   = old_cmap[i].red;
  1581.       defs[i].green = old_cmap[i].green;
  1582.       defs[i].blue  = old_cmap[i].blue;
  1583.     }
  1584.     defs[i].flags = DoRed | DoGreen | DoBlue;
  1585.     XAllocColor(theDisp,theCmap,&defs[i]);
  1586.   }
  1587.   
  1588.   /* Query the cmap */
  1589.   for(i=0;i<x11_cmap_size;i++)
  1590.   {
  1591.     if (x11_display_type & XA_X11_TRUE)
  1592.     {
  1593.       xaULONG d;
  1594.       d  =  (i << x11_red_shift)   & x11_red_mask;
  1595.       d |=  (i << x11_green_shift) & x11_green_mask;
  1596.       d |=  (i << x11_blue_shift)  & x11_blue_mask;
  1597.       defs[i].pixel =  d;
  1598.     }
  1599.     else defs[i].pixel = i;
  1600.     defs[i].flags = DoRed | DoGreen | DoBlue;
  1601.   }
  1602.   XQueryColors(theDisp,theCmap, defs,x11_cmap_size);
  1603.  
  1604.   if (old_csize != x11_cmap_size)
  1605.   {
  1606.     new_cmap = (ColorReg *)malloc(x11_cmap_size * sizeof(ColorReg) );
  1607.     if (new_cmap == 0) TheEnd1("X11_Make_Nice_CHDR: cmap malloc err");
  1608.     FREE(old_cmap,0x400); old_cmap=0;
  1609.     chdr->csize = x11_cmap_size;
  1610.     chdr->cmap = new_cmap;
  1611.   }
  1612.  
  1613.   if (old_msize != x11_cmap_size)
  1614.   { new_map = (xaULONG *)malloc(x11_cmap_size * sizeof(xaULONG) );
  1615.     if (new_map == 0) TheEnd1("X11_Make_Nice_CHDR: map malloc err");
  1616.     FREE(old_map,0x401); old_cmap=0;
  1617.     chdr->msize = x11_cmap_size;
  1618.     chdr->map = new_map;
  1619.   }
  1620.   
  1621.   DEBUG_LEVEL2 fprintf(stderr,"X11_Make_Nice_CHDR: \n");
  1622.   chdr->moff = chdr->coff = 0;
  1623.   for(i=0;i<x11_cmap_size;i++)
  1624.   { xaULONG r,g,b;
  1625.     r = chdr->cmap[i].red   = defs[i].red; 
  1626.     g = chdr->cmap[i].green = defs[i].green; 
  1627.     b = chdr->cmap[i].blue  = defs[i].blue; 
  1628.     chdr->cmap[i].gray = (xaUSHORT)( ( (r * 11) + (g * 16) + (b * 5) ) >> 5 );
  1629.     chdr->map[i] = i;
  1630.     DEBUG_LEVEL2 fprintf(stderr," %d) <%x %x %x> %x\n",i,r,g,b,chdr->cmap[i].gray);
  1631.   }
  1632. }
  1633.  
  1634.  
  1635. int XA_Error_Handler(errDisp,event)
  1636. Display *errDisp;
  1637. XErrorEvent *event;
  1638. { char errbuff[255];
  1639.   if (x11_error_possible != 1) 
  1640.     XGetErrorText(errDisp,event->error_code, errbuff, 255);
  1641.   x11_error_possible = -1;
  1642.   return(0);
  1643. }
  1644.  
  1645.  
  1646. #ifdef XA_PETUNIA
  1647.  
  1648. void xa_remote_expose();
  1649.  
  1650. static void InitButtons();
  1651. static void InitButtonsTypes();
  1652. static void InitScrolls();
  1653. static void GetButtonColors();
  1654. static void DrawRemote();
  1655. static void DrawButton();
  1656. static void DrawScroll();
  1657. static xaULONG InButtonQuery();
  1658. static void AdjustScroll();
  1659. static xaLONG WhichButton();
  1660.  
  1661.  
  1662.  
  1663. /* Make xa_buttons.h */
  1664.  
  1665. typedef struct
  1666. {
  1667.   int width;
  1668.   int height;
  1669.   unsigned char *hi_bitmap;
  1670.   unsigned char *lo_bitmap;
  1671.   Pixmap hi;
  1672.   Pixmap lo;
  1673. } BUTTON_TYPE;
  1674.  
  1675. /** Buttons ***/
  1676. #include "buttons/but_quad10_hi.xbm"
  1677. #include "buttons/but_quad10_lo.xbm"
  1678. #include "buttons/but_quad16_hi.xbm"
  1679. #include "buttons/but_quad16_lo.xbm"
  1680. #include "buttons/but_rtri10_hi.xbm"
  1681. #include "buttons/but_rtri10_lo.xbm"
  1682. #include "buttons/but_ltri10_hi.xbm"
  1683. #include "buttons/but_ltri10_lo.xbm"
  1684. #include "buttons/but_rstp16_hi.xbm"
  1685. #include "buttons/but_rstp16_lo.xbm"
  1686. #include "buttons/but_lstp16_hi.xbm"
  1687. #include "buttons/but_lstp16_lo.xbm"
  1688. #include "buttons/but_plus16_hi.xbm"
  1689. #include "buttons/but_plus16_lo.xbm"
  1690. #include "buttons/but_dash16_hi.xbm"
  1691. #include "buttons/but_dash16_lo.xbm"
  1692. #include "buttons/but_sond16_hi.xbm"
  1693. #include "buttons/but_sond16_lo.xbm"
  1694. #include "buttons/but_next16_hi.xbm"
  1695. #include "buttons/but_next16_lo.xbm"
  1696. #include "buttons/but_prev16_hi.xbm"
  1697. #include "buttons/but_prev16_lo.xbm"
  1698. #include "buttons/but_circ16_hi.xbm"
  1699. #include "buttons/but_circ16_lo.xbm"
  1700. #include "buttons/but_vol56_lo.xbm"
  1701. #include "buttons/but_vol56_hi.xbm"
  1702.  
  1703. /** Scrollbars */
  1704. #include "buttons/bar_6x4_lo.xbm"
  1705. #include "buttons/bar_6x4_hi.xbm"
  1706.  
  1707. /** Decals ***/
  1708. #include "buttons/txt_exit.xbm"
  1709. #include "buttons/txt_auup.xbm"
  1710. #include "buttons/txt_audn.xbm"
  1711.  
  1712. #define BUTTON_TYPE_QUAD16       0
  1713. #define BUTTON_TYPE_RTRI16       1
  1714. #define BUTTON_TYPE_LTRI16       2
  1715. #define BUTTON_TYPE_RSTP16       3
  1716. #define BUTTON_TYPE_LSTP16       4
  1717. #define BUTTON_TYPE_PLUS16       5
  1718. #define BUTTON_TYPE_DASH16       6
  1719. #define BUTTON_TYPE_SOND16       7
  1720. #define BUTTON_TYPE_QUAD10       8
  1721. #define BUTTON_TYPE_NEXT16       9
  1722. #define BUTTON_TYPE_PREV16      10
  1723. #define BUTTON_TYPE_CIRC16      11
  1724. #define BUTTON_TYPE_VOL56       12
  1725.  
  1726.  
  1727. #define NUM_BUTTON_TYPES 13
  1728. BUTTON_TYPE button_types[] =    {
  1729.         { but_quad16_hi_width, but_quad16_hi_height,
  1730.           but_quad16_hi_bits, but_quad16_lo_bits, 0, 0 },
  1731.         { but_rtri10_hi_width, but_rtri10_hi_height,
  1732.           but_rtri10_hi_bits, but_rtri10_lo_bits, 0, 0 },
  1733.         { but_ltri10_hi_width, but_ltri10_hi_height,
  1734.           but_ltri10_hi_bits, but_ltri10_lo_bits, 0, 0 },
  1735.         { but_rstp16_hi_width, but_rstp16_hi_height,
  1736.           but_rstp16_hi_bits, but_rstp16_lo_bits, 0, 0 },
  1737.         { but_lstp16_hi_width, but_lstp16_hi_height,
  1738.           but_lstp16_hi_bits, but_lstp16_lo_bits, 0, 0 },
  1739.         { but_plus16_hi_width, but_plus16_hi_height,
  1740.           but_plus16_hi_bits, but_plus16_lo_bits, 0, 0 },
  1741.         { but_dash16_hi_width, but_dash16_hi_height,
  1742.           but_dash16_hi_bits, but_dash16_lo_bits, 0, 0 },
  1743.         { but_sond16_hi_width, but_sond16_hi_height,
  1744.           but_sond16_hi_bits, but_sond16_lo_bits, 0, 0 },
  1745.         { but_quad10_hi_width, but_quad10_hi_height,
  1746.           but_quad10_hi_bits, but_quad10_lo_bits, 0, 0 },
  1747.         { but_next16_hi_width, but_next16_hi_height,
  1748.           but_next16_hi_bits, but_next16_lo_bits, 0, 0 },
  1749.         { but_prev16_hi_width, but_prev16_hi_height,
  1750.           but_prev16_hi_bits, but_prev16_lo_bits, 0, 0 },
  1751.         { but_circ16_hi_width, but_circ16_hi_height,
  1752.           but_circ16_hi_bits, but_circ16_lo_bits, 0, 0 },
  1753.         { but_vol56_hi_width, but_vol56_hi_height,
  1754.           but_vol56_hi_bits, but_vol56_lo_bits, 0, 0 },
  1755.                                 };
  1756.  
  1757. #define BUTTON_STATE_OFF    0x0000
  1758. #define BUTTON_STATE_ON        0x0001
  1759.  
  1760. #define BUTTON_STATE_FIXED    0x0100
  1761. #define BUTTON_STATE_AON    0x0100
  1762.  
  1763. #define BUTTON_STATE_SEL      0x0200
  1764. #define BUTTON_STATE_SELON    0x0200
  1765. #define BUTTON_STATE_SELOFF    0x0201
  1766.  
  1767. #define BUTTON_STATE_FSEL     0x0400
  1768.  
  1769. /* redefine into Colors */
  1770. static int button_back,button_lo,button_main,button_hi;
  1771.  
  1772.  
  1773. typedef struct
  1774. { xaLONG type;
  1775.   xaULONG xpos, ypos;
  1776.   xaULONG state;
  1777.   void (*func)();
  1778.   xaULONG width, height;
  1779.   unsigned char *bitmap;
  1780.   Pixmap  pmap;
  1781.   xaLONG scroll;
  1782. } BUTTON;
  1783.  
  1784. /* These are for toggle functions implemented later below */
  1785. #define BUTTON_PLAYPREV 1
  1786. #define BUTTON_PLAYSTOP 2
  1787. #define BUTTON_PLAYNEXT 3
  1788. #define BUTTON_AUDIO    12
  1789. #define BUTTON_SPEED    9
  1790. #define BUTTON_VOLBAR    14
  1791.  
  1792.  
  1793. /* POD Eventually come up with a more elegant way of defining this */
  1794. #define REMOTE_HEIGHT (4 + 16 + 4 + 16 + 4 + 16 + 4 + 20 + 4 )
  1795. #define REMOTE_WIDTH  (4 + 16 + 4 + 10 + 4 + 10 + 4 + 10 + 4 + 16 + 4 )
  1796.  
  1797. #define NUM_BUTTONS 15
  1798. BUTTON buttons[] =      {
  1799.         { BUTTON_TYPE_PREV16,  4,  4 ,BUTTON_STATE_OFF, xanim_step_prev_action,
  1800.                 0, 0, 0, 0, -1 },
  1801.         { BUTTON_TYPE_LTRI16, 24,  4 ,BUTTON_STATE_OFF, xact_playprev,
  1802.                 0, 0, 0, 0, -1 },
  1803.         { BUTTON_TYPE_QUAD10, 38,  4 ,BUTTON_STATE_OFF, xact_playstop,
  1804.                 0, 0, 0, 0, -1 },
  1805.         { BUTTON_TYPE_RTRI16, 52,  4 ,BUTTON_STATE_ON, xact_playnext,
  1806.                 0, 0, 0, 0, -1 },
  1807.         { BUTTON_TYPE_NEXT16, 66,  4 ,BUTTON_STATE_OFF, xanim_step_next_action,
  1808.                 0, 0, 0, 0, -1 },
  1809.  
  1810.         { BUTTON_TYPE_LSTP16,  11, 24 ,BUTTON_STATE_OFF, xanim_prev_anim_action,
  1811.                 0, 0, 0, 0, -1 },
  1812.         { BUTTON_TYPE_QUAD16,  31, 24 ,BUTTON_STATE_OFF, xanim_quit_action,
  1813.                 txt_exit_width, txt_exit_height, txt_exit_bits, 0, -1 },
  1814.         { BUTTON_TYPE_RSTP16,  51, 24 ,BUTTON_STATE_OFF, xanim_next_anim_action,
  1815.                 0, 0, 0, 0, -1 },
  1816.  
  1817.         { BUTTON_TYPE_DASH16, 11, 44 ,BUTTON_STATE_OFF,xanim_slower_action,
  1818.                 0, 0, 0, 0, 0},
  1819.         { BUTTON_TYPE_CIRC16, 31, 44 ,BUTTON_STATE_ON, xanim_speed_reset_action,
  1820.                 0, 0, 0, 0, -1 },
  1821.         { BUTTON_TYPE_PLUS16, 51, 44 ,BUTTON_STATE_OFF,xanim_faster_action,
  1822.                 0, 0, 0, 0, -1 },
  1823.  
  1824.         { BUTTON_TYPE_SOND16, 11, 64 ,BUTTON_STATE_OFF, xanim_dec_audio_5,
  1825.                 txt_audn_width, txt_audn_height, txt_audn_bits, 0, -1 },
  1826.         { BUTTON_TYPE_SOND16, 31, 64 ,BUTTON_STATE_ON, xanim_mute_audio,
  1827.                 0, 0, 0, 0, -1 },
  1828.         { BUTTON_TYPE_SOND16, 51, 64 ,BUTTON_STATE_OFF, xanim_inc_audio_5,
  1829.                 txt_auup_width, txt_auup_height, txt_auup_bits, 0, -1 },
  1830.         { BUTTON_TYPE_VOL56 , 72, 26 ,BUTTON_STATE_AON, xanim_set_volume,
  1831.                 0, 0, 0, 0, 0 },
  1832.                         };
  1833.  
  1834.  
  1835. static void xanim_set_volume(w,event,but)
  1836. Widget w;
  1837. XEvent *event;
  1838. BUTTON *but;
  1839. { XButtonEvent *xbut = (XButtonEvent *)event;
  1840.   xaLONG len, pos, new_vol;
  1841.  
  1842.   /* border of scroll bar is 2 pixels */
  1843.   len = button_types[ but->type ].height - 4;
  1844.   pos = len - (xbut->y - (but->ypos + 2));
  1845.   if (pos < 0) pos = 0;
  1846.   new_vol = (XA_AUDIO_MAXVOL * pos) / len;
  1847.   if (new_vol > XA_AUDIO_MAXVOL) new_vol = XA_AUDIO_MAXVOL;
  1848.   vaudiof->volume = new_vol;
  1849.   vaudiof->newvol = xaTRUE;
  1850.   XA_AUDIO_SET_VOLUME(vaudiof->volume);
  1851. #ifdef XA_REMOTE_CONTROL
  1852.   XA_Remote_Adj_Volume(vaudiof->volume,XA_AUDIO_MAXVOL);
  1853. #endif
  1854. }
  1855.  
  1856. typedef struct
  1857. {
  1858.   xaULONG type;        /* 0 vert 1 horiz */
  1859.   xaULONG cur;
  1860.   xaULONG xpos, ypos;
  1861.   xaULONG length;
  1862.   xaULONG width, height;
  1863.   unsigned char *lo_bitmap;
  1864.   unsigned char *hi_bitmap;
  1865.   Pixmap  lo;
  1866.   Pixmap  hi;
  1867. } SCROLLBAR;
  1868.  
  1869.  
  1870.  
  1871. #define SCROLLBAR_VOLUME 0
  1872.  
  1873. #define NUM_SCROLLBARS 1
  1874. static SCROLLBAR scrollbars[] = {
  1875.     { 0, 38, 73, 28, 48, bar_6x4_hi_width, bar_6x4_hi_height,
  1876.       bar_6x4_lo_bits, bar_6x4_hi_bits, 0, 0 },
  1877.         };
  1878.  
  1879. static void remote_btn1dn(), remote_btn1up();
  1880.  
  1881. #define REMOTE_ACTIONTABLE_SIZE 2
  1882. XtActionsRec remote_actionTable[] = {
  1883.         {"RemBtn1Dn", remote_btn1dn},
  1884.         {"RemBtn1Up", remote_btn1up},
  1885. };
  1886.  
  1887.  
  1888. String   Remote_Translation =
  1889.   "<Expose>:            Expose()\n\
  1890.    <Btn1Down>:          RemBtn1Dn()\n\
  1891.    <Btn1Up>:            RemBtn1Up()\n\
  1892.    <Key>1:              DecAudio5()\n\
  1893.    <Key>2:              DecAudio1()\n\
  1894.    <Key>3:              IncAudio1()\n\
  1895.    <Key>4:              IncAudio5()\n\
  1896.    <Key>8:              SpeakerTog()\n\
  1897.    <Key>9:              HDPhoneTog()\n\
  1898.    <Key>p:        PingPong()\n\
  1899.    <Key>s:              AudioMute()\n\
  1900.    <Key>q:              Quit()\n\
  1901.    <Key>w:              Resize()\n\
  1902.    <Key>F:              InstallCmap()\n\
  1903.    <Key>z:              RealizeRemote()\n\
  1904.    <Key>g:              StopCmap()\n\
  1905.    <Key>r:              RestoreCmap()\n\
  1906.    <Key>-:              Slower()\n\
  1907.    <Key>=:              Faster()\n\
  1908.    <Key>0:              SpeedReset()\n\
  1909.    <Key>.:              StepNext()\n\
  1910.    <Key>comma:          StepPrev()\n\
  1911.    <Key>greater:        NextAnim()\n\
  1912.    <Key>less:           PrevAnim()\n\
  1913.    <Key>/:              StepNextInt()\n\
  1914.    <Key>m:              StepPrevInt()\n\
  1915.    <Key>space:          RunStop()";
  1916.  
  1917.  
  1918. /* PETUNIA */
  1919. void XA_Create_Remote(wg,remote_flag)
  1920. Widget wg;
  1921. xaLONG remote_flag;
  1922. { xaLONG n;
  1923.   Arg arglist[20];
  1924.   XWMHints xwm_hints;
  1925.  
  1926.   XtAppAddActions(theContext, remote_actionTable, REMOTE_ACTIONTABLE_SIZE);
  1927.  
  1928.   GetButtonColors(0);
  1929.  
  1930.   n = 0;
  1931. #ifdef XtNvisual
  1932.   XtSetArg(arglist[n], XtNvisual, theVisual); n++;
  1933. #endif
  1934.   XtSetArg(arglist[n], XtNcolormap, theCmap); n++;
  1935.   XtSetArg(arglist[n], XtNdepth, x11_depth); n++;
  1936.   XtSetArg(arglist[n], XtNforeground, button_main); n++;
  1937.   XtSetArg(arglist[n], XtNbackground, button_back); n++;
  1938.   XtSetArg(arglist[n], XtNborderColor, button_main); n++;
  1939.   XtSetArg(arglist[n], XtNwidth, REMOTE_WIDTH); n++;
  1940.   XtSetArg(arglist[n], XtNheight, REMOTE_HEIGHT); n++;
  1941.   XtSetArg(arglist[n], XtNx, XA_REMW_XPOS); n++;
  1942.   XtSetArg(arglist[n], XtNy, XA_REMW_YPOS); n++;
  1943.   XtSetArg(arglist[n], XtNmaxWidth, REMOTE_WIDTH); n++;
  1944.   XtSetArg(arglist[n], XtNmaxHeight, REMOTE_HEIGHT); n++;
  1945.  
  1946.   XtSetArg(arglist[n], XtNtranslations,
  1947.                         XtParseTranslationTable(Remote_Translation)); n++;
  1948.  
  1949.   remote_widget = XtCreatePopupShell("Control",topLevelShellWidgetClass,
  1950.                             wg,arglist,n);
  1951.  
  1952.   XtRealizeWidget(remote_widget);
  1953.   remoteW = XtWindow(remote_widget);
  1954.  
  1955.   { xaULONG gc_mask = 0;
  1956.     XGCValues gc_init;
  1957.     gc_init.function = GXcopy;                          gc_mask |= GCFunction;
  1958.     gc_init.foreground = button_main; gc_mask |= GCForeground;
  1959.     gc_init.background = button_back; gc_mask |= GCBackground;
  1960.     gc_init.graphics_exposures = False;         gc_mask |= GCGraphicsExposures;
  1961.     remoteGC  = XCreateGC(theDisp,remoteW,gc_mask,&gc_init);
  1962.   }
  1963.   xwm_hints.input = True;
  1964.   xwm_hints.flags = InputHint;
  1965.   XSetWMHints(theDisp,remoteW,&xwm_hints);
  1966.   XSync(theDisp,False);
  1967.  
  1968.   InitButtonsTypes(button_types,NUM_BUTTON_TYPES);
  1969.   InitButtons(buttons,NUM_BUTTONS);
  1970.   InitScrolls(scrollbars,NUM_SCROLLBARS);
  1971.  
  1972.   /* THIS IS VERY IMPORTANT AND IS TO DELAY STARTUP UNTIL AN EXPOSE EVENT
  1973.    * HAPPENS so everything is realized and mapped before animation starts.
  1974.    * xa_remote_ready is set to xaTRUE in the xa_remote_expose routine.
  1975.    */
  1976.   XtAddRawEventHandler(remote_widget, ExposureMask, False, 
  1977.                         xa_remote_expose, NULL);
  1978.  
  1979.   /******** REALIZE THE WIDGET *******/
  1980.   if (remote_flag == xaTRUE) XA_Realize_Remote(remote_widget);
  1981.   else xa_remote_ready = xaTRUE;
  1982. }
  1983.  
  1984. /* 
  1985.  * uses global last_widget 
  1986.  */
  1987. void XA_Realize_Remote(remote)
  1988. Widget remote;
  1989. {
  1990.   xa_remote_realized = xaTRUE;
  1991.   XtRealizeWidget(remote_widget);
  1992.   remoteW = XtWindow(remote_widget);
  1993.   XSync(theDisp,False);
  1994.   while(XtIsRealized(remote)==False) XSync(theDisp,False);
  1995.  
  1996.   { xaULONG gc_mask = 0;
  1997.     XGCValues gc_init;
  1998.     gc_init.function = GXcopy;                          gc_mask |= GCFunction;
  1999.     gc_init.foreground = button_main; gc_mask |= GCForeground;
  2000.     gc_init.background = button_back; gc_mask |= GCBackground;
  2001.     gc_init.graphics_exposures = False;         gc_mask |= GCGraphicsExposures;
  2002.     remoteGC  = XCreateGC(theDisp,remoteW,gc_mask,&gc_init);
  2003.   }
  2004.   { XWMHints xwm_hints;
  2005.     xwm_hints.input = True;
  2006.     xwm_hints.flags = InputHint;
  2007.     XSetWMHints(theDisp,remoteW,&xwm_hints);
  2008.     XSync(theDisp,False);
  2009.   }
  2010.   XMapWindow(theDisp,remoteW);
  2011.   XRaiseWindow(theDisp, remoteW );
  2012.   XSetWindowColormap(theDisp, remoteW, theCmap); 
  2013.   GetButtonColors(xa_chdr_now);
  2014.   DrawRemote(buttons,NUM_BUTTONS);
  2015. }
  2016.  
  2017. void XA_Unrealize_Remote(remote)
  2018. Widget remote;
  2019. {
  2020.   XSync(theDisp,False);
  2021.   XtPopdown(remote);
  2022.   XSync(theDisp,False);
  2023.   XtUnrealizeWidget(remote);
  2024.   XSync(theDisp,False);
  2025.   while(XtIsRealized(remote)==True) XSync(theDisp,False);
  2026.   xa_remote_realized = xaFALSE;
  2027. }
  2028.  
  2029.  
  2030. /* Event Handler */
  2031. void xa_remote_expose(wg, closure, event, notused)
  2032. Widget          wg;        XtPointer    closure;
  2033. XEvent        *event;        Boolean        *notused;
  2034. { xa_remote_ready = xaTRUE;
  2035.   GetButtonColors(xa_chdr_now);
  2036.   DrawRemote(buttons,NUM_BUTTONS);
  2037. }
  2038.  
  2039.  
  2040. static int button_wait = 0;
  2041.  
  2042. static void PetuniaButtonsUp()
  2043. { int i;
  2044.   button_wait = 0;
  2045.   for(i=0;i<NUM_BUTTONS;i++)
  2046.   { if (buttons[i].state & BUTTON_STATE_SEL)
  2047.         { buttons[i].state &= ~BUTTON_STATE_SEL;
  2048.           DrawButton(&buttons[i]);
  2049.         }
  2050.     if (buttons[i].state & BUTTON_STATE_FSEL)
  2051.         { buttons[i].state &= ~BUTTON_STATE_FSEL; }
  2052.   }
  2053. }
  2054.  
  2055. /* This stuff is to make sure the buttons are held down for X amount
  2056.  * of milliseconds so the user gets to see the button being pressed.
  2057.  * Otherwise on fast machines, they may not see it at all.
  2058.  */
  2059. void PetuniaButtonWait(client_data,id)
  2060. void *client_data;
  2061. void *id;
  2062. {
  2063.   button_wait++;  if (button_wait >= 3) PetuniaButtonsUp();
  2064. }
  2065.  
  2066.  
  2067. ACTION_PROC(remote_btn1dn)
  2068. { XButtonEvent *xbut = (XButtonEvent *)event;
  2069.   int but;
  2070.  
  2071.   if (button_wait) return;  /* Too Soon */
  2072.  
  2073.   but = WhichButton(buttons,NUM_BUTTONS,xbut->x,xbut->y);
  2074.   if ( (but >= 0) && (but < NUM_BUTTONS) )
  2075.   { if (buttons[but].state & BUTTON_STATE_FIXED)
  2076.     { buttons[but].state |= BUTTON_STATE_FSEL;
  2077.     }
  2078.     else
  2079.     { buttons[but].state |= BUTTON_STATE_SEL; 
  2080.       DrawButton( &buttons[but] );
  2081.     }
  2082.     button_wait = 1;
  2083.     XtAppAddTimeOut(theContext,50,(XtTimerCallbackProc)PetuniaButtonWait,NULL);
  2084.  
  2085.   }
  2086. }
  2087.  
  2088. ACTION_PROC(remote_btn1up)
  2089. { XButtonEvent *xbut = (XButtonEvent *)event;
  2090.   int but = WhichButton(buttons,NUM_BUTTONS,xbut->x,xbut->y);
  2091.   if ((but >= 0) && (but < NUM_BUTTONS))
  2092.   { if (buttons[but].state & BUTTON_STATE_SEL)
  2093.     { 
  2094.       if (buttons[but].func)  buttons[but].func(w,event,params,num_params);
  2095.     }
  2096.     else if (buttons[but].state & BUTTON_STATE_FSEL)
  2097.     {
  2098.       if (buttons[but].func)  buttons[but].func(w,event,&buttons[but]);
  2099.     }
  2100.   }
  2101.   button_wait++;  if (button_wait >= 3) PetuniaButtonsUp();
  2102. }
  2103.  
  2104. /***************************************
  2105.  * Find closet color in chdr, but NOT for monochrome displays
  2106.  *  r,g,b  8 bits each.
  2107.  *******************************/
  2108. xaULONG PetuniaGetColor(r,g,b,chdr)
  2109. xaULONG r,g,b;
  2110. XA_CHDR *chdr;
  2111. { if (x11_display_type & XA_X11_TRUE) return(X11_Get_True_Color(r,g,b,8));
  2112.   else if ((chdr) || (xa_chdr_first))
  2113.   { XA_CHDR *tchdr = (chdr)?(chdr):(xa_chdr_first);
  2114.     /* using xaFALSE for GrayScale?? */
  2115.     return( CMAP_Find_Closest(tchdr->cmap,tchdr->csize,r,g,b,8,8,8,xaTRUE) );
  2116.   }
  2117.   else
  2118.   { XColor col;        
  2119.     col.red   = r; col.green = g; col.blue  = b;
  2120.     col.flags = DoRed | DoGreen | DoBlue;
  2121.     XAllocColor(theDisp,theCmap,&col);
  2122.     return( (xaULONG)(col.pixel) );
  2123.   }
  2124. }
  2125.  
  2126. static void GetButtonColors(chdr)
  2127. XA_CHDR *chdr;
  2128. { if (x11_display_type == XA_MONOCHROME)
  2129.   { button_main = button_back = BlackPixel(theDisp,theScreen);
  2130.     button_hi = button_lo = WhitePixel(theDisp,theScreen);
  2131.   }
  2132.   else
  2133.   { button_back = PetuniaGetColor(0x00,0x00,0x00,chdr);
  2134.     button_lo   = PetuniaGetColor(0x60,0x60,0x60,chdr);
  2135.     button_main = PetuniaGetColor(0xa8,0xa8,0xa8,chdr);
  2136.     button_hi   = PetuniaGetColor(0xd0,0xd0,0xd0,chdr);
  2137.   }
  2138. }
  2139.  
  2140.  
  2141. /*
  2142.  * Use remoteW, remoteGC
  2143.  *
  2144.  *
  2145.  *
  2146.  */
  2147. static void DrawRemote(buttons,num)
  2148. BUTTON *buttons;
  2149. xaULONG num;
  2150. { int i;
  2151.  
  2152.   XSetClipMask(theDisp,remoteGC,None);
  2153.   XSetForeground(theDisp,remoteGC,button_main);
  2154.   XFillRectangle(theDisp,remoteW,remoteGC,0,0,REMOTE_WIDTH,REMOTE_HEIGHT);
  2155.   for(i=0; i < num; i++) DrawButton( &buttons[i] );
  2156. }
  2157.  
  2158.  
  2159. static void InitButtonsTypes(button_types,num)
  2160. BUTTON_TYPE *button_types;
  2161. xaULONG num;
  2162. { xaULONG i;
  2163.  
  2164.   for(i=0; i < num; i++)
  2165.   { if (button_types[i].width)
  2166.     { button_types[i].hi = XCreatePixmapFromBitmapData(theDisp, remoteW, 
  2167.     (char *)button_types[i].hi_bitmap,
  2168.     (int)button_types[i].width, (int)button_types[i].height,0x01,0x00,1);
  2169.       button_types[i].lo = XCreatePixmapFromBitmapData(theDisp, remoteW, 
  2170.     (char *)button_types[i].lo_bitmap,
  2171.     (int)button_types[i].width, (int)button_types[i].height,0x01,0x00,1);
  2172.     }
  2173.   }
  2174. }
  2175.  
  2176. /**** Make sure remoteW exists at this point */
  2177. static void InitButtons(buttons,num)
  2178. BUTTON *buttons;
  2179. xaULONG num;
  2180. { xaULONG i;
  2181.   for(i=0; i < num; i++)
  2182.   { if (buttons[i].bitmap)
  2183.     { buttons[i].pmap = XCreatePixmapFromBitmapData(theDisp, remoteW, 
  2184.     (char *)buttons[i].bitmap,
  2185.     (int)buttons[i].width, (int)buttons[i].height,0x01,0x00,1);
  2186.     }
  2187.   }
  2188. }
  2189.  
  2190. static void InitScrolls(scrolls,num)
  2191. SCROLLBAR *scrolls;
  2192. xaULONG num;
  2193. { xaULONG i;
  2194.  
  2195.   for(i=0; i < num; i++)
  2196.   { 
  2197.     scrolls[i].hi = XCreatePixmapFromBitmapData(theDisp, remoteW, 
  2198.     (char *)scrolls[i].hi_bitmap,
  2199.     (int)scrolls[i].width, (int)scrolls[i].height,0x01,0x00,1);
  2200.     scrolls[i].lo = XCreatePixmapFromBitmapData(theDisp, remoteW, 
  2201.     (char *)scrolls[i].lo_bitmap,
  2202.     (int)scrolls[i].width, (int)scrolls[i].height,0x01,0x00,1);
  2203.   }
  2204. }
  2205.  
  2206.  
  2207. static void DrawButton(button)
  2208. BUTTON *button;
  2209. { xaULONG type,x,y,width,height;
  2210.   int hi, lo; 
  2211.  
  2212.   if (button == 0) return;
  2213.   type = button->type;
  2214.   x = button->xpos;            y = button->ypos;
  2215.   width  = button_types[type].width;    height = button_types[type].height;
  2216.  
  2217.   if (button->state == BUTTON_STATE_OFF) { hi = button_hi; lo = button_lo; }
  2218.   else { hi = button_lo; lo = button_hi; }
  2219.  
  2220.   XSetClipOrigin(theDisp,remoteGC,x,y);
  2221.     /** If SubButton erase area first **/
  2222.   if (button->scroll >= 0)
  2223.   { XSetForeground(theDisp,remoteGC,button_main);
  2224.     XSetClipMask(theDisp,remoteGC,None);
  2225.     XFillRectangle(theDisp,remoteW,remoteGC,
  2226.                 (int)x,(int)y,(int)width,(int)height);
  2227.   }
  2228.     /** Low Color **/
  2229.   if (button_types[type].lo)
  2230.   { XSetForeground(theDisp,remoteGC,lo);
  2231.     XSetClipMask(theDisp,remoteGC,button_types[type].lo);
  2232.     XFillRectangle(theDisp,remoteW,remoteGC,
  2233.                 (int)x,(int)y,(int)width,(int)height);
  2234.   }
  2235.     /** Hi Color **/
  2236.   if (button_types[type].hi)
  2237.   { XSetForeground(theDisp,remoteGC,hi);
  2238.     XSetClipMask(theDisp,remoteGC,button_types[type].hi);
  2239.     XFillRectangle(theDisp,remoteW,remoteGC,
  2240.                 (int)x,(int)y,(int)width,(int)height);
  2241.   }
  2242.     /** Text Color **/
  2243.   if (button->pmap)
  2244.   { if (x11_display_type == XA_MONOCHROME)
  2245.             XSetForeground(theDisp,remoteGC,button_hi);
  2246.     else        XSetForeground(theDisp,remoteGC,button_back);
  2247.     XSetClipMask(theDisp,remoteGC,button->pmap);
  2248.     XFillRectangle(theDisp,remoteW,remoteGC,
  2249.             (int)x,(int)y,(int)button->width,(int)button->height);
  2250.   }
  2251.   if (button->scroll >= 0) DrawScroll( &scrollbars[button->scroll] );
  2252.   XSync(theDisp,False);
  2253. }
  2254.  
  2255. static void DrawScroll(scroll)
  2256. SCROLLBAR *scroll;
  2257. { xaULONG x,y,width,height;
  2258.  
  2259.   if (scroll == 0) return;
  2260.   if (scroll->type == 0) { x = scroll->xpos;        y = scroll->cur; }
  2261.   else             { x = scroll->cur;        y = scroll->ypos; }
  2262.  
  2263.   width  = scroll->width;    height = scroll->height;
  2264.  
  2265.   XSetClipOrigin(theDisp,remoteGC,x,y);
  2266.     /** Low Color **/
  2267.   if (scroll->lo)
  2268.   { XSetForeground(theDisp,remoteGC,button_lo);
  2269.     XSetClipMask(theDisp,remoteGC,scroll->lo);
  2270.     XFillRectangle(theDisp,remoteW,remoteGC,
  2271.                 (int)x,(int)y,(int)width,(int)height);
  2272.   }
  2273.     /** Hi Color **/
  2274.   if (scroll->hi)
  2275.   { XSetForeground(theDisp,remoteGC,button_hi);
  2276.     XSetClipMask(theDisp,remoteGC,scroll->hi);
  2277.     XFillRectangle(theDisp,remoteW,remoteGC,
  2278.                 (int)x,(int)y,(int)width,(int)height);
  2279.   }
  2280.   XSync(theDisp,False);
  2281. }
  2282.  
  2283. /* ret xaTRUE if in button
  2284.  *     xaFALSE if not
  2285.  */
  2286. static xaULONG InButtonQuery(button,x,y)
  2287. BUTTON *button;
  2288. int x,y;
  2289. { BUTTON_TYPE  *btype; if (button == 0) return(xaFALSE);
  2290.   if (button->type >= NUM_BUTTON_TYPES) return(xaFALSE);
  2291.   btype = &button_types[ button->type ];
  2292.   if ((x < button->xpos) || (y < button->ypos)) return(xaFALSE);
  2293.   if (x > (button->xpos + btype->width)) return(xaFALSE);
  2294.   if (y > (button->ypos + btype->height)) return(xaFALSE);
  2295. /*POD TODO: separate active region of button */
  2296.   return(xaTRUE);
  2297. }
  2298.  
  2299.  
  2300. static xaLONG WhichButton(buttons,num,x,y)
  2301. BUTTON *buttons;
  2302. xaULONG num;
  2303. int x,y;
  2304. { int i;
  2305.   for(i=0; i<num; i++) if (InButtonQuery(&buttons[i],x,y)==xaTRUE) return(i);
  2306.   return(-1);
  2307. }
  2308.  
  2309. static void AdjustScroll(sidx, val, scale)
  2310. xaULONG sidx;
  2311. xaULONG val, scale;
  2312. { SCROLLBAR *scroll; xaULONG pos;
  2313.   if (sidx >= NUM_SCROLLBARS) return;
  2314.   if (scale == 0) return; 
  2315.   scroll = &scrollbars[sidx];
  2316.   if (val > scale) val = scale; 
  2317.   pos = (val * scroll->length) / scale;
  2318.  
  2319.   if (scroll->type == 0) scroll->cur = (scroll->ypos + scroll->length) - pos;
  2320.   else             scroll->cur =  scroll->xpos + pos;
  2321.  
  2322. }
  2323.  
  2324.  
  2325. void XA_Remote_Play_Common(prev,stop,next)  
  2326. xaULONG prev,stop,next;
  2327. { buttons[BUTTON_PLAYPREV].state = prev;
  2328.   buttons[BUTTON_PLAYSTOP].state = stop;
  2329.   buttons[BUTTON_PLAYNEXT].state = next;
  2330.   DrawButton(&buttons[BUTTON_PLAYPREV]);
  2331.   DrawButton(&buttons[BUTTON_PLAYSTOP]);
  2332.   DrawButton(&buttons[BUTTON_PLAYNEXT]);
  2333. }
  2334.  
  2335. void XA_Remote_PlayPrev()  
  2336.  { XA_Remote_Play_Common(BUTTON_STATE_ON, BUTTON_STATE_OFF, BUTTON_STATE_OFF); }
  2337. void XA_Remote_PlayStop()  
  2338.  { XA_Remote_Play_Common(BUTTON_STATE_OFF, BUTTON_STATE_ON, BUTTON_STATE_OFF); }
  2339. void XA_Remote_PlayNext()  
  2340.  { XA_Remote_Play_Common(BUTTON_STATE_OFF, BUTTON_STATE_OFF, BUTTON_STATE_ON); }
  2341. void XA_Remote_StepPrev() { XA_Remote_PlayStop(); }
  2342. void XA_Remote_StepNext() { XA_Remote_PlayStop(); }
  2343.  
  2344. void XA_Remote_Pause()      { XA_Remote_PlayStop(); }
  2345.  
  2346. void XA_Remote_AudioOff()
  2347. { buttons[BUTTON_AUDIO].state = BUTTON_STATE_ON;
  2348.   DrawButton(&buttons[BUTTON_AUDIO]);
  2349. }
  2350. void XA_Remote_AudioOn()
  2351. { buttons[BUTTON_AUDIO].state = BUTTON_STATE_OFF;
  2352.   DrawButton(&buttons[BUTTON_AUDIO]);
  2353. }
  2354. void XA_Remote_SpeedNorm()
  2355. { buttons[BUTTON_SPEED].state = BUTTON_STATE_OFF;
  2356.   DrawButton(&buttons[BUTTON_SPEED]);
  2357. }
  2358. void XA_Remote_SpeedDiff()
  2359. { buttons[BUTTON_SPEED].state = BUTTON_STATE_ON;
  2360.   DrawButton(&buttons[BUTTON_SPEED]);
  2361. }
  2362. void XA_Remote_Adj_Volume(vol,maxvol)
  2363. xaULONG vol,maxvol;
  2364. { AdjustScroll(SCROLLBAR_VOLUME,vol,maxvol);
  2365.   DrawButton(&buttons[BUTTON_VOLBAR]);
  2366. }
  2367. void XA_Remote_ColorUpdate(chdr)
  2368. XA_CHDR *chdr;
  2369. {
  2370.   GetButtonColors(chdr);
  2371.   DrawRemote(buttons,NUM_BUTTONS);
  2372. }
  2373.  
  2374. void XA_Remote_Free()
  2375. { int i;
  2376.   for(i=0; i< NUM_BUTTON_TYPES; i++)
  2377.   { if (button_types[i].hi)
  2378.     { XFreePixmap(theDisp,button_types[i].hi); button_types[i].hi = 0; }
  2379.     if (button_types[i].lo)
  2380.     { XFreePixmap(theDisp,button_types[i].lo); button_types[i].lo = 0; }
  2381.   }
  2382.   for(i=0; i< NUM_BUTTONS; i++)
  2383.   { if (buttons[i].pmap)
  2384.     { XFreePixmap(theDisp,buttons[i].pmap); buttons[i].pmap = 0; }
  2385.   }
  2386.   for(i=0; i< NUM_SCROLLBARS; i++)
  2387.   { if (scrollbars[i].hi)
  2388.     { XFreePixmap(theDisp,scrollbars[i].hi); scrollbars[i].hi = 0; }
  2389.     if (scrollbars[i].lo)
  2390.     { XFreePixmap(theDisp,scrollbars[i].lo); scrollbars[i].lo = 0; }
  2391.   }
  2392. }
  2393.  
  2394.  
  2395. #else
  2396. #ifdef XA_REMOTE_CONTROL
  2397. /****************************************************************************
  2398.  *  XA_Create_Remote with non-portable, troublesome, silly Widgets.
  2399.  *  Schedules to be removed with haste.
  2400.  ****************************************************************************/
  2401. void xa_remote_expose();
  2402.  
  2403. #include "BM_step_prev.xbm"
  2404. #include "BM_play.xbm"
  2405. #include "BM_step_next.xbm"
  2406. #include "BM_next.xbm"
  2407. #include "BM_quit.xbm"
  2408. #include "BM_prev.xbm"
  2409. #include "BM_slower.xbm"
  2410. #include "BM_speed1.xbm"
  2411. #include "BM_faster.xbm"
  2412. #include "BM_vol_dn.xbm"
  2413. #include "BM_vol_off.xbm"
  2414. #include "BM_vol_up.xbm"
  2415. #include "BM_back.xbm"
  2416. #include "BM_stop.xbm"
  2417. #include "BM_vol_on.xbm"
  2418. #include "BM_fuzz.xbm"
  2419.  
  2420. #define BM_NUMBER 16
  2421. #define BM_STPP        0
  2422. #define BM_PLAY        1
  2423. #define BM_STPN        2
  2424. #define BM_NEXT        3
  2425. #define BM_QUIT        4
  2426. #define BM_PREV        5
  2427. #define BM_SLOW        6
  2428. #define BM_NORM        7
  2429. #define BM_FAST        8
  2430. #define BM_BACK        12
  2431. #define BM_STOP        13
  2432. #define BM_FUZZ        15
  2433.  
  2434. #ifdef XA_AUDIO
  2435. #define BM_VDOWN    9
  2436. #define BM_VOFF        10
  2437. #define BM_VUP        11
  2438. #define BM_VON         14
  2439. #else
  2440. #define BM_VDOWN    15
  2441. #define BM_VOFF        15
  2442. #define BM_VUP        15
  2443. #define BM_VON         15
  2444. #endif
  2445.  
  2446. static Pixmap BM_pmap[BM_NUMBER] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
  2447.  
  2448. static int BM_width[] 
  2449.         = {BM_step_prev_width,BM_play_width,BM_step_next_width,
  2450.         BM_next_width,BM_quit_width,BM_prev_width,BM_slower_width,
  2451.         BM_speed1_width,BM_faster_width,BM_vol_dn_width,
  2452.         BM_vol_off_width,BM_vol_up_width,BM_back_width,
  2453.         BM_stop_width,BM_vol_on_width,BM_fuzz_width};
  2454. static int BM_height[] 
  2455.         = {BM_step_prev_height,BM_play_height,BM_step_next_height,
  2456.         BM_next_height,BM_quit_height,BM_prev_height,BM_slower_height,
  2457.         BM_speed1_height,BM_faster_height,BM_vol_dn_height,
  2458.         BM_vol_off_height,BM_vol_up_height,BM_back_height,
  2459.         BM_stop_height,BM_vol_on_height,BM_fuzz_height};
  2460. static unsigned char *BM_bits[] 
  2461.         = {BM_step_prev_bits,BM_play_bits,BM_step_next_bits,
  2462.         BM_next_bits,BM_quit_bits,BM_prev_bits,BM_slower_bits,
  2463.         BM_speed1_bits,BM_faster_bits,BM_vol_dn_bits,
  2464.         BM_vol_off_bits,BM_vol_up_bits,BM_back_bits,
  2465.         BM_stop_bits,BM_vol_on_bits,BM_fuzz_bits};
  2466.  
  2467.  
  2468. /****** ATHENA DEFINES **********/
  2469. #ifdef XA_ATHENA
  2470. #define XA_FORM_CLASS    formWidgetClass
  2471. #define XA_BUTTON_CLASS    commandWidgetClass
  2472.  
  2473. #define XA_REMOTE_TOPFORM(arg,n)    {}
  2474. #define XA_REMOTE_BOTTOMFORM(arg,n) {}
  2475. #define XA_REMOTE_LEFTFORM(arg,n)   {}
  2476. #define XA_REMOTE_RIGHTFORM(arg,n)  {}
  2477. #define XA_REMOTE_TOPWIDGET(arg,n,the_w) {XtSetArg(arg[n],XtNfromVert,the_w); n++;}
  2478. #define XA_REMOTE_LEFTWIDGET(arg,n,the_w) {XtSetArg(arg[n],XtNfromHoriz,the_w); n++;}
  2479.  
  2480. #define XA_REMOTE_PIXMAP(arg,n,pixmap)    { \
  2481.  XtSetArg(arg[n],XtNbitmap, pixmap); n++; }
  2482.  
  2483. #endif  /******** END OF ATHENA **********/
  2484.  
  2485. /****** MOTIF DEFINES **********/
  2486. #ifdef XA_MOTIF
  2487. #define XA_FORM_CLASS    xmFormWidgetClass
  2488. #define XA_BUTTON_CLASS    xmPushButtonWidgetClass
  2489.  
  2490. #define XA_REMOTE_TOPFORM(arg,n)    {XtSetArg(arg[n],XmNtopAttachment,XmATTACH_FORM); n++;}
  2491. #define XA_REMOTE_BOTTOMFORM(arg,n) {XtSetArg(arg[n],XmNbottomAttachment,XmATTACH_FORM); n++;}
  2492. #define XA_REMOTE_LEFTFORM(arg,n)   {XtSetArg(arg[n],XmNleftAttachment,XmATTACH_FORM); n++;}
  2493. #define XA_REMOTE_RIGHTFORM(arg,n)  {XtSetArg(arg[n],XmNrightAttachment,XmATTACH_FORM); n++;}
  2494.  
  2495. #define XA_REMOTE_TOPWIDGET(arg,n,the_w)    { \
  2496.   XtSetArg(arg[n],XmNtopAttachment,XmATTACH_WIDGET); n++; \
  2497.   XtSetArg(arg[n],XmNtopWidget,the_w); n++;    }
  2498.  
  2499. #define XA_REMOTE_LEFTWIDGET(arg,n,the_w)    { \
  2500.   XtSetArg(arg[n],XmNleftAttachment,XmATTACH_WIDGET); n++; \
  2501.   XtSetArg(arg[n],XmNleftWidget,the_w); n++;    }
  2502.  
  2503. #define XA_REMOTE_PIXMAP(arg,n,pixmap)    { \
  2504.  XtSetArg(arg[n],XmNlabelPixmap, pixmap); n++; \
  2505.  XtSetArg(arg[n],XmNlabelType,XmPIXMAP); n++;    }
  2506. #endif  /******** END OF MOTIF **********/
  2507.  
  2508.  
  2509. void XA_Create_Remote(wg,remote_flag)
  2510. Widget wg;
  2511. xaLONG remote_flag;
  2512. { int i,n,nb,nc,foregnd,backgnd;
  2513.   Widget form,w,oldw;
  2514.   Arg arglist[20];
  2515.   Window t_window;
  2516.  
  2517. /* Query Black and White */
  2518.   if (x11_display_type == XA_MONOCHROME)
  2519.   { foregnd = WhitePixel(theDisp,theScreen);
  2520.     backgnd = BlackPixel(theDisp,theScreen);
  2521.   }
  2522.   else if (x11_display_type & XA_X11_TRUE)
  2523.   { backgnd = X11_Get_True_Color(0,0,0,8);
  2524.     foregnd = X11_Get_True_Color(255,255,255,8);
  2525.   }
  2526.   else if (xa_chdr_first)
  2527.   { XA_CHDR *chdr = xa_chdr_first;
  2528.    backgnd = CMAP_Find_Closest(chdr->cmap,chdr->csize,0,0,0,8,8,8,xaTRUE);
  2529.    foregnd = CMAP_Find_Closest(chdr->cmap,chdr->csize,255,255,255,8,8,8,xaTRUE);
  2530.    i = 2;
  2531.   }
  2532.   else
  2533.   { foregnd = WhitePixel(theDisp,theScreen);
  2534.     backgnd = BlackPixel(theDisp,theScreen);
  2535.   }
  2536.  
  2537.  if (x11_verbose_flag == xaTRUE)
  2538.     fprintf(stderr,"foregnd = %x backgnd = %x\n",foregnd,backgnd);
  2539.  
  2540.  for(i=0; i < BM_NUMBER; i++)
  2541.  {
  2542.    BM_pmap[i] = XCreatePixmapFromBitmapData(theDisp,mainW,(char *)(BM_bits[i]),
  2543.             BM_width[i],BM_height[i],foregnd,backgnd,x11_depth);
  2544.  }
  2545.  
  2546.  
  2547.  
  2548.   nb = 0;
  2549. #ifdef XtNvisual
  2550.   XtSetArg(arglist[nb], XtNvisual, theVisual); nb++;
  2551. #endif
  2552.   XtSetArg(arglist[nb], XtNcolormap, theCmap); nb++;
  2553.   XtSetArg(arglist[nb], XtNdepth, x11_depth); nb++;
  2554.   XtSetArg(arglist[nb], XtNforeground, foregnd); nb++;
  2555.   XtSetArg(arglist[nb], XtNbackground, backgnd); nb++;
  2556.   XtSetArg(arglist[nb], XtNborderColor, foregnd); nb++;
  2557.   XtSetArg(arglist[nb], XtNx, XA_REMW_XPOS); nb++;
  2558.   XtSetArg(arglist[nb], XtNy, XA_REMW_YPOS); nb++;
  2559.  
  2560.   XtSetArg(arglist[nb], XtNtranslations,
  2561.                         XtParseTranslationTable(Translation)); nb++;
  2562.  
  2563.   remote_widget = XtCreatePopupShell("Control",topLevelShellWidgetClass,wg,arglist,nb);
  2564.   form = XtCreateManagedWidget("form",XA_FORM_CLASS,remote_widget,arglist,nb);
  2565.  
  2566.   t_window = mainW;
  2567.   /************* TOP ROW: ***/
  2568.   nc = nb; w = XtCreateManagedWidget("stepPrevButton",XA_BUTTON_CLASS, form,NULL,0);
  2569.   XA_REMOTE_TOPFORM(arglist,nc);
  2570.   n = nc;
  2571.   XA_REMOTE_LEFTFORM(arglist,n);
  2572.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_STPP]);
  2573.   XtSetValues(w,arglist,n); oldw = w;
  2574.   XtOverrideTranslations(w, 
  2575.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: StepPrev()"));
  2576.  
  2577.   n = nc; play_widget = XtCreateManagedWidget("toggleButton",XA_BUTTON_CLASS,form,NULL,0);
  2578.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2579.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_STOP]);
  2580.   XtSetValues(play_widget,arglist,n); oldw = play_widget;
  2581.   XtOverrideTranslations(play_widget, 
  2582.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: RunStop()"));
  2583.  
  2584.   n = nc; w = XtCreateManagedWidget("stepNextButton",XA_BUTTON_CLASS,form,NULL,0);
  2585.   XA_REMOTE_RIGHTFORM(arglist,n);
  2586.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2587.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_STPN]);
  2588.   XtSetValues(w,arglist,n); oldw = w;
  2589.   XtOverrideTranslations(w, 
  2590.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: StepNext()"));
  2591.   /************** MIDDLE ROW: **********/
  2592.   nc = nb; w = XtCreateManagedWidget("prevAnimButton",XA_BUTTON_CLASS,form,NULL,0);
  2593.   XA_REMOTE_TOPWIDGET(arglist,nc,oldw);
  2594.   n = nc;
  2595.   XA_REMOTE_LEFTFORM(arglist,n);
  2596.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_PREV]);
  2597.   XtSetValues(w,arglist,n); oldw = w;
  2598.   XtOverrideTranslations(w, 
  2599.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: PrevAnim()"));
  2600.  
  2601.   n = nc; w = XtCreateManagedWidget("quitButton",XA_BUTTON_CLASS,form,NULL,0);
  2602.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2603.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_QUIT]);
  2604.   XtSetValues(w,arglist,n); oldw = w;
  2605.   XtOverrideTranslations(w, 
  2606.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: Quit()"));
  2607.  
  2608.   n = nc; w = XtCreateManagedWidget("nextAnimButton",XA_BUTTON_CLASS,form,NULL,0);
  2609.   XA_REMOTE_RIGHTFORM(arglist,n);
  2610.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2611.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_NEXT]);
  2612.   XtSetValues(w,arglist,n); oldw = w;
  2613.   XtOverrideTranslations(w, 
  2614.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: NextAnim()"));
  2615.   /*************** BOTTOM ROW: ********/
  2616.   nc = nb; w = XtCreateManagedWidget("slowerButton",XA_BUTTON_CLASS,form,NULL,0);
  2617.   XA_REMOTE_TOPWIDGET(arglist,nc,oldw);
  2618.   n = nc;
  2619.   XA_REMOTE_LEFTFORM(arglist,n);
  2620.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_SLOW]);
  2621.   XtSetValues(w,arglist,n); oldw = w;
  2622.   XtOverrideTranslations(w, 
  2623.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: Slower()"));
  2624.  
  2625.   n = nc; norm_widget = XtCreateManagedWidget("speedResetButton",XA_BUTTON_CLASS,form,NULL,0);
  2626.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2627.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_FUZZ]);
  2628.   XtSetValues(norm_widget,arglist,n); oldw = norm_widget;
  2629.   XtOverrideTranslations(norm_widget, 
  2630.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: SpeedReset()"));
  2631.  
  2632.   n = nc; w = XtCreateManagedWidget("fasterButton",XA_BUTTON_CLASS,form,NULL,0);
  2633.   XA_REMOTE_RIGHTFORM(arglist,n);
  2634.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2635.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_FAST]);
  2636.   XtSetValues(w,arglist,n); oldw = w;
  2637.   XtOverrideTranslations(w, 
  2638.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: Faster()"));
  2639.   /********* AUDIO VERY BOTTOM ROW: ****/
  2640.   nc = nb; w = XtCreateManagedWidget("decAudioButton",XA_BUTTON_CLASS,form,NULL,0);
  2641.   XA_REMOTE_TOPWIDGET(arglist,nc,oldw);
  2642.   XA_REMOTE_BOTTOMFORM(arglist,nc);
  2643.   n = nc;
  2644.   XA_REMOTE_LEFTFORM(arglist,n);
  2645.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_VDOWN]);
  2646.   XtSetValues(w,arglist,n); oldw = w;
  2647.   XtOverrideTranslations(w, 
  2648.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: DecAudio5()"));
  2649.  
  2650.   n = nc; audio_widget = XtCreateManagedWidget("audioMuteButton",XA_BUTTON_CLASS,form,NULL,0);
  2651.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2652.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_VOFF]);
  2653.   XtSetValues(audio_widget,arglist,n); oldw = audio_widget;
  2654.   XtOverrideTranslations(audio_widget, 
  2655.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: AudioMute()"));
  2656.  
  2657.   n = nc; last_widget = XtCreateManagedWidget("incAudioButton",XA_BUTTON_CLASS,form,NULL,0);
  2658.   XA_REMOTE_RIGHTFORM(arglist,n);
  2659.   XA_REMOTE_LEFTWIDGET(arglist,n,oldw);
  2660.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[BM_VUP]);
  2661.   XtSetValues(last_widget,arglist,n); oldw = last_widget;
  2662.   XtOverrideTranslations(last_widget, 
  2663.         XtParseTranslationTable("<Btn1Down>,<Btn1Up>: IncAudio5()"));
  2664.  
  2665.  
  2666.  
  2667.   /* THIS IS VERY IMPORTANT AND IS TO DELAY STARTUP UNTIL AN EXPOSE EVENT
  2668.    * HAPPENS so everything is realized and mapped before animation starts.
  2669.    * xa_remote_ready is set to xaTRUE in the xa_remote_expose routine.
  2670.    */
  2671.   XtAddRawEventHandler(last_widget, ExposureMask, False, xa_remote_expose, NULL);
  2672.   /******** REALIZE THE WIDGET *******/
  2673.   if (remote_flag == xaTRUE) XA_Realize_Remote(remote_widget);
  2674.   else xa_remote_ready = xaTRUE;
  2675. }
  2676.  
  2677. void XA_Realize_Remote(remote)
  2678. Widget remote;
  2679. {
  2680.   xa_remote_realized = xaTRUE;
  2681.   XtPopup(remote,XtGrabNone);
  2682.   XSync(theDisp,False);
  2683.   while(XtIsRealized(remote)==False) XSync(theDisp,False);
  2684.   while(XtIsRealized(last_widget)==False) XSync(theDisp,False);
  2685.   XRaiseWindow(theDisp, XtWindow(remote) );
  2686. }
  2687.  
  2688. void XA_Unrealize_Remote(remote)
  2689. Widget remote;
  2690. {
  2691.   XSync(theDisp,False);
  2692.   XtPopdown(remote);
  2693.   XSync(theDisp,False);
  2694.   XtUnrealizeWidget(remote);
  2695.   XSync(theDisp,False);
  2696.   while(XtIsRealized(remote)==True) XSync(theDisp,False);
  2697.   xa_remote_realized = xaFALSE;
  2698. }
  2699.  
  2700. /* Change pixmap of a button */
  2701. void XA_Remote_Change(widg,button)
  2702. Widget widg;
  2703. int button;
  2704. { Arg arglist[5];
  2705.   int n = 0;
  2706.   XA_REMOTE_PIXMAP(arglist,n,BM_pmap[button]);
  2707.   XtSetValues(widg,arglist,n);
  2708. }
  2709.  
  2710. /* Event Handler */
  2711. void xa_remote_expose(wg, closure, event, notused)
  2712. Widget          wg;        XtPointer    closure;
  2713. XEvent        *event;        Boolean        *notused;
  2714. { xa_remote_ready = xaTRUE;
  2715. }
  2716.  
  2717. /* convenience function so xanim.c code can change play button during
  2718.  * pauses. */
  2719. void XA_Remote_Pause()       { XA_Remote_Change(play_widget,BM_PLAY); }
  2720. void XA_Remote_PlayNext()  { XA_Remote_Change(play_widget,BM_PLAY); }
  2721. void XA_Remote_PlayPrev()  { XA_Remote_Change(play_widget,BM_BACK); }
  2722. void XA_Remote_PlayStop()  { XA_Remote_Change(play_widget,BM_STOP); }
  2723. void XA_Remote_StepNext()  { XA_Remote_Change(play_widget,BM_PLAY); }
  2724. void XA_Remote_StepPrev()  { XA_Remote_Change(play_widget,BM_BACK); }
  2725. void XA_Remote_AudioOff()  { XA_Remote_Change(audio_widget,BM_VOFF);}
  2726. void XA_Remote_AudioOn()   { XA_Remote_Change(audio_widget,BM_VON); }
  2727. void XA_Remote_SpeedNorm() { XA_Remote_Change(norm_widget,BM_NORM); }
  2728. void XA_Remote_SpeedDiff() { XA_Remote_Change(norm_widget,BM_FUZZ); }
  2729. void XA_Remote_Adj_Volume(vol,maxvol)
  2730. xaULONG vol,maxvol;
  2731. { xaULONG i = vol * maxvol; /* do nothing */
  2732. }
  2733.  
  2734. void XA_Remote_Free()
  2735. { int i;
  2736.  for(i=0; i < BM_NUMBER; i++) 
  2737.    if (BM_pmap[i]) { XFreePixmap(theDisp,BM_pmap[i]); BM_pmap[i] = 0; }
  2738. }
  2739.  
  2740. #endif
  2741. #endif
  2742.  
  2743. void XA_Free_CMAP()
  2744. {
  2745.   if (theCmap && (theCmap != DefaultColormap(theDisp,theScreen)) )
  2746.             { XFreeColormap(theDisp, theCmap); theCmap = 0; }
  2747. }
  2748.