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