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