1 /*
2 
3     Canvas.c - a widget that allows programmer-specified refresh procedures.
4     Copyright (C) 1990,93,94 Robert H. Forsman Jr.
5 
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10 
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15 
16     You should have received a copy of the GNU Library General Public
17     License along with this library; if not, write to the Free
18     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <fc_config.h>
24 #endif
25 
26 #include <stdio.h>
27 
28 #include <X11/IntrinsicP.h>
29 #include <X11/StringDefs.h>
30 #include <X11/Xaw/XawInit.h>
31 
32 #include "gui_main.h"
33 #include "gui_stuff.h"
34 #include "canvasp.h"
35 
36 #define offset(field) XtOffset(CanvasWidget, canvas.field)
37 
38 static XtResource resources[] = {
39   {XtNexposeProc, XtCExposeProc, XtRFunction, sizeof(XfwfCanvasExposeProc),
40      offset(redraw),	XtRFunction, NULL},
41   {XtNexposeProcData, XtCExposeProcData, XtRPointer, sizeof(XtPointer),
42      offset(redraw_data), XtRFunction, NULL},
43   {XtNresizeProc, XtCResizeProc, XtRFunction, sizeof(XfwfCanvasResizeProc),
44      offset(resize),	XtRFunction, NULL},
45   {XtNresizeProcData, XtCResizeProcData, XtRPointer, sizeof(XtPointer),
46      offset(resize_data), XtRFunction, NULL},
47   {XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*),
48       offset(visual), XtRImmediate, CopyFromParent},
49   {XtNBackPixmap, XtCBackPixmap, XtRBitmap, sizeof(Pixmap),
50      offset(pixmap), XtRBitmap, NULL}
51 };
52 
53 
54 static void CanvasRealize(Widget widget, XtValueMask *value_mask,
55 			  XSetWindowAttributes *attributes);
56 static void Redisplay(Widget w, XEvent *event, Region region);
57 static void ClassInitialize(void);
58 static void Resize(Widget w);
59 static void Destroy(Widget w);
60 static Boolean SetValues(Widget current,
61 			 Widget request,
62 			 Widget New,
63 			 ArgList args, Cardinal *nargs);
64 
65 CanvasClassRec canvasClassRec = {
66     {
67     /* core_class fields	 */
68     /* superclass	  	 */ (WidgetClass) &simpleClassRec,
69     /* class_name	  	 */ "Canvas",
70     /* widget_size	  	 */ sizeof(CanvasRec),
71     /* class_initialize   	 */ ClassInitialize,
72     /* class_part_initialize	 */ NULL,
73     /* class_inited       	 */ False,
74     /* initialize	  	 */ NULL,
75     /* initialize_hook		 */ NULL,
76     /* realize		  	 */ CanvasRealize,
77     /* actions		  	 */ NULL,
78     /* num_actions	  	 */ 0,
79     /* resources	  	 */ resources,
80     /* num_resources	  	 */ XtNumber(resources),
81     /* xrm_class	  	 */ NULLQUARK,
82     /* compress_motion	  	 */ True,
83     /* compress_exposure  	 */ XtExposeCompressMultiple,
84     /* compress_enterleave	 */ True,
85     /* visible_interest	  	 */ True,
86     /* destroy		  	 */ Destroy,
87     /* resize		  	 */ Resize,
88     /* expose		  	 */ Redisplay,
89     /* set_values	  	 */ SetValues,
90     /* set_values_hook		 */ NULL,
91     /* set_values_almost	 */ XtInheritSetValuesAlmost,
92     /* get_values_hook		 */ NULL,
93     /* accept_focus	 	 */ NULL,
94     /* version			 */ XtVersion,
95     /* callback_private   	 */ NULL,
96     /* tm_table		   	 */ NULL,
97     /* query_geometry		 */ NULL,
98     /* display_accelerator       */ XtInheritDisplayAccelerator,
99     /* extension                 */ NULL
100     },
101     {
102       XtInheritChangeSensitive            /* change_sensitive       */
103     },  /* SimpleClass fields initialization */
104     {
105       0 /* some stupid compilers barf on empty structures */
106     },
107 };
108 
109 WidgetClass xfwfcanvasWidgetClass = (WidgetClass) & canvasClassRec;
110 
111 
CanvasRealize(Widget widget,XtValueMask * value_mask,XSetWindowAttributes * attributes)112 static void CanvasRealize(Widget widget, XtValueMask *value_mask,
113 			  XSetWindowAttributes *attributes)
114 {
115   CanvasWidget	cw = (CanvasWidget)widget;
116   cw->canvas.is_visible=0;
117 
118   XtCreateWindow(widget, (unsigned int) InputOutput,
119 	(Visual *) cw->canvas.visual, *value_mask, attributes);
120 
121   cw->canvas.pixmap=XCreatePixmap(display, root_window,
122 				  cw->core.width, cw->core.height,
123 				  display_depth);
124 
125 } /* CoreRealize */
126 
Redisplay(Widget w,XEvent * event,Region region)127 static void Redisplay(Widget w, XEvent *event, Region region)
128 {
129   XExposeEvent *exposeEvent = (XExposeEvent *)event;
130   CanvasWidget	cw = (CanvasWidget)w;
131 
132   if (!XtIsRealized(w))
133     return;
134 
135   if(cw->canvas.redraw) {
136     (cw->canvas.redraw)((Widget)cw,exposeEvent,region,cw->canvas.redraw_data);
137   }
138   else {
139     if(cw->canvas.is_visible)
140       XCopyArea(display, cw->canvas.pixmap, XtWindow(w),
141 		civ_gc,
142 		0, 0,
143 		cw->core.width, cw->core.height,
144 		0, 0);
145     else {
146       XSetForeground(display, fill_bg_gc, cw->core.background_pixel);
147       XFillRectangle(display, XtWindow(w), fill_bg_gc,
148 		     0, 0, cw->core.width, cw->core.height);
149     }
150   }
151 }
152 
SetValues(Widget current,Widget request,Widget New,ArgList args,Cardinal * nargs)153 static Boolean SetValues(Widget current,
154 			 Widget request,
155 			 Widget New,
156 			 ArgList args, Cardinal *nargs)
157 {
158   int	i;
159   for(i=0; i<*nargs; i++) {
160     if (strcmp(XtNexposeProc,args[i].name)==0 ||
161 	strcmp(XtNexposeProcData,args[i].name)==0)
162       return True;
163   }
164   return False;
165 }
166 
167 
Resize(Widget w)168 static void Resize(Widget w)
169 {
170   CanvasWidget cw = (CanvasWidget)w;
171   if (cw->canvas.resize)
172     (cw->canvas.resize)((Widget)cw, cw->canvas.resize_data);
173 
174   XFreePixmap(display, cw->canvas.pixmap);
175 
176   cw->canvas.pixmap=XCreatePixmap(display, root_window,
177 				  cw->core.width, cw->core.height,
178 				  display_depth);
179 }
180 
Destroy(Widget w)181 static void Destroy(Widget w)
182 {
183   CanvasWidget	cw = (CanvasWidget)w;
184   XFreePixmap(display, cw->canvas.pixmap);
185 }
186 
ClassInitialize(void)187 static void ClassInitialize(void)
188 {
189     XawInitializeWidgetSet();
190 }
191 
192 
canvas_get_backpixmap(Widget w)193 Pixmap canvas_get_backpixmap(Widget w)
194 {
195   CanvasWidget	cw = (CanvasWidget)w;
196   return XtIsRealized(w) ? cw->canvas.pixmap : 0;
197 }
198 
canvas_copy_to_backpixmap(Widget w,Pixmap src)199 void canvas_copy_to_backpixmap(Widget w, Pixmap src)
200 {
201   CanvasWidget cw = (CanvasWidget)w;
202 
203   XCopyArea(display, src, cw->canvas.pixmap,
204 	    civ_gc,
205 	    0, 0,
206 	    cw->core.width, cw->core.height,
207 	    0, 0);
208   cw->canvas.is_visible=1;
209   xaw_expose_now(w);
210 }
211 
212 
canvas_show(Widget w)213 void canvas_show(Widget w)
214 {
215   CanvasWidget	cw = (CanvasWidget)w;
216   cw->canvas.is_visible=1;
217   xaw_expose_now(w);
218 }
219 
canvas_hide(Widget w)220 void canvas_hide(Widget w)
221 {
222   CanvasWidget	cw = (CanvasWidget)w;
223   cw->canvas.is_visible=0;
224   xaw_expose_now(w);
225 }
226