1 /*  NAME:
2         E3UnixDrawContext.c
3 
4     DESCRIPTION:
5         Unix specific Draw Context calls.
6 
7     COPYRIGHT:
8         Copyright (c) 1999-2005, Quesa Developers. All rights reserved.
9 
10         For the current release of Quesa, please see:
11 
12             <http://www.quesa.org/>
13 
14         Redistribution and use in source and binary forms, with or without
15         modification, are permitted provided that the following conditions
16         are met:
17 
18             o Redistributions of source code must retain the above copyright
19               notice, this list of conditions and the following disclaimer.
20 
21             o Redistributions in binary form must reproduce the above
22               copyright notice, this list of conditions and the following
23               disclaimer in the documentation and/or other materials provided
24               with the distribution.
25 
26             o Neither the name of Quesa nor the names of its contributors
27               may be used to endorse or promote products derived from this
28               software without specific prior written permission.
29 
30         THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31         "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32         LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33         A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34         OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35         SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
36         TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
37         PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
38         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
39         NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40         SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41     ___________________________________________________________________________
42 */
43 //=============================================================================
44 //      Include files
45 //-----------------------------------------------------------------------------
46 #include "E3Prefix.h"
47 #include "E3DrawContext.h"
48 
49 
50 
51 
52 
53 //=============================================================================
54 //      Internal types
55 //-----------------------------------------------------------------------------
56 
57 
58 
59 class E3XDrawContext : public E3DrawContext  // This is a leaf class so no other classes use this,
60 								// so it can be here in the .c file rather than in
61 								// the .h file, hence all the fields can be public
62 								// as nobody should be including this file
63 	{
64 public :
65 
66 	TQ3DrawContextUnionData				instanceData ;
67 	} ;
68 
69 
70 
71 //=============================================================================
72 //      Internal functions
73 //-----------------------------------------------------------------------------
74 //      e3drawcontext_x_new : X11 draw context new method.
75 //-----------------------------------------------------------------------------
76 static TQ3Status
e3drawcontext_x_new(TQ3Object theObject,void * privateData,const void * paramData)77 e3drawcontext_x_new(TQ3Object theObject, void *privateData, const void *paramData)
78 {	TQ3DrawContextUnionData			*instanceData = (TQ3DrawContextUnionData *) privateData;
79 	const TQ3XDrawContextData		*x11Data      = (const TQ3XDrawContextData *) paramData;
80 
81 
82 
83 	// Initialise our instance data
84 	instanceData->data.x11Data.theData = *x11Data;
85 
86 	E3DrawContext_InitaliseData(&instanceData->data.x11Data.theData.contextData);
87 
88 	return(kQ3Success);
89 }
90 
91 
92 
93 
94 
95 //=============================================================================
96 //      e3drawcontext_x_get_dimensions : X11 draw context dimensions.
97 //-----------------------------------------------------------------------------
98 static void
e3drawcontext_x_get_dimensions(TQ3DrawContextObject theDrawContext,TQ3Area * thePane)99 e3drawcontext_x_get_dimensions(TQ3DrawContextObject theDrawContext, TQ3Area *thePane)
100 {
101 	// Return our dimensions (not currently implemented on X11)
102 	thePane->min.x = 0.0f;
103 	thePane->min.y = 0.0f;
104 	thePane->max.x = 0.0f;
105 	thePane->max.y = 0.0f;
106 }
107 
108 
109 
110 
111 
112 //=============================================================================
113 //      e3drawcontext_x_metahandler : X11 draw context metahandler.
114 //-----------------------------------------------------------------------------
115 static TQ3XFunctionPointer
e3drawcontext_x_metahandler(TQ3XMethodType methodType)116 e3drawcontext_x_metahandler(TQ3XMethodType methodType)
117 {	TQ3XFunctionPointer		theMethod = NULL;
118 
119 
120 
121 	// Return our methods
122 	switch (methodType) {
123 		case kQ3XMethodTypeObjectNew:
124 			theMethod = (TQ3XFunctionPointer) e3drawcontext_x_new;
125 			break;
126 
127 		case kQ3XMethodTypeDrawContextGetDimensions:
128 			theMethod = (TQ3XFunctionPointer) e3drawcontext_x_get_dimensions;
129 			break;
130 		}
131 
132 	return(theMethod);
133 }
134 
135 
136 
137 
138 
139 //=============================================================================
140 //      Public functions
141 //-----------------------------------------------------------------------------
142 //      E3XDrawContext_RegisterClass : Register the class.
143 //-----------------------------------------------------------------------------
144 TQ3Status
E3XDrawContext_RegisterClass(void)145 E3XDrawContext_RegisterClass(void)
146 {	TQ3Status		qd3dStatus;
147 
148 
149 
150 	// Register the class
151 	qd3dStatus = E3ClassTree::RegisterClass(kQ3SharedTypeDrawContext,
152 											kQ3DrawContextTypeX11,
153 											kQ3ClassNameDrawContextX11,
154 											e3drawcontext_x_metahandler,
155 											sizeof(E3XDrawContext));
156 
157 	return(qd3dStatus);
158 }
159 
160 
161 
162 
163 
164 //=============================================================================
165 //      E3XDrawContext_UnregisterClass : Unregister the class.
166 //-----------------------------------------------------------------------------
167 TQ3Status
E3XDrawContext_UnregisterClass(void)168 E3XDrawContext_UnregisterClass(void)
169 {	TQ3Status		qd3dStatus;
170 
171 
172 
173 	// Unregister the classes
174 	qd3dStatus = E3ClassTree::UnregisterClass(kQ3DrawContextTypeX11, kQ3True);
175 
176 	return(qd3dStatus);
177 }
178 
179 
180 
181 
182 
183 //=============================================================================
184 //      E3MacDrawContext_New : Create a new X11 draw context.
185 //-----------------------------------------------------------------------------
186 TQ3DrawContextObject
E3XDrawContext_New(const TQ3XDrawContextData * drawContextData)187 E3XDrawContext_New(const TQ3XDrawContextData *drawContextData)
188 {	TQ3Object		theObject;
189 
190 
191 
192 	// Create the object
193 	theObject = E3ClassTree::CreateInstance(kQ3DrawContextTypeX11, kQ3False, drawContextData);
194 
195 	return(theObject);
196 }
197 
198 
199 
200 
201 
202 //=============================================================================
203 //      E3XDrawContext_NewWithWindow : Create a new X11 Draw Context object.
204 //-----------------------------------------------------------------------------
205 TQ3DrawContextObject
E3XDrawContext_NewWithWindow(TQ3ObjectType drawContextType,void * drawContextTarget)206 E3XDrawContext_NewWithWindow(TQ3ObjectType drawContextType, void *drawContextTarget)
207 {	TQ3XDrawContextData		x11DrawContextData;
208 	TQ3DrawContextData		drawContextData;
209 	TQ3DrawContextObject	drawContext;
210 
211 
212 
213 	// Check we have a suitable target for the draw context
214 	if (drawContextType != kQ3DrawContextTypeX11)
215 		return(NULL);
216 
217 
218 
219 	// Prepare the draw context
220 	Q3ColorARGB_Set(&drawContextData.clearImageColor, kQ3DrawContextDefaultBackgroundColour);
221 
222 	drawContextData.clearImageMethod  = kQ3ClearMethodWithColor;
223 	drawContextData.paneState         = kQ3False;
224 	drawContextData.maskState		  = kQ3False;
225 	drawContextData.doubleBufferState = kQ3True;
226 	drawContextData.pane.min.x        = 0.0f;
227 	drawContextData.pane.min.y        = 0.0f;
228 	drawContextData.pane.max.x        = 0.0f;
229 	drawContextData.pane.max.y        = 0.0f;
230 
231 	Q3Memory_Clear(&x11DrawContextData, sizeof(x11DrawContextData));
232 	x11DrawContextData.contextData  = drawContextData;
233 	x11DrawContextData.visual       = (Visual *) drawContextTarget;
234 
235 
236 
237 	// Create the draw context
238 	drawContext = Q3XDrawContext_New(&x11DrawContextData);
239 
240 	return(drawContext);
241 }
242 
243 
244 
245 
246 
247 //=============================================================================
248 //      E3XDrawContext_SetDisplay : Set the display for an X11 draw context.
249 //-----------------------------------------------------------------------------
250 TQ3Status
E3XDrawContext_SetDisplay(TQ3DrawContextObject drawContext,const Display * display)251 E3XDrawContext_SetDisplay(TQ3DrawContextObject drawContext, const Display *display)
252 	{
253 	// Set the field and reset our flag. We don't compare the current
254 	// state, and assume that setting a new display may cause a rebuild.
255 	( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.display = (Display *) display;
256 	( (E3XDrawContext*) drawContext )->instanceData.theState                    |= kQ3XDrawContextValidationAll;
257 	Q3Shared_Edited(drawContext);
258 
259 	return(kQ3Success);
260 	}
261 
262 
263 
264 
265 
266 //=============================================================================
267 //      E3XDrawContext_GetDisplay : Get the display for an X11 draw context.
268 //-----------------------------------------------------------------------------
269 TQ3Status
E3XDrawContext_GetDisplay(TQ3DrawContextObject drawContext,Display ** display)270 E3XDrawContext_GetDisplay(TQ3DrawContextObject drawContext, Display **display)
271 	{
272 	// Get the field
273 	*display = ( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.display;
274 
275 	return(kQ3Success);
276 	}
277 
278 
279 
280 
281 
282 //=============================================================================
283 //      E3XDrawContext_SetDrawable : Set the drawable for an X11 draw context.
284 //-----------------------------------------------------------------------------
285 TQ3Status
E3XDrawContext_SetDrawable(TQ3DrawContextObject drawContext,Drawable drawable)286 E3XDrawContext_SetDrawable(TQ3DrawContextObject drawContext, Drawable drawable)
287 	{
288 	// Set the field and reset our flag
289 	if (( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.drawable != drawable)
290 		{
291 		( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.drawable = drawable;
292 		( (E3XDrawContext*) drawContext )->instanceData.theState                     |= kQ3XDrawContextValidationAll;
293 		Q3Shared_Edited(drawContext);
294 		}
295 
296 	return(kQ3Success);
297 	}
298 
299 
300 
301 
302 
303 //=============================================================================
304 //      E3XDrawContext_GetDrawable : Get the drawable for an X11 draw context.
305 //-----------------------------------------------------------------------------
306 TQ3Status
E3XDrawContext_GetDrawable(TQ3DrawContextObject drawContext,Drawable * drawable)307 E3XDrawContext_GetDrawable(TQ3DrawContextObject drawContext, Drawable *drawable)
308 	{
309 	// Get the field
310 	*drawable = ( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.drawable;
311 
312 	return(kQ3Success);
313 	}
314 
315 
316 
317 
318 
319 //=============================================================================
320 //      E3XDrawContext_SetVisual : Set the visual for an X11 draw context.
321 //-----------------------------------------------------------------------------
322 TQ3Status
E3XDrawContext_SetVisual(TQ3DrawContextObject drawContext,const Visual * visual)323 E3XDrawContext_SetVisual(TQ3DrawContextObject drawContext, const Visual *visual)
324 	{
325 	// Set the field and reset our flag. We don't compare the current
326 	// state, and assume that setting a new visual may cause a rebuild.
327 	( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.visual = (Visual *) visual;
328 	( (E3XDrawContext*) drawContext )->instanceData.theState                   |= kQ3XDrawContextValidationAll;
329 	Q3Shared_Edited(drawContext);
330 
331 	return(kQ3Success);
332 	}
333 
334 
335 
336 
337 
338 //=============================================================================
339 //      E3XDrawContext_GetVisual : Get the visual for an X11 draw context.
340 //-----------------------------------------------------------------------------
341 TQ3Status
E3XDrawContext_GetVisual(TQ3DrawContextObject drawContext,Visual ** visual)342 E3XDrawContext_GetVisual(TQ3DrawContextObject drawContext, Visual **visual)
343 	{
344 	// Get the field
345 	*visual = ( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.visual;
346 
347 	return(kQ3Success);
348 	}
349 
350 
351 
352 
353 
354 //=============================================================================
355 //      E3XDrawContext_SetColormap : Set the color map for an X11 draw context.
356 //-----------------------------------------------------------------------------
357 TQ3Status
E3XDrawContext_SetColormap(TQ3DrawContextObject drawContext,Colormap colormap)358 E3XDrawContext_SetColormap(TQ3DrawContextObject drawContext, Colormap colormap)
359 	{
360 	// Set the field and reset our flag. We don't compare the current
361 	// state, and assume that setting a new colormap may cause a rebuild.
362 	( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.cmap = colormap;
363 	( (E3XDrawContext*) drawContext )->instanceData.theState                 |= kQ3XDrawContextValidationAll;
364 	Q3Shared_Edited(drawContext);
365 
366 	return(kQ3Success);
367 	}
368 
369 
370 
371 
372 
373 //=============================================================================
374 //      E3XDrawContext_GetColormap : Get the color map for an X11 draw context.
375 //-----------------------------------------------------------------------------
376 TQ3Status
E3XDrawContext_GetColormap(TQ3DrawContextObject drawContext,Colormap * colormap)377 E3XDrawContext_GetColormap(TQ3DrawContextObject drawContext, Colormap *colormap)
378 	{
379 	// Get the field
380 	*colormap = ( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.cmap;
381 
382 	return(kQ3Success);
383 	}
384 
385 
386 
387 
388 
389 //=============================================================================
390 //      E3XDrawContext_SetColormapData : Set the colour map data.
391 //-----------------------------------------------------------------------------
392 TQ3Status
E3XDrawContext_SetColormapData(TQ3DrawContextObject drawContext,const TQ3XColormapData * colormapData)393 E3XDrawContext_SetColormapData(TQ3DrawContextObject drawContext, const TQ3XColormapData *colormapData)
394 	{
395 	// Set the field and reset our flag. We don't compare the current
396 	// state, and assume that setting a new colormap may cause a rebuild.
397 	( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.colorMapData = (TQ3XColormapData *) colormapData;
398 	( (E3XDrawContext*) drawContext )->instanceData.theState                         |= kQ3XDrawContextValidationAll;
399 	Q3Shared_Edited(drawContext);
400 
401 	return(kQ3Success);
402 	}
403 
404 
405 
406 
407 
408 //=============================================================================
409 //      E3XDrawContext_GetColormapData : Get the colour map data.
410 //-----------------------------------------------------------------------------
411 TQ3Status
E3XDrawContext_GetColormapData(TQ3DrawContextObject drawContext,TQ3XColormapData * colormapData)412 E3XDrawContext_GetColormapData(TQ3DrawContextObject drawContext, TQ3XColormapData *colormapData)
413 	{
414 	// Get the field
415 	Q3Memory_Copy(( (E3XDrawContext*) drawContext )->instanceData.data.x11Data.theData.colorMapData, colormapData, sizeof(TQ3XColormapData));
416 
417 	return(kQ3Success);
418 	}
419 
420 
421 
422 
423 
424 //=============================================================================
425 //      E3XBuffers_New : Create a TQ3XBufferObject 'object'.
426 //-----------------------------------------------------------------------------
427 //		Note :	Unclear what the purpose of this object is for, so we just
428 //				create it as a simple structure for now - i.e., this, like the
429 //				viewer is not really a TQ3Object.
430 //-----------------------------------------------------------------------------
431 TQ3XBufferObject
E3XBuffers_New(Display * dpy,TQ3Uns32 numBuffers,Window window)432 E3XBuffers_New(Display *dpy, TQ3Uns32 numBuffers, Window window)
433 {	TQ3XBufferObject		theBuffer;
434 
435 
436 
437 	// Allocate the 'object'
438 	theBuffer = (TQ3XBufferObject) Q3Memory_Allocate(sizeof(OpaqueTQ3XBufferObject));
439 	if (theBuffer == NULL)
440 		return(NULL);
441 
442 
443 
444 	// Initialise the 'object'
445 	theBuffer->theDisplay = dpy;
446 	theBuffer->theWindow  = window;
447 	theBuffer->numBuffers = numBuffers;
448 
449 	return(theBuffer);
450 }
451 
452 
453 
454 
455 
456 //=============================================================================
457 //      E3XBuffers_Swap : Swap the buffers.
458 //-----------------------------------------------------------------------------
459 //		Note :	Currently just flushes the display, since swapping is handled
460 //				by the renderer under Quesa.
461 //-----------------------------------------------------------------------------
462 void
E3XBuffers_Swap(Display * dpy,TQ3XBufferObject buffers)463 E3XBuffers_Swap(Display *dpy, TQ3XBufferObject buffers)
464 {
465 
466 
467 	// Just flush the display?
468 	XFlush(dpy);
469 }
470 
471 
472 
473 
474 
475 //=============================================================================
476 //      E3X_GetVisualInfo : Get an XVisualInfo.
477 //-----------------------------------------------------------------------------
478 //		Note :	No documentation on what this function would be for, so we just
479 //				do what seems reasonable... We assume that the intention is to
480 //				return an array that will be freed by our caller with XFree.
481 //
482 //				There's no way we can return the size of the array, so I assume
483 //				the idea was that the first item was the one to be used.
484 //-----------------------------------------------------------------------------
485 XVisualInfo *
E3X_GetVisualInfo(Display * dpy,Screen * screen)486 E3X_GetVisualInfo(Display *dpy, Screen *screen)
487 {	XVisualInfo		visualInfoTemplate;
488 	long			visualInfoMask;
489 	int				numberVisuals;
490 	XVisualInfo		*visualArray;
491 
492 
493 
494 	// Fill in the template
495 	visualInfoMask            = VisualClassMask | VisualScreenMask;
496 #ifdef __cplusplus
497 	visualInfoTemplate.c_class  = PseudoColor;
498 #else
499 	visualInfoTemplate.class  = PseudoColor;
500 #endif
501 	visualInfoTemplate.screen = DefaultScreen(dpy);
502 
503 
504 
505 	// Try and find a visual
506 	visualArray = XGetVisualInfo(dpy,
507 								 visualInfoMask,
508 								 &visualInfoTemplate,
509 								 &numberVisuals);
510 
511 	return(visualArray);
512 }
513