1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8 /*********************************************************************/
9 /* I.B.M. CONFIENTIAL */
10 /*********************************************************************/
11
12 #include <dxconfig.h>
13
14
15 /*---------------------------------------------------------------------------*\
16 $Source: /src/master/dx/src/exec/hwrender/xgl/hwInteractorEchoXGL.c,v $
17
18 These are the XGL implementations of the TDM direct interactor echos,
19 along with miscellaneous utility routines. Each function needs to be
20 ported to the native graphics API of the target system in order to provide
21 support for direct interactors.
22
23 Applications such as DX can be ported as a first step without direct
24 interactor facilities by stubbing out everything here.
25
26 TDM's idea of the origin of DC space is the lower-left corner of the
27 graphics window, while XGL uses the upper-left convention. The only
28 primitives in XGL which use device coordinates are the pixel level
29 read/write primitives. Therefore, in order to draw in pixel space we set
30 up model and world coordinates to map to TDM's notion of DC; XGL then
31 flips the Y coordinate implicitly. However, when we use the XGL pixel
32 read/write primitives we have to flip the Y coordinate ourselves.
33
34 $Log: hwInteractorEchoXGL.c,v $
35 Revision 1.3 1999/05/10 15:45:39 gda
36 Copyright message
37
38 Revision 1.3 1999/05/10 15:45:39 gda
39 Copyright message
40
41 Revision 1.2 1999/05/03 14:06:42 gda
42 moved to using dxconfig.h rather than command-line defines
43
44 Revision 1.1.1.1 1999/03/24 15:18:36 gda
45 Initial CVS Version
46
47 Revision 1.1.1.1 1999/03/19 20:59:49 gda
48 Initial CVS
49
50 Revision 10.1 1999/02/23 21:01:47 gda
51 OpenDX Baseline
52
53 Revision 9.1 1997/05/22 22:33:11 svs
54 Copy of release 3.1.4 code
55
56 * Revision 8.1 1996/05/03 17:54:54 gda
57 * fix(?) zoom box when NO_BACKING_STORE set
58 *
59 * Revision 8.0 1995/10/03 22:14:56 nsc
60 * Copy of release 3.1 code
61 *
62 * Revision 7.8 1995/08/30 21:09:53 c1orrang
63 * Re-doublebuffered solaris build w/ DX_SINGLE_BUFFER_SUN flag
64 *
65 * Revision 7.4 1994/06/08 20:07:53 jrush
66 * Change made in common layer to interface to SET_LINE_ATTRIBUTES
67 * from long to int32. This has no effect other than to generate
68 * a compile time warning, thus this change.
69 * ,.
70 *
71 * Revision 7.3 1994/05/06 14:26:42 mjh
72 * Cursor interactor maintenance: add SetLineAttributes to support dashed
73 * lines.
74 *
75 * Revision 7.2 94/03/31 15:55:11 tjm
76 * added versioning
77 *
78 * Revision 7.1 94/01/18 18:59:57 svs
79 * changes since release 2.0.1
80 *
81 * Revision 6.1 93/11/16 10:26:03 svs
82 * ship level code, release 2.0
83 *
84 * Revision 1.4 93/10/05 18:11:43 ellen
85 * Fixed Zoombox...it wasn't redrawing correctly, and
86 * was leaving the white zoom box trail.
87 *
88 * Revision 1.3 93/09/28 08:39:00 tjm
89 * fixed <DMCZAP54> garbage on screen when moving roam point
90 *
91 * Revision 1.2 93/07/14 13:28:51 tjm
92 * added solaris ifdefs
93 *
94 * Revision 1.1 93/06/29 10:01:25 tjm
95 * Initial revision
96 *
97 * Revision 5.3 93/05/11 18:04:30 mjh
98 * Implement screen door transparency for the GT.
99 *
100 * Revision 5.2 93/04/09 18:34:39 mjh
101 * replace calls to TDM_DRAW_ARROWHEAD_XGL with _dxf_DRAW_ARROWHEAD_XGL
102 *
103 * Revision 5.1 93/03/30 14:40:57 ellen
104 * Moved these files from the 5.0.2 Branch
105 *
106 * Revision 5.0.2.9 93/03/29 15:37:30 ellen
107 * Cleaned up _dxf_CREATE_CURSOR_PIXMAPS.
108 *
109 * Revision 5.0.2.8 93/03/22 18:41:56 ellen
110 * Set error in _dxf_CREATE_CURSOR_PIXMAPS if there isn't enough memory.
111 *
112 * Revision 5.0.2.7 93/02/11 20:39:55 mjh
113 * In _dxf_DRAW_GNOMON() and _dxf_DRAW_GLOBE(), use PDATA(buffermode)
114 * instead of PDATA(redrawmode) restoring the frame buffer configuration
115 * after blitting the echo from the draw buffer to the display buffer.
116 *
117 * Revision 5.0.2.6 93/02/04 19:25:36 mjh
118 * Implement cursor interactor echo.
119 *
120 * Revision 5.0.2.5 93/02/02 18:39:19 mjh
121 * Implement globe echo. DXRemove shadow rendering code since this is
122 * very slow on the Sun GS.
123 *
124 * Revision 5.0.2.4 93/02/01 22:22:11 mjh
125 * Implement pixel read/write, gnomon and zoom box echos.
126 *
127 * The gnomon echo is no longer double-buffered as this incurs the expense
128 * of copying the display buffer to the draw buffer as part of the
129 * interactor setup, and this is quite slow with the Sun GS card. The echo
130 * is now rendered into the draw buffer and then blitted into the display
131 * buffer.
132 *
133 * Revision 5.0.2.3 93/01/06 17:00:55 mjh
134 * window creation and destruction
135 *
136 * Revision 5.0.2.2 93/01/06 04:42:00 mjh
137 * initial revision
138 *
139 \*---------------------------------------------------------------------------*/
140
141 #include <stdio.h>
142 #define STRUCTURES_ONLY
143 #include "hwDeclarations.h"
144 #include "hwPortXGL.h"
145 #include "hwMatrix.h"
146 #include "hwInteractor.h"
147 #include "hwInteractorEcho.h"
148 #include "hwCursorInteractor.h"
149 #include "hwRotateInteractor.h"
150 #include "hwZoomInteractor.h"
151 #include "hwGlobeEchoDef.h"
152
153 #ifndef STANDALONE
154 #include "hwMemory.h"
155 #endif
156
157 #include "hwPortLayer.h"
158
159 void *
160 _dxf_ALLOCATE_PIXEL_ARRAY (void *ctx, int width, int height) ;
161
162 void
_dxf_BUFFER_CONFIG(void * ctx,void * image,int llx,int lly,int urx,int ury,int * CurrentDisplayMode,int * CurrentBufferMode,tdmInteractorRedrawMode redrawMode)163 _dxf_BUFFER_CONFIG (void *ctx, void *image, int llx, int lly, int urx, int ury,
164 int *CurrentDisplayMode, int *CurrentBufferMode,
165 tdmInteractorRedrawMode redrawMode)
166 {
167 /*
168 * Direct interactor echos use this and following routine to manage
169 * double buffering.
170 */
171
172 DEFCONTEXT(ctx) ;
173 DPRINT("\n(_dxf_BUFFER_CONFIG") ;
174
175 if(!DOUBLE_BUFFER_MODE)
176 return;
177
178 *CurrentBufferMode = BUFFER_CONFIG_MODE ;
179
180 if (redrawMode == tdmBothBufferDraw ||
181 redrawMode == tdmFrontBufferDraw)
182 {
183 DPRINT1 ("\n%s", redrawMode == tdmBothBufferDraw ?
184 "tdmBothBufferDraw" : "tdmFrontBufferDraw") ;
185 /*
186 * Enable the front buffer for writing. This translates into
187 * setting the XGL draw and display buffers to the same buffer so
188 * that draw updates are immediately visible.
189 *
190 * We won't be double buffering the globe and gnomon echos for the
191 * XGL port, so we needn't be concerned with keeping the back
192 * buffer contents identical to the front.
193 */
194
195 if (DISPLAY_BUFFER != DRAW_BUFFER)
196 if (DISPLAY_BUFFER == 1)
197 {
198 xgl_object_set (XGLRAS,
199 XGL_WIN_RAS_BUF_DRAW, 1,
200 XGL_WIN_RAS_BUF_DISPLAY, 1,
201 NULL) ;
202 DRAW_BUFFER = 1 ;
203 }
204 else
205 {
206 xgl_object_set (XGLRAS,
207 XGL_WIN_RAS_BUF_DRAW, 0,
208 XGL_WIN_RAS_BUF_DISPLAY, 0,
209 NULL) ;
210 DRAW_BUFFER = 0 ;
211 }
212
213 BUFFER_CONFIG_MODE = FRNTBUFFER ;
214 }
215 else if (redrawMode == tdmBackBufferDraw ||
216 redrawMode == tdmViewEchoMode)
217 {
218 DPRINT1 ("\n%s", redrawMode == tdmViewEchoMode ?
219 "tdmViewEchoMode" : "tdmBackBufferDraw") ;
220 /*
221 * Enable the back buffer for writing. In XGL this just means
222 * setting the draw and display buffers not equal to each other.
223 */
224
225 if (DISPLAY_BUFFER == DRAW_BUFFER)
226 if (DISPLAY_BUFFER == 1)
227 {
228 xgl_object_set (XGLRAS,
229 XGL_WIN_RAS_BUF_DRAW, 0,
230 XGL_WIN_RAS_BUF_DISPLAY, 1,
231 NULL) ;
232 DRAW_BUFFER = 0 ;
233 }
234 else
235 {
236 xgl_object_set (XGLRAS,
237 XGL_WIN_RAS_BUF_DRAW, 1,
238 XGL_WIN_RAS_BUF_DISPLAY, 0,
239 NULL) ;
240 DRAW_BUFFER = 1 ;
241 }
242
243 BUFFER_CONFIG_MODE = BCKBUFFER ;
244 }
245 else
246 DPRINT("\nignoring redraw mode") ;
247
248 DPRINT(")") ;
249 }
250
251
252 void
_dxf_BUFFER_RESTORE_CONFIG(void * ctx,int OrigDisplayMode,int OrigBufferMode,tdmInteractorRedrawMode redrawMode)253 _dxf_BUFFER_RESTORE_CONFIG (void *ctx, int OrigDisplayMode, int OrigBufferMode,
254 tdmInteractorRedrawMode redrawMode)
255 {
256 /*
257 * Restore frame buffer configuration.
258 */
259
260 DEFCONTEXT(ctx) ;
261 DPRINT("\n(_dxf_BUFFER_RESTORE_CONFIG") ;
262
263 if(!DOUBLE_BUFFER_MODE)
264 return;
265
266 if (redrawMode == tdmBothBufferDraw ||
267 redrawMode == tdmFrontBufferDraw)
268 {
269 DPRINT1("\ncurrent interactor redraw mode is %s",
270 redrawMode == tdmFrontBufferDraw ?
271 "tdmFrontBufferDraw" : "tdmBothBufferDraw") ;
272
273 if (OrigBufferMode == BCKBUFFER)
274 {
275 DPRINT("\nrestoring to original back buffer draw") ;
276 if (DISPLAY_BUFFER == 1)
277 {
278 xgl_object_set (XGLRAS,
279 XGL_WIN_RAS_BUF_DRAW, 0,
280 XGL_WIN_RAS_BUF_DISPLAY, 1,
281 NULL) ;
282 DRAW_BUFFER = 0 ;
283 }
284 else
285 {
286 xgl_object_set (XGLRAS,
287 XGL_WIN_RAS_BUF_DRAW, 1,
288 XGL_WIN_RAS_BUF_DISPLAY, 0,
289 NULL) ;
290 DRAW_BUFFER = 1 ;
291 }
292
293 BUFFER_CONFIG_MODE = BCKBUFFER ;
294 }
295 else
296 DPRINT("\nremaining in original front buffer draw") ;
297 }
298 else if (redrawMode == tdmBackBufferDraw ||
299 redrawMode == tdmViewEchoMode)
300 {
301 DPRINT1 ("\ncurrent interactor redraw mode is %s",
302 redrawMode == tdmViewEchoMode ?
303 "tdmViewEchoMode" : "tdmBackBufferDraw") ;
304
305 if (OrigBufferMode == FRNTBUFFER)
306 {
307 DPRINT("\nrestoring to original front buffer draw") ;
308 if (DISPLAY_BUFFER == 1)
309 {
310 xgl_object_set (XGLRAS,
311 XGL_WIN_RAS_BUF_DRAW, 1,
312 XGL_WIN_RAS_BUF_DISPLAY, 1,
313 NULL) ;
314 DRAW_BUFFER = 1 ;
315 }
316 else
317 {
318 xgl_object_set (XGLRAS,
319 XGL_WIN_RAS_BUF_DRAW, 0,
320 XGL_WIN_RAS_BUF_DISPLAY, 0,
321 NULL) ;
322 DRAW_BUFFER = 0 ;
323 }
324
325 BUFFER_CONFIG_MODE = FRNTBUFFER ;
326 }
327 else
328 DPRINT("\nremaining in original back buffer draw") ;
329 }
330 else
331 DPRINT("\nignoring redraw mode") ;
332
333 DPRINT(")") ;
334 }
335
336 void
_dxf_READ_BUFFER(void * ctx,int llx,int lly,int urx,int ury,void * buff)337 _dxf_READ_BUFFER(void *ctx, int llx, int lly, int urx, int ury, void *buff)
338 {
339 /*
340 * DXRead an array of pixels from display buffer into buff.
341 */
342
343 DEFCONTEXT(ctx) ;
344 Xgl_bounds_i2d rect ;
345
346 DPRINT("\n(_dxf_READ_BUFFER") ;
347 DPRINT1("\nllx %d", llx) ; DPRINT1(" lly %d", lly) ;
348 DPRINT1(" urx %d", urx) ; DPRINT1(" ury %d", ury) ;
349
350 rect.xmin = llx ; rect.xmax = urx ;
351 rect.ymin = VP_YMAX-ury ; rect.ymax = VP_YMAX-lly ;
352
353 /* set buff as rendering surface for temporary XGL context */
354 xgl_object_set (XGLTMPCTX, XGL_CTX_DEVICE, buff, NULL) ;
355
356 if (DISPLAY_BUFFER == DRAW_BUFFER)
357 /* doesn't matter which buffer we read from */
358 #ifdef solaris
359 xgl_context_copy_buffer (XGLTMPCTX, &rect, NULL, XGLRAS) ;
360 #else
361 xgl_context_copy_raster (XGLTMPCTX, &rect, NULL, XGLRAS) ;
362 #endif
363 else
364 if (DISPLAY_BUFFER == 1)
365 {
366 /* set draw buffer to 1 so we can read it, but don't swap display */
367 xgl_object_set (XGLRAS,
368 XGL_WIN_RAS_BUF_DRAW, 1,
369 XGL_WIN_RAS_BUF_DISPLAY, 1,
370 NULL) ;
371
372 /* read pixels and reset original buffer assignments */
373 #ifdef solaris
374 xgl_context_copy_buffer (XGLTMPCTX, &rect, NULL, XGLRAS) ;
375 #else
376 xgl_context_copy_raster (XGLTMPCTX, &rect, NULL, XGLRAS) ;
377 #endif
378 xgl_object_set (XGLRAS,
379 XGL_WIN_RAS_BUF_DRAW, 0,
380 XGL_WIN_RAS_BUF_DISPLAY, 1,
381 NULL) ;
382 }
383 else
384 {
385 /* set draw buffer to 0 so we can read it, but don't swap display */
386 xgl_object_set (XGLRAS,
387 XGL_WIN_RAS_BUF_DRAW, 0,
388 XGL_WIN_RAS_BUF_DISPLAY, 0,
389 NULL) ;
390
391 /* read pixels and reset original buffer assignments */
392 #ifdef solaris
393 xgl_context_copy_buffer (XGLTMPCTX, &rect, NULL, XGLRAS) ;
394 #else
395 xgl_context_copy_raster (XGLTMPCTX, &rect, NULL, XGLRAS) ;
396 #endif
397 xgl_object_set (XGLRAS,
398 XGL_WIN_RAS_BUF_DRAW, 1,
399 XGL_WIN_RAS_BUF_DISPLAY, 0,
400 NULL) ;
401 }
402
403 DPRINT(")") ;
404 }
405
406 void
_dxf_WRITE_BUFFER(void * ctx,int llx,int lly,int urx,int ury,void * buff)407 _dxf_WRITE_BUFFER (void *ctx, int llx, int lly, int urx, int ury, void *buff)
408 {
409 /*
410 * DXWrite pixel array from buff. The entire contents of buff are written.
411 */
412
413 DEFCONTEXT(ctx) ;
414 Xgl_pt_i2d position ;
415
416 DPRINT("\n(_dxf_WRITE_BUFFER") ;
417 DPRINT1("\nllx %d", llx) ; DPRINT1(" lly %d", lly) ;
418 DPRINT1(" urx %d", urx) ; DPRINT1(" ury %d", ury) ;
419
420 position.x = llx ; position.y = VP_YMAX-ury ;
421 #ifdef solaris
422 xgl_context_copy_buffer (XGLCTX, NULL, &position, buff) ;
423 #else
424 xgl_context_copy_raster (XGLCTX, NULL, &position, buff) ;
425 #endif
426
427 DPRINT(")") ;
428 }
429
430 void
_dxf_DRAW_GLOBE(tdmInteractor I,void * udata,float rot[4][4],int draw)431 _dxf_DRAW_GLOBE (tdmInteractor I, void *udata, float rot[4][4], int draw)
432 {
433 /*
434 * draw == 1 to draw globe, draw == 0 to undraw. This is done with two
435 * separate calls in order to support explicit erasure of edges for
436 * some implementations. A draw is always preceded by an undraw and
437 * the pair of invocations is assumed to be atomic.
438 */
439
440 DEFDATA(I,tdmRotateData) ;
441 DEFPORT(I_PORT_HANDLE) ;
442 Xgl_color color ;
443 Xgl_pt_list line ;
444 Xgl_pt_f3d pos[LATS+LONGS+1] ;
445 register Xgl_pt_f3d *p ;
446 int u, v, on, dummy = 0 ;
447
448 /* globe edge visibility flags. all globe instance share this data. */
449 static struct {
450 int latvis, longvis ;
451 } edges[LATS][LONGS] ;
452
453 /* globe and globeface defined in tdmGlobeEchoDef.h */
454 register float (*Globe)[LONGS][3] = (float (*)[LONGS][3])globe ;
455 register struct Face (*Globeface)[LONGS] = (struct Face(*)[LONGS])globeface ;
456
457 /* view normal */
458 register float z0, z1, z2 ;
459 z0 = rot[0][2] ; z1 = rot[1][2] ; z2 = rot[2][2] ;
460
461 #define FACEVISIBLE(u,v,z0,z1,z2) \
462 (Globeface[u][v].norm[0] * z0 + \
463 Globeface[u][v].norm[1] * z1 + \
464 Globeface[u][v].norm[2] * z2 > 0.0)
465
466 #define ENDLINE { \
467 if (p != pos) xgl_multipolyline (XGLCTX, NULL, 1, &line) ; \
468 p = pos ; }
469
470 #define MOVE(vertex) { \
471 ENDLINE ; \
472 *p = *(Xgl_pt_f3d *)vertex ; \
473 line.num_pts = 1 ; }
474
475 #define DRAW(vertex) { \
476 *++p = *(Xgl_pt_f3d *)vertex ; \
477 line.num_pts++ ; }
478
479 DPRINT("\n(DrawGlobe") ;
480 if (draw)
481 {
482 color.rgb.r = 1.0 ;
483 color.rgb.g = 1.0 ;
484 color.rgb.b = 1.0 ;
485 xgl_object_set (XGLCTX,
486 XGL_CTX_LINE_COLOR, &color,
487 NULL) ;
488 }
489 else
490 {
491 if (PDATA(redrawmode) != tdmViewEchoMode)
492 {
493 /*
494 * In tdmViewEchoMode (DX's Execute On Change), we are drawing
495 * the globe echo on top of a background image that is redrawn
496 * with every frame of a direct interaction.
497 *
498 * If we're not in that mode, the background image is static
499 * while the globe echo rotates in front of it, so erasing the
500 * globe means we have to repair damage to the background. We
501 * do this by blitting a portion of the static image to the
502 * back buffer, drawing the globe over that, then blitting the
503 * combined results back to the front buffer.
504 */
505
506 /* force graphics output into back (draw) buffer */
507 _dxf_BUFFER_CONFIG (PORT_CTX, &dummy, dummy, dummy, dummy, dummy,
508 &dummy, &dummy, tdmBackBufferDraw) ;
509
510 /* erase globe background */
511 _dxf_WRITE_BUFFER (PORT_CTX, PDATA(illx), PDATA(illy),
512 PDATA(iurx), PDATA(iury), PDATA(background)) ;
513 }
514
515 DPRINT(")") ;
516 return ;
517 }
518
519 /* mark visible edges */
520 for (u=0 ; u<LATS-1 ; u++)
521 {
522 if (FACEVISIBLE(u, 0, z0, z1, z2))
523 {
524 edges[u][LONGS-1].latvis++ ;
525 edges[u+1][LONGS-1].latvis++ ;
526 edges[u][0].longvis++ ;
527 edges[u][LONGS-1].longvis++ ;
528 }
529 for (v=1 ; v<LONGS ; v++)
530 if (FACEVISIBLE(u, v, z0, z1, z2))
531 {
532 edges[u][v-1].latvis++ ;
533 edges[u+1][v-1].latvis++ ;
534 edges[u][v].longvis++ ;
535 edges[u][v-1].longvis++ ;
536 }
537 }
538
539 /* north pole */
540 if (z1 > 0.0)
541 for (v=0 ; v<LONGS ; v++)
542 edges[LATS-1][v].latvis++ ;
543
544 /* south pole */
545 if (z1 < 0.0)
546 for (v=0 ; v<LONGS ; v++)
547 edges[0][v].latvis++ ;
548
549 /* set up XGL point list */
550 line.pt_type = XGL_PT_F3D ;
551 line.bbox = NULL ;
552 line.pts.f3d = p = pos ;
553
554 /* draw each visible edge exactly once */
555 for (u=0 ; u<LATS ; u++)
556 {
557 /* latitude lines */
558 for (v=0, on=0 ; v<LONGS-1 ; v++)
559 if (edges[u][v].latvis)
560 {
561 if (!on)
562 {
563 on = 1 ;
564 MOVE(Globe[u][v]) ;
565 }
566 DRAW(Globe[u][v+1]) ;
567 edges[u][v].latvis = 0 ;
568 }
569 else on = 0 ;
570
571 /* close latitude line if necessary */
572 if (edges[u][LONGS-1].latvis)
573 {
574 if (!on) MOVE(Globe[u][LONGS-1]) ;
575
576 DRAW(Globe[u][0]) ;
577 edges[u][LONGS-1].latvis = 0 ;
578 }
579 }
580
581 for (v=0 ; v<LONGS ; v++)
582 /* longitude lines */
583 for (u=0, on=0 ; u<LATS-1 ; u++)
584 if (edges[u][v].longvis)
585 {
586 if (!on)
587 {
588 on = 1 ;
589 MOVE(Globe[u][v]) ;
590 }
591 DRAW(Globe[u+1][v]) ;
592 edges[u][v].longvis = 0 ;
593 }
594 else on = 0 ;
595
596 ENDLINE ;
597
598 if (PDATA(redrawmode) != tdmViewEchoMode)
599 {
600 /* copy rendered globe from draw buffer to display buffer */
601 Xgl_bounds_i2d rect ;
602 Xgl_pt_i2d position ;
603
604 position.x = PDATA(illx) ; position.y = VP_YMAX-PDATA(iury) ;
605 rect.xmin = PDATA(illx) ; rect.ymin = VP_YMAX-PDATA(iury) ;
606 rect.xmax = PDATA(iurx) ; rect.ymax = VP_YMAX-PDATA(illy) ;
607
608 /* ensure that draw buffer rendering is completed */
609 xgl_context_post (XGLCTX, 0) ;
610
611 /* copy the combined globe and background image to display buffer */
612 #ifdef solaris
613 xgl_object_set (XGLRAS,
614 XGL_RAS_SOURCE_BUFFER, DRAW_BUFFER,
615 NULL) ;
616
617 /* Set XGLCTX output dest to XGL_RENDER_DISPLAY_BUFFER
618 ( == DISPLAY_BUFFER) */
619 xgl_object_set (XGLCTX,
620 XGL_CTX_RENDER_BUFFER, XGL_RENDER_DISPLAY_BUFFER,
621 NULL) ;
622 xgl_context_copy_buffer
623 (XGLCTX, &rect, &position, XGLRAS) ;
624
625 /* Reset XGLCTX output dest to default */
626 xgl_object_set (XGLCTX,
627 XGL_CTX_RENDER_BUFFER, XGL_RENDER_DRAW_BUFFER,
628 NULL) ;
629 #else
630 xgl_context_copy_buffer
631 (XGLCTX, &rect, &position, DRAW_BUFFER, DISPLAY_BUFFER) ;
632 #endif
633
634 _dxf_BUFFER_RESTORE_CONFIG
635 (PORT_CTX, dummy, PDATA(buffermode), tdmBackBufferDraw) ;
636 }
637 DPRINT(")") ;
638 }
639
640 void
_dxf_DRAW_ARROWHEAD(void * ctx,float ax,float ay)641 _dxf_DRAW_ARROWHEAD (void *ctx, float ax, float ay)
642 {
643 DEFCONTEXT(ctx) ;
644 Xgl_pt_list line ;
645 Xgl_pt_f3d verts[3] ;
646 double angle, hyp, length ;
647 float x1, y1 ;
648
649 /* set up XGL point list */
650 line.pt_type = XGL_PT_F3D ;
651 line.bbox = NULL ;
652 line.num_pts = 3 ;
653 line.pts.f3d = verts ;
654 verts[1].x = ax ;
655 verts[1].y = ay ;
656 verts[0].z = 0 ;
657 verts[1].z = 0 ;
658 verts[2].z = 0 ;
659
660 hyp = sqrt(ax*ax + ay*ay) ;
661
662 if (hyp == 0.0)
663 return ;
664
665 if (hyp < 0.2)
666 length = 0.06 ;
667 else
668 length = 0.12 ;
669
670 /* To avoid acos DOMAIN errors due to floating point inaccuracies */
671 if (-ax/hyp > 1.0)
672 hyp = -ax;
673 if (-ax/hyp < -1.0)
674 hyp = ax;
675
676 angle = acos((double)(-ax/hyp)) ;
677 if (ay > 0)
678 angle = 2*M_PI - angle ;
679
680 angle = angle + M_PI/6 ;
681 if (angle > 2*M_PI)
682 angle = angle - 2*M_PI ;
683
684 x1 = cos(angle) * length ;
685 y1 = sin(angle) * length ;
686
687 verts[0].x = ax + x1 ;
688 verts[0].y = ay + y1 ;
689
690 angle = angle - M_PI/3 ;
691 if (angle < 0)
692 angle = angle + 2*M_PI ;
693
694 x1 = cos(angle) * length ;
695 y1 = sin(angle) * length ;
696
697 verts[2].x = ax + x1 ;
698 verts[2].y = ay + y1 ;
699
700 xgl_multipolyline (XGLCTX, NULL, 1, &line) ;
701 }
702
703 void
_dxf_DRAW_GNOMON(tdmInteractor I,void * udata,float rot[4][4],int draw)704 _dxf_DRAW_GNOMON (tdmInteractor I, void *udata, float rot[4][4], int draw)
705 {
706 /*
707 * draw == 1 to draw gnomon, draw == 0 to undraw. This is done with
708 * two separate calls in order to support explicit erasure of edges for
709 * some implementations. A draw is always preceded by an undraw and
710 * the pair of invocations is assumed to be atomic.
711 *
712 * Computations are done in normalized screen coordinates in order to
713 * render arrow heads correctly.
714 */
715
716 DEFDATA(I,tdmRotateData) ;
717 DEFPORT(I_PORT_HANDLE) ;
718 Xgl_color color ;
719 Xgl_pt_list line ;
720 Xgl_pt_f3d pos[2] ;
721 int dummy = 0 ;
722
723 float origin[2] ;
724 float xaxis[2], yaxis[2], zaxis[2] ;
725 float xlabel[2], ylabel[2], zlabel[2] ;
726
727 DPRINT("\n(DrawGnomon") ;
728
729 if (draw)
730 {
731 color.rgb.r = 1.0 ;
732 color.rgb.g = 1.0 ;
733 color.rgb.b = 1.0 ;
734 xgl_object_set (XGLCTX,
735 XGL_CTX_LINE_COLOR, &color,
736 #ifdef solaris
737 XGL_CTX_STEXT_COLOR, &color,
738 #else
739 XGL_CTX_SFONT_TEXT_COLOR, &color,
740 #endif
741 NULL) ;
742 }
743 else
744 {
745 if (PDATA(redrawmode) != tdmViewEchoMode)
746 {
747 /*
748 * In tdmViewEchoMode (DX's Execute On Change), we are drawing
749 * the gnomon echo on top of a background image that is redrawn
750 * with every frame of a direct interaction.
751 *
752 * If we're not in that mode, the background image is static
753 * while the gnomon echo rotates in front of it, so erasing the
754 * gnomon means we have to repair damage to the background. We
755 * do this by blitting a portion of the static image to the
756 * back buffer, drawing the gnomon over that, then blitting the
757 * combined results back to the front buffer.
758 */
759
760 /* force graphics output into back (draw) buffer */
761 _dxf_BUFFER_CONFIG (PORT_CTX, &dummy, dummy, dummy, dummy, dummy,
762 &dummy, &dummy, tdmBackBufferDraw) ;
763
764 /* erase gnomon background */
765 _dxf_WRITE_BUFFER (PORT_CTX, PDATA(illx), PDATA(illy),
766 PDATA(iurx), PDATA(iury), PDATA(background)) ;
767 }
768
769 DPRINT(")") ;
770 return ;
771 }
772
773 origin[0] = 0.0 ;
774 origin[1] = 0.0 ;
775
776 xaxis[0] = 0.7 * rot[0][0] ; xaxis[1] = 0.7 * rot[0][1] ;
777 yaxis[0] = 0.7 * rot[1][0] ; yaxis[1] = 0.7 * rot[1][1] ;
778 zaxis[0] = 0.7 * rot[2][0] ; zaxis[1] = 0.7 * rot[2][1] ;
779
780 /* set up normalized coordinates */
781 _dxf_PUSH_REPLACE_MATRIX (PORT_CTX, (float (*)[4])identity) ;
782
783 /* set up XGL point list */
784 line.pt_type = XGL_PT_F3D ;
785 line.bbox = NULL ;
786 line.num_pts = 2 ;
787 line.pts.f3d = pos ;
788 pos[0].x = origin[0] ;
789 pos[0].y = origin[1] ;
790 pos[0].z = 0 ;
791 pos[1].z = 0 ;
792
793 /* draw x axis */
794 pos[1].x = xaxis[0] ;
795 pos[1].y = xaxis[1] ;
796 xgl_multipolyline (XGLCTX, NULL, 1, &line) ;
797 _dxf_DRAW_ARROWHEAD (PORT_CTX, xaxis[0], xaxis[1]) ;
798
799 /* draw y axis */
800 pos[1].x = yaxis[0] ;
801 pos[1].y = yaxis[1] ;
802 xgl_multipolyline (XGLCTX, NULL, 1, &line) ;
803 _dxf_DRAW_ARROWHEAD (PORT_CTX, yaxis[0], yaxis[1]) ;
804
805 /* draw z axis */
806 pos[1].x = zaxis[0] ;
807 pos[1].y = zaxis[1] ;
808 xgl_multipolyline (XGLCTX, NULL, 1, &line) ;
809 _dxf_DRAW_ARROWHEAD (PORT_CTX, zaxis[0], zaxis[1]) ;
810
811 /* compute axes label positions */
812 xlabel[0] = 0.8 * rot[0][0] ; xlabel[1] = 0.8 * rot[0][1] ;
813 ylabel[0] = 0.8 * rot[1][0] ; ylabel[1] = 0.8 * rot[1][1] ;
814 zlabel[0] = 0.8 * rot[2][0] ; zlabel[1] = 0.8 * rot[2][1] ;
815
816 /* move labels left and/or down if they're going to hit arrowheads */
817 if (xlabel[0] <= 0) xlabel[0] -= 0.15 ;
818 if (xlabel[1] <= 0) xlabel[1] -= 0.15 ;
819
820 if (ylabel[0] <= 0) ylabel[0] -= 0.15 ;
821 if (ylabel[1] <= 0) ylabel[1] -= 0.15 ;
822
823 if (zlabel[0] <= 0) zlabel[0] -= 0.15 ;
824 if (zlabel[1] <= 0) zlabel[1] -= 0.15 ;
825
826 /* render the axes labels */
827 pos[1].x = 0 ; pos[1].y = 0 ;
828 #ifdef solaris
829 xgl_object_set (XGLCTX, XGL_CTX_ATEXT_CHAR_HEIGHT, 0.15, 0) ;
830 #else
831 xgl_object_set (XGLCTX, XGL_CTX_ANNOT_CHAR_HEIGHT, 0.15, 0) ;
832 #endif
833
834 pos[0].x = xlabel[0] ; pos[0].y = xlabel[1] ;
835 xgl_annotation_text (XGLCTX, "X", &pos[0], &pos[1]) ;
836
837 pos[0].x = ylabel[0] ; pos[0].y = ylabel[1] ;
838 xgl_annotation_text (XGLCTX, "Y", &pos[0], &pos[1]) ;
839
840 pos[0].x = zlabel[0] ; pos[0].y = zlabel[1] ;
841 xgl_annotation_text (XGLCTX, "Z", &pos[0], &pos[1]) ;
842
843 /* return to pushed coordinate system */
844 _dxf_POP_MATRIX(PORT_CTX) ;
845
846 if (PDATA(redrawmode) != tdmViewEchoMode)
847 {
848 /* copy draw buffer to display buffer */
849 Xgl_bounds_i2d rect ;
850 Xgl_pt_i2d position ;
851
852 position.x = PDATA(illx) ; position.y = VP_YMAX-PDATA(iury) ;
853 rect.xmin = PDATA(illx) ; rect.ymin = VP_YMAX-PDATA(iury) ;
854 rect.xmax = PDATA(iurx) ; rect.ymax = VP_YMAX-PDATA(illy) ;
855
856 /* ensure that draw buffer rendering is completed */
857 xgl_context_post (XGLCTX, 0) ;
858
859 /* copy the combined gnomon and background image to display buffer */
860 #ifdef solaris
861 xgl_object_set (XGLRAS,
862 XGL_RAS_SOURCE_BUFFER, DRAW_BUFFER,
863 NULL) ;
864 xgl_object_set (XGLCTX,
865 XGL_CTX_RENDER_BUFFER, XGL_RENDER_DISPLAY_BUFFER,
866 NULL) ;
867 xgl_context_copy_buffer
868 (XGLCTX, &rect, &position, XGLRAS) ;
869 xgl_object_set (XGLCTX,
870 XGL_CTX_RENDER_BUFFER, XGL_RENDER_DRAW_BUFFER,
871 NULL) ;
872 #else
873 xgl_context_copy_buffer
874 (XGLCTX, &rect, &position, DRAW_BUFFER, DISPLAY_BUFFER) ;
875 #endif
876
877 _dxf_BUFFER_RESTORE_CONFIG
878 (PORT_CTX, dummy, PDATA(buffermode), tdmBackBufferDraw) ;
879 }
880
881 DPRINT(")") ;
882 }
883
884
885 static void
_dxf_captureZoomBox(tdmInteractor I,void * udata,float rot[4][4])886 _dxf_captureZoomBox (tdmInteractor I, void *udata, float rot[4][4])
887 {
888 DEFDATA(I,tdmZoomData) ;
889 DEFPORT(I_PORT_HANDLE) ;
890 Xgl_bounds_i2d rect ;
891 Xgl_pt_i2d position ;
892 int x1, y1, x2, y2 ;
893
894 xgl_object_set(XGLTMPCTX, XGL_CTX_DEVICE, CDATA(image), NULL);
895
896 /* left */
897 rect.xmin = MAX(0,x1-1) ; rect.xmax = rect.xmin + 1 ;
898 rect.ymin = MAX(0,VP_YMAX-y2) ; rect.ymax = MAX(0,VP_YMAX-y1) ;
899 position.x = rect.xmin ; position.y = rect.ymin ;
900 #ifdef solaris
901 xgl_context_copy_buffer (XGLTMPCTX, &rect, &position, XGLRAS);
902 #else
903 xgl_context_copy_raster (XGLTMPCTX, &rect, &position, XGLRAS);
904 #endif
905
906 /* right */
907 rect.xmin = MAX(0,x2-1) ; rect.xmax = rect.xmin + 1 ;
908 rect.ymin = MAX(0,VP_YMAX-y2) ; rect.ymax = MAX(0,VP_YMAX-y1) ;
909 position.x = rect.xmin ; position.y = rect.ymin ;
910 #ifdef solaris
911 xgl_context_copy_buffer (XGLTMPCTX, &rect, &position, XGLRAS);
912 #else
913 xgl_context_copy_raster (XGLTMPCTX, &rect, &position, XGLRAS);
914 #endif
915
916 /* bottom */
917 rect.xmin = MAX(0,x1) ; rect.xmax = MAX(0,x2) ;
918 rect.ymin = MAX(0,VP_YMAX-y1-1) ; rect.ymax = rect.ymin + 1 ;
919 position.x = rect.xmin ; position.y = rect.ymin ;
920 #ifdef solaris
921 xgl_context_copy_buffer (XGLTMPCTX, &rect, &position, XGLRAS);
922 #else
923 xgl_context_copy_raster (XGLTMPCTX, &rect, &position, XGLRAS);
924 #endif
925
926 /* top */
927 rect.xmin = MAX(0,x1) ; rect.xmax = MAX(0,x2) ;
928 rect.ymin = MAX(0,VP_YMAX-y2-1) ; rect.ymax = rect.ymin + 1 ;
929 position.x = rect.xmin ; position.y = rect.ymin ;
930 #ifdef solaris
931 xgl_context_copy_buffer (XGLTMPCTX, &rect, &position, XGLRAS);
932 #else
933 xgl_context_copy_raster (XGLTMPCTX, &rect, &position, XGLRAS);
934 #endif
935 }
936
937 static void
_dxf_restoreZoomBox(tdmInteractor I,void * udata,float rot[4][4])938 _dxf_restoreZoomBox (tdmInteractor I, void *udata, float rot[4][4])
939 {
940 DEFDATA(I,tdmZoomData) ;
941 DEFPORT(I_PORT_HANDLE) ;
942 Xgl_bounds_i2d rect ;
943 Xgl_pt_i2d position ;
944 int x1, y1, x2, y2 ;
945
946 /*
947 * Repair the image by blitting pixels from backing store. The
948 * blits are expressed in XGL's notion of device coordinates, so we
949 * must flip the Y coordinates.
950 */
951
952 /* left */
953 rect.xmin = MAX(0,x1-1) ; rect.xmax = rect.xmin + 1 ;
954 rect.ymin = MAX(0,VP_YMAX-y2) ; rect.ymax = MAX(0,VP_YMAX-y1) ;
955 position.x = rect.xmin ; position.y = rect.ymin ;
956 #ifdef solaris
957 xgl_context_copy_buffer (XGLCTX, &rect, &position, CDATA(image)) ;
958 #else
959 xgl_context_copy_raster (XGLCTX, &rect, &position, CDATA(image)) ;
960 #endif
961
962 /* right */
963 rect.xmin = MAX(0,x2-1) ; rect.xmax = rect.xmin + 1 ;
964 rect.ymin = MAX(0,VP_YMAX-y2) ; rect.ymax = MAX(0,VP_YMAX-y1) ;
965 position.x = rect.xmin ; position.y = rect.ymin ;
966 #ifdef solaris
967 xgl_context_copy_buffer (XGLCTX, &rect, &position, CDATA(image)) ;
968 #else
969 xgl_context_copy_raster (XGLCTX, &rect, &position, CDATA(image)) ;
970 #endif
971
972 /* bottom */
973 rect.xmin = MAX(0,x1) ; rect.xmax = MAX(0,x2) ;
974 rect.ymin = MAX(0,VP_YMAX-y1-1) ; rect.ymax = rect.ymin + 1 ;
975 position.x = rect.xmin ; position.y = rect.ymin ;
976 #ifdef solaris
977 xgl_context_copy_buffer (XGLCTX, &rect, &position, CDATA(image)) ;
978 #else
979 xgl_context_copy_raster (XGLCTX, &rect, &position, CDATA(image)) ;
980 #endif
981
982 /* top */
983 rect.xmin = MAX(0,x1) ; rect.xmax = MAX(0,x2) ;
984 rect.ymin = MAX(0,VP_YMAX-y2-1) ; rect.ymax = rect.ymin + 1 ;
985 position.x = rect.xmin ; position.y = rect.ymin ;
986 #ifdef solaris
987 xgl_context_copy_buffer (XGLCTX, &rect, &position, CDATA(image)) ;
988 #else
989 xgl_context_copy_raster (XGLCTX, &rect, &position, CDATA(image)) ;
990 #endif
991 }
992
993 #undef _dxf_SERVICES_FLAGS
994 extern hwFlags _dxf_SERVICES_FLAGS();
995
996 void
_dxf_DRAW_ZOOMBOX(tdmInteractor I,void * udata,float rot[4][4],int draw)997 _dxf_DRAW_ZOOMBOX (tdmInteractor I, void *udata, float rot[4][4], int draw)
998 {
999 /*
1000 * draw == 1 to draw zoombox, draw == 0 to undraw. This is done with
1001 * two separate calls in order to support explicit erasure.
1002 */
1003
1004 DEFDATA(I,tdmZoomData) ;
1005 DEFPORT(I_PORT_HANDLE) ;
1006 int x1, y1, x2, y2 ;
1007 DPRINT("\n(DrawZoomBox") ;
1008
1009 x1 = PDATA(x1) ; x2 = PDATA(x2) ;
1010 y1 = PDATA(y1) ; y2 = PDATA(y2) ;
1011
1012 if (draw)
1013 {
1014 /*
1015 * Coordinates are expressed in TDM's notion of device coordinates,
1016 * so _dxf_SET_WORLD_SCREEN() needs to be called before this routine
1017 * is invoked.
1018 */
1019
1020 Xgl_color color ;
1021 Xgl_pt_list box ;
1022 Xgl_pt_f3d pos[5] ;
1023
1024 if (_dxf_isFlagsSet(_dxf_SERVICES_FLAGS(), SF_INVALIDATE_BACKSTORE))
1025 _dxf_captureZoomBox(I, udata, rot);
1026
1027 color.rgb.r = 1.0 ; color.rgb.g = 1.0 ; color.rgb.b = 1.0 ;
1028 xgl_object_set (XGLCTX,
1029 XGL_CTX_LINE_COLOR, &color,
1030 NULL) ;
1031
1032 box.pt_type = XGL_PT_F3D ;
1033 box.bbox = NULL ;
1034 box.num_pts = 5 ;
1035 box.pts.f3d = pos ;
1036
1037 pos[0].x = x1 ; pos[0].y = y1 ; pos[0].z = 0 ;
1038 pos[1].x = x2 ; pos[1].y = y1 ; pos[1].z = 0 ;
1039 pos[2].x = x2 ; pos[2].y = y2 ; pos[2].z = 0 ;
1040 pos[3].x = x1 ; pos[3].y = y2 ; pos[3].z = 0 ;
1041 pos[4].x = x1 ; pos[4].y = y1 ; pos[4].z = 0 ;
1042
1043 xgl_multipolyline (XGLCTX, NULL, 1, &box) ;
1044 xgl_context_post (XGLCTX, 0) ;
1045 }
1046 else if (CDATA(image))
1047 {
1048 _dxf_restoreZoomBox(I, udata, rot);
1049 }
1050 else
1051 {
1052 DPRINT("\nno backing store to erase zoombox") ;
1053 }
1054
1055 DPRINT(")") ;
1056 }
1057
1058
1059 int
_dxf_GET_ZBUFFER_STATUS(void * ctx)1060 _dxf_GET_ZBUFFER_STATUS (void *ctx)
1061 {
1062 /*
1063 * return whether zbuffer is active or not
1064 */
1065
1066 DEFCONTEXT(ctx) ;
1067 Xgl_hlhsr_mode zmode ;
1068 int status ;
1069 DPRINT("\n(_dxf_GET_ZBUFFER_STATUS:") ;
1070
1071 xgl_object_get (XGLCTX, XGL_3D_CTX_HLHSR_MODE, &zmode) ;
1072 if (zmode == XGL_HLHSR_NONE)
1073 status = 0 ;
1074 else
1075 status = 1 ;
1076
1077 DPRINT1 ("%d)", status) ;
1078 return status ;
1079 }
1080
1081 void
_dxf_SET_ZBUFFER_STATUS(void * ctx,int status)1082 _dxf_SET_ZBUFFER_STATUS (void *ctx, int status)
1083 {
1084 /*
1085 * set zbuffer off or on
1086 */
1087
1088 DEFCONTEXT(ctx) ;
1089 DPRINT1 ("\n(_dxf_SET_ZBUFFER_STATUS:%d", status) ;
1090
1091 if (status)
1092 #ifdef solaris
1093 xgl_object_set (XGLCTX, XGL_3D_CTX_HLHSR_MODE, XGL_HLHSR_Z_BUFFER, 0) ;
1094 #else
1095 xgl_object_set (XGLCTX, XGL_3D_CTX_HLHSR_MODE, XGL_HLHSR_ZBUFFER, 0) ;
1096 #endif
1097 else
1098 xgl_object_set (XGLCTX, XGL_3D_CTX_HLHSR_MODE, XGL_HLHSR_NONE, 0) ;
1099
1100 DPRINT(")") ;
1101 }
1102
1103 void
_dxf_SET_SOLID_FILL_PATTERN(void * ctx)1104 _dxf_SET_SOLID_FILL_PATTERN (void *ctx)
1105 {
1106 /*
1107 * reset screen door half transparency to solid if used
1108 */
1109
1110 DEFCONTEXT(ctx) ;
1111 DPRINT("\n(_dxf_SET_SOLID_FILL_PATTERN") ;
1112
1113 xgl_object_set
1114 (XGLCTX,
1115 XGL_CTX_SURF_FRONT_FILL_STYLE, XGL_SURF_FILL_SOLID,
1116 NULL) ;
1117
1118 DPRINT(")") ;
1119 }
1120
1121 void
_dxf_GET_WINDOW_ORIGIN(void * ctx,int * x,int * y)1122 _dxf_GET_WINDOW_ORIGIN (void *ctx, int *x, int *y)
1123 {
1124 /*
1125 * return LL corner of window relative to LL corner of screen in pixels
1126 */
1127
1128 DEFCONTEXT(ctx) ;
1129 Xgl_pt_i2d origin ;
1130 DPRINT("\n(_dxf_GET_WINDOW_ORIGIN") ;
1131
1132 xgl_object_get (XGLRAS, XGL_WIN_RAS_POSITION, &origin) ;
1133
1134 *y = SCREEN_YMAX - (origin.y + VP_YMAX) ;
1135 *x = origin.x ;
1136
1137 DPRINT1 ("\n%d,", *x) ; DPRINT1 (" %d)", *y) ;
1138 }
1139
1140 void
_dxf_GET_MAXSCREEN(void * ctx,int * x,int * y)1141 _dxf_GET_MAXSCREEN (void *ctx, int *x, int *y)
1142 {
1143 /*
1144 * return maximum coordinates of entire screen in pixels
1145 */
1146
1147 DEFCONTEXT(ctx) ;
1148 DPRINT("\n(_dxf_GET_MAXSCREEN") ;
1149
1150 *x = SCREEN_XMAX ;
1151 *y = SCREEN_YMAX ;
1152 DPRINT1 ("\n%d,", *x) ; DPRINT1 (" %d)", *y) ;
1153 }
1154
1155 void
_dxf_SET_WORLD_SCREEN(void * ctx,int w,int h)1156 _dxf_SET_WORLD_SCREEN (void *ctx, int w, int h)
1157 {
1158 /*
1159 * This routine can be ignored if API can write directly to DC,
1160 * otherwise, must set up transforms for screen mode.
1161 */
1162
1163 DEFCONTEXT(ctx) ;
1164 float S[4][4], xs, ys ;
1165 DPRINT("\n(_dxf_SET_WORLD_SCREEN") ;
1166
1167 xs = 2.0 / ((w-1) + 0.5) ;
1168 ys = 2.0 / ((h-1) + 0.5) ;
1169
1170 S[0][0] = xs ; S[0][1] = 0 ; S[0][2] = 0 ; S[0][3] = 0 ;
1171 S[1][0] = 0 ; S[1][1] = ys ; S[1][2] = 0 ; S[1][3] = 0 ;
1172 S[2][0] = 0 ; S[2][1] = 0 ; S[2][2] = 1 ; S[2][3] = 0 ;
1173 S[3][0] = -1 ; S[3][1] = -1 ; S[3][2] = 0 ; S[3][3] = 1 ;
1174
1175 _dxf_SET_VIEWPORT (ctx, 0, w-1, 0, h-1) ;
1176 xgl_transform_write (PROJECTION_TRANSFORM, S) ;
1177 xgl_transform_write (MODEL_VIEW_TRANSFORM, identity) ;
1178
1179 DPRINT(")") ;
1180 }
1181
1182 void
_dxf_CREATE_CURSOR_PIXMAPS(tdmInteractor I)1183 _dxf_CREATE_CURSOR_PIXMAPS (tdmInteractor I)
1184 {
1185 /*
1186 * Cursors are pixmaps used for representing probe/roam positions.
1187 */
1188
1189 DEFDATA(I,CursorData) ;
1190 DEFPORT(I_PORT_HANDLE) ;
1191 Xgl_pt_i2d pos ;
1192 Xgl_color black, gray, green, white ;
1193 DPRINT("\n(xglTDM_CREATE_CURSOR_PIXMAPS") ;
1194
1195 /* set up XGL rgb colors */
1196 green.rgb.r = 0.0 ; green.rgb.g = 1.0 ; green.rgb.b = 0.0 ;
1197 gray.rgb.r = 0.5 ; gray.rgb.g = 0.5 ; gray.rgb.b = 0.5 ;
1198 black.rgb.r = 0.0 ; black.rgb.g = 0.0 ; black.rgb.b = 0.0 ;
1199 white.rgb.r = 1.0 ; white.rgb.g = 1.0 ; white.rgb.b = 1.0 ;
1200
1201 /* Initialize the Interactors */
1202 PDATA(cursor_saveunder) = PDATA(ActiveSquareCursor) =
1203 PDATA(PassiveSquareCursor) = PDATA(ProjectionMark) = NULL ;
1204
1205 /* allocate a cursor save-under for the roam/probe interactor */
1206 if ( !(PDATA(cursor_saveunder) = _dxf_ALLOCATE_PIXEL_ARRAY (PORT_CTX,
1207 PDATA(cursor_size), PDATA(cursor_size)) )) goto error ;
1208
1209 /* allocate and init active cursor pixmap: green outline, black interior */
1210 if ( !(PDATA(ActiveSquareCursor) = _dxf_ALLOCATE_PIXEL_ARRAY (PORT_CTX,
1211 PDATA(cursor_size), PDATA(cursor_size)) )) goto error ;
1212
1213 /* set pixel array as rendering surface for temporary XGL context */
1214 xgl_object_set (XGLTMPCTX, XGL_CTX_DEVICE, PDATA(ActiveSquareCursor), NULL) ;
1215
1216 for (pos.x=0 ; pos.x<PDATA(cursor_size) ; pos.x++)
1217 for (pos.y=0 ; pos.y<PDATA(cursor_size) ; pos.y++)
1218 if (pos.x==0 || pos.x==PDATA(cursor_size)-1 ||
1219 pos.y==0 || pos.y==PDATA(cursor_size)-1 )
1220
1221 xgl_context_set_pixel (XGLTMPCTX, &pos, &green) ;
1222 else
1223 xgl_context_set_pixel (XGLTMPCTX, &pos, &black) ;
1224
1225 /* allocate and init passive cursor pixmap: gray outline, black interior */
1226 if ( !(PDATA(PassiveSquareCursor) = _dxf_ALLOCATE_PIXEL_ARRAY (PORT_CTX,
1227 PDATA(cursor_size), PDATA(cursor_size)) )) goto error ;
1228
1229 /* set pixel array as rendering surface for temporary XGL context */
1230 xgl_object_set (XGLTMPCTX,
1231 XGL_CTX_DEVICE, PDATA(PassiveSquareCursor),
1232 NULL) ;
1233
1234 for (pos.x=0 ; pos.x<PDATA(cursor_size) ; pos.x++)
1235 for (pos.y=0 ; pos.y<PDATA(cursor_size) ; pos.y++)
1236 if (pos.x==0 || pos.x==PDATA(cursor_size)-1 ||
1237 pos.y==0 || pos.y==PDATA(cursor_size)-1 )
1238
1239 xgl_context_set_pixel (XGLTMPCTX, &pos, &gray) ;
1240 else
1241 xgl_context_set_pixel (XGLTMPCTX, &pos, &black) ;
1242
1243 /* allocate and init projection mark pixmap */
1244 if ( !(PDATA(ProjectionMark) = _dxf_ALLOCATE_PIXEL_ARRAY (PORT_CTX, 3, 3)) )
1245 goto error ;
1246
1247 /* set pixel array as rendering surface for temporary XGL context */
1248 xgl_object_set (XGLTMPCTX,
1249 XGL_CTX_DEVICE, PDATA(ProjectionMark),
1250 NULL) ;
1251
1252 for (pos.x=0 ; pos.x<3 ; pos.x++)
1253 for (pos.y=0 ; pos.y<3 ; pos.y++)
1254 xgl_context_set_pixel (XGLTMPCTX, &pos, &white) ;
1255
1256 DPRINT(")") ;
1257 return ;
1258
1259 error:
1260 DPRINT("\nerror)" ) ;
1261 PDATA(cursor_saveunder) = PDATA(ActiveSquareCursor) =
1262 PDATA(PassiveSquareCursor) = PDATA(ProjectionMark) = NULL ;
1263 return ;
1264
1265 }
1266
1267 void
_dxf_DRAW_MARKER(tdmInteractor I)1268 _dxf_DRAW_MARKER (tdmInteractor I)
1269 {
1270 /*
1271 * Draw projection marks for the probe/roam interactor. Marks are the
1272 * projections of a probe/roam interactor's position onto the bounding
1273 * box.
1274 */
1275
1276 DEFDATA(I,CursorData) ;
1277 DEFPORT(I_PORT_HANDLE) ;
1278 register int i, mx, my ;
1279 Xgl_rect_af3d rect ;
1280 Xgl_rect_list rect_list ;
1281 DPRINT("\n(_dxf_DRAW_MARKER") ;
1282
1283 for (i = 0 ; i < PDATA(iMark) ; i++)
1284 {
1285 PDATA(pXmark)[i] = PDATA(Xmark)[i] ;
1286 PDATA(pYmark)[i] = PDATA(Ymark)[i] ;
1287 }
1288
1289 PDATA(piMark) = PDATA(iMark) ;
1290
1291 for (i = 0 ; i < PDATA(iMark) ; i++)
1292 {
1293 /* round marker to int */
1294 mx = (int)(PDATA(Xmark[i])+0.5) ;
1295 my = (int)(PDATA(Ymark[i])+0.5) ;
1296
1297 /* blit it */
1298 if (!CLIPPED(mx,my))
1299 _dxf_WRITE_BUFFER (PORT_CTX, mx-1, my-1, mx+1, my+1,
1300 PDATA(ProjectionMark)) ;
1301 }
1302 DPRINT(")") ;
1303 }
1304
1305 void
_dxf_ERASE_PREVIOUS_MARKS(tdmInteractor I)1306 _dxf_ERASE_PREVIOUS_MARKS (tdmInteractor I)
1307 {
1308 DEFDATA(I,CursorData) ;
1309 DEFPORT(I_PORT_HANDLE) ;
1310 Xgl_pt_i2d position ;
1311 Xgl_bounds_i2d rect ;
1312 register int i, j, mx, my ;
1313
1314 /* do nothing if interactor is invisible or backing store not available */
1315 if (!PDATA(visible) || !CDATA(image)) return ;
1316
1317 /* restore the image over the previous projection marks */
1318 for (i = 0 ; i < PDATA(piMark) ; i++)
1319 {
1320 /* round mark coordinates to int */
1321 mx = (long)(PDATA(pXmark[i])+0.5) ;
1322 my = (long)(PDATA(pYmark[i])+0.5) ;
1323
1324 if (!CLIPPED(mx,my))
1325 {
1326 rect.xmin = mx-1 ; rect.ymin = VP_YMAX - (my+1) ;
1327 rect.xmax = mx+1 ; rect.ymax = VP_YMAX - (my-1) ;
1328 position.x = rect.xmin ; position.y = rect.ymin ;
1329 #ifdef solaris
1330 xgl_context_copy_buffer (XGLCTX, &rect, &position, CDATA(image)) ;
1331 #else
1332 xgl_context_copy_raster (XGLCTX, &rect, &position, CDATA(image)) ;
1333 #endif
1334 }
1335 }
1336 }
1337
1338 void
_dxf_ERASE_CURSOR(tdmInteractor I,int x,int y)1339 _dxf_ERASE_CURSOR (tdmInteractor I, int x, int y)
1340 {
1341 /*
1342 * Erase previous probe/roam cursor position by blitting stored image.
1343 */
1344
1345 DEFDATA(I,CursorData) ;
1346 DEFPORT(I_PORT_HANDLE) ;
1347 Xgl_pt_i2d position ;
1348 Xgl_bounds_i2d rect ;
1349 int s2 ;
1350
1351 /* if not visible, nor backing store available, nor within window, return */
1352 if (!PDATA(visible) || !CDATA(image) || CLIPPED(x,y)) return ;
1353
1354 s2= PDATA(cursor_size) / 2 ;
1355 rect.xmin = x-s2 ; rect.ymin = VP_YMAX - (y+s2) ;
1356 rect.xmax = x+s2 ; rect.ymax = VP_YMAX - (y-s2) ;
1357 position.x = rect.xmin ; position.y = rect.ymin ;
1358 #ifdef solaris
1359 xgl_context_copy_buffer (XGLCTX, &rect, &position, CDATA(image)) ;
1360 #else
1361 xgl_context_copy_raster (XGLCTX, &rect, &position, CDATA(image)) ;
1362 #endif
1363 }
1364
1365
1366 void
_dxf_POINTER_INVISIBLE(void * ctx)1367 _dxf_POINTER_INVISIBLE (void *ctx)
1368 {
1369 /*
1370 * Substitute an invisible mouse pointer.
1371 */
1372
1373 DEFCONTEXT(ctx) ;
1374 int i ;
1375 Pixmap p1, p2 ;
1376 XColor fc, bc ;
1377 char tmp_bits[8] ;
1378 Cursor cursorId ;
1379 DPRINT("\n(_dxf_POINTER_INVISIBLE)") ;
1380
1381 for (i = 0 ; i < 8 ; i++)
1382 tmp_bits[i] = 0 ;
1383
1384 p1 = XCreatePixmapFromBitmapData
1385 (XGLDISPLAY, RootWindow(XGLDISPLAY, XGLSCREEN), tmp_bits, 4, 4, 0, 0, 1) ;
1386 p2 = XCreatePixmapFromBitmapData
1387 (XGLDISPLAY, RootWindow(XGLDISPLAY, XGLSCREEN), tmp_bits, 4, 4, 0, 0, 1) ;
1388
1389 cursorId = XCreatePixmapCursor (XGLDISPLAY, p1, p2, &fc, &bc, 1, 1 ) ;
1390
1391 XFreePixmap (XGLDISPLAY, p1) ;
1392 XFreePixmap (XGLDISPLAY, p2) ;
1393
1394 XDefineCursor (XGLDISPLAY, XGLXWINID, cursorId) ;
1395 }
1396
1397 void
_dxf_POINTER_VISIBLE(void * ctx)1398 _dxf_POINTER_VISIBLE (void *ctx)
1399 {
1400 /*
1401 * Use the default visible mouse pointer.
1402 */
1403
1404 DEFCONTEXT(ctx) ;
1405 DPRINT("\n(_dxf_POINTER_VISIBLE)") ;
1406
1407 XUndefineCursor (XGLDISPLAY, XGLXWINID) ;
1408 }
1409
1410 void
_dxf_WARP_POINTER(void * ctx,int x,int y)1411 _dxf_WARP_POINTER (void *ctx, int x, int y)
1412 {
1413 /*
1414 * Warp mouse pointer to specified position.
1415 */
1416
1417 DEFCONTEXT(ctx) ;
1418 DPRINT("\n(_dxf_WARP_POINTER)") ;
1419
1420 XWarpPointer (XGLDISPLAY, None, DefaultRootWindow(XGLDISPLAY), 0, 0, 0, 0,
1421 x, SCREEN_YMAX-y) ;
1422 }
1423
1424 static void
_dxf_SET_LINE_ATTRIBUTES(void * ctx,int32 color,int style,float width)1425 _dxf_SET_LINE_ATTRIBUTES (void *ctx, int32 color, int style, float width)
1426 {
1427 DEFCONTEXT(ctx) ;
1428 Xgl_color xgl_color ;
1429
1430 /*
1431 * color is packed RGB.
1432 * style 0 is solid. style 1 is dashed.
1433 * width is screen width of line, may be subpixel. not currently used.
1434 */
1435
1436 switch (color)
1437 {
1438 case 0x8f8f8f8f:
1439 xgl_color.rgb.r = 0.5 ; xgl_color.rgb.g = 0.5 ; xgl_color.rgb.b = 0.5 ;
1440 break ;
1441 case 0xffffffff:
1442 default:
1443 xgl_color.rgb.r = 1.0 ; xgl_color.rgb.g = 1.0 ; xgl_color.rgb.b = 1.0 ;
1444 break ;
1445 }
1446
1447 xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR, &xgl_color, NULL) ;
1448
1449 switch (style)
1450 {
1451 case 1:
1452 xgl_object_set (XGLCTX, XGL_CTX_LINE_STYLE, XGL_LINE_PATTERNED, 0) ;
1453 xgl_object_set (XGLCTX, XGL_CTX_LINE_PATTERN, xgl_lpat_dashed, 0);
1454 break ;
1455 case 0:
1456 default:
1457 xgl_object_set (XGLCTX, XGL_CTX_LINE_STYLE, XGL_LINE_SOLID, 0) ;
1458 break ;
1459 }
1460 }
1461
1462
1463 void
_dxf_SET_LINE_COLOR_WHITE(void * ctx)1464 _dxf_SET_LINE_COLOR_WHITE (void *ctx)
1465 {
1466 /* obsolete entry: do not use in new code */
1467 DEFCONTEXT(ctx) ;
1468 Xgl_color color ;
1469
1470 color.rgb.r = 1.0 ; color.rgb.g = 1.0 ; color.rgb.b = 1.0 ;
1471 xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR, &color, NULL) ;
1472 }
1473
1474 void
_dxf_SET_LINE_COLOR_GRAY(void * ctx)1475 _dxf_SET_LINE_COLOR_GRAY (void *ctx)
1476 {
1477 /* obsolete entry: do not use in new code */
1478 DEFCONTEXT(ctx) ;
1479 Xgl_color color ;
1480
1481 color.rgb.r = 0.5 ; color.rgb.g = 0.5 ; color.rgb.b = 0.5 ;
1482 xgl_object_set (XGLCTX, XGL_CTX_LINE_COLOR, &color, NULL) ;
1483 }
1484
1485 void
_dxf_DRAW_LINE(void * ctx,int x1,int y1,int x2,int y2)1486 _dxf_DRAW_LINE(void *ctx, int x1, int y1, int x2, int y2)
1487 {
1488 /*
1489 * Used for cursor box.
1490 */
1491
1492 DEFCONTEXT(ctx) ;
1493 Xgl_pt_list line ;
1494 static Xgl_pt_f3d verts[2] = {0, 0, 0, 0, 0, 0} ;
1495
1496 DPRINT("\n(_dxf_DRAW_LINE") ;
1497 DPRINT1("\n%d", x1) ; DPRINT1(" %d", y1) ;
1498 DPRINT1("\n%d", x2) ; DPRINT1(" %d", y2) ;
1499
1500 line.pt_type = XGL_PT_F3D ;
1501 line.bbox = NULL ;
1502 line.num_pts = 2 ;
1503 line.pts.f3d = verts ;
1504
1505 verts[0].x = x1 ;
1506 verts[0].y = y1 ;
1507 verts[1].x = x2 ;
1508 verts[1].y = y2 ;
1509
1510 xgl_multipolyline (XGLCTX, NULL, 1, &line) ;
1511 DPRINT(")") ;
1512 }
1513
1514 void
_dxf_DRAW_CURSOR_COORDS(tdmInteractor I,char * text)1515 _dxf_DRAW_CURSOR_COORDS (tdmInteractor I, char *text)
1516 {
1517 /*
1518 * Draw cursor coordinates at specified position.
1519 */
1520
1521 DEFDATA(I,CursorData) ;
1522 DEFPORT(I_PORT_HANDLE) ;
1523 Xgl_pt_f3d pos, offs ;
1524 Xgl_color white, black ;
1525
1526 white.rgb.r = 1.0 ;
1527 white.rgb.g = 1.0 ;
1528 white.rgb.b = 1.0 ;
1529
1530 black.rgb.r = 0.0 ;
1531 black.rgb.g = 0.0 ;
1532 black.rgb.b = 0.0 ;
1533
1534 offs.x = 0 ; offs.y = 0 ; offs.z = 0 ; pos.z = 0 ;
1535
1536 #ifdef solaris
1537 xgl_object_set (XGLCTX,
1538 XGL_CTX_ATEXT_CHAR_HEIGHT, 0.036,
1539 XGL_CTX_STEXT_CHAR_EXPANSION_FACTOR, 0.7,
1540 XGL_CTX_STEXT_COLOR, &black,
1541 NULL) ;
1542 #else
1543 xgl_object_set (XGLCTX,
1544 XGL_CTX_ANNOT_CHAR_HEIGHT, 0.036,
1545 XGL_CTX_SFONT_CHAR_EXPANSION_FACTOR, 0.7,
1546 XGL_CTX_SFONT_TEXT_COLOR, &black,
1547 NULL) ;
1548 #endif
1549
1550 pos.x = PDATA(coord_llx)+5 ; pos.y = PDATA(coord_lly)+3 ;
1551 xgl_annotation_text (XGLCTX, text, &pos, &offs) ;
1552
1553 xgl_object_set (XGLCTX,
1554 #ifdef solaris
1555 XGL_CTX_STEXT_COLOR, &white,
1556 #else
1557 XGL_CTX_SFONT_TEXT_COLOR, &white,
1558 #endif
1559 NULL) ;
1560
1561 pos.x = PDATA(coord_llx)+4 ; pos.y = PDATA(coord_lly)+4 ;
1562 xgl_annotation_text (XGLCTX, text, &pos, &offs) ;
1563
1564 }
1565
1566 tdmInteractorEchoT _dxd_hwInteractorEchoPort =
1567 {
1568 /* BufferConfig */ _dxf_BUFFER_CONFIG,
1569 /* BufferRestoreConfig */ _dxf_BUFFER_RESTORE_CONFIG,
1570 /* CreateCurXFsorPixmaps */ _dxf_CREATE_CURSOR_PIXMAPS,
1571 /* DrawArrowhead */ _dxf_DRAW_ARROWHEAD,
1572 /* DrawCursorCoords */ _dxf_DRAW_CURSOR_COORDS,
1573 /* DrawGlobe */ _dxf_DRAW_GLOBE,
1574 /* DrawGnomon */ _dxf_DRAW_GNOMON,
1575 /* DrawLine */ _dxf_DRAW_LINE,
1576 /* DrawMarker */ _dxf_DRAW_MARKER,
1577 /* DrawZoombox */ _dxf_DRAW_ZOOMBOX,
1578 /* EraseCursor */ _dxf_ERASE_CURSOR,
1579 /* ErasePreviousMarks */ _dxf_ERASE_PREVIOUS_MARKS,
1580 /* GetMaxscreen */ _dxf_GET_MAXSCREEN,
1581 /* GetWindowOrigin */ _dxf_GET_WINDOW_ORIGIN,
1582 /* GetZbufferStatus */ _dxf_GET_ZBUFFER_STATUS,
1583 /* PointerInvisible */ _dxf_POINTER_INVISIBLE,
1584 /* PointerVisible */ _dxf_POINTER_VISIBLE,
1585 /* ReadBuffer */ _dxf_READ_BUFFER,
1586 /* SetLineColorGray */ _dxf_SET_LINE_COLOR_GRAY,
1587 /* SetLineColorWhite */ _dxf_SET_LINE_COLOR_WHITE,
1588 /* SetSolidFillPattern */ _dxf_SET_SOLID_FILL_PATTERN,
1589 /* SetWorldScreen */ _dxf_SET_WORLD_SCREEN,
1590 /* SetZbufferStatus */ _dxf_SET_ZBUFFER_STATUS,
1591 /* WarpPointer */ _dxf_WARP_POINTER,
1592 /* WriteBuffer */ _dxf_WRITE_BUFFER,
1593 /* SetLineAttributes */ _dxf_SET_LINE_ATTRIBUTES
1594 };
1595