291 ! ! |
293 ! ! |
292 |
294 |
293 !GLXWorkstation primitiveFunctions! |
295 !GLXWorkstation primitiveFunctions! |
294 |
296 |
295 %{ |
297 %{ |
|
298 |
|
299 /* |
|
300 * begin moved from GLXsupport.c |
|
301 */ |
|
302 |
|
303 /* |
|
304 * GLXsupport.c: |
|
305 * |
|
306 * This file provides a helper function "GLXCreateWindow", which does |
|
307 * all the necessary magic to create an X window suitable for GL drawing |
|
308 * to take place within. see the definition of GLXCreateWindow for a |
|
309 * description of how to call it. |
|
310 * |
|
311 * claus: I really had no time to look into all this, |
|
312 * this file has been just copied from a 4Dgifts demo .. |
|
313 * (will need more than a day to show more ...) |
|
314 */ |
|
315 #if defined(GLX) || defined(VGL) |
|
316 |
|
317 #include <X11/Xlib.h> |
|
318 #include <X11/Xutil.h> |
|
319 #ifndef VGL |
|
320 # include <gl/glws.h> |
|
321 #endif |
|
322 #include <signal.h> |
|
323 #include <setjmp.h> |
|
324 #include "stcIntern.h" |
|
325 |
|
326 /* |
|
327 * glxhelper.h: |
|
328 * |
|
329 * List of drawing modes supported by GLXCreateWindow (in glxhelper.c). |
|
330 * More than this are possible with mixed model, but this is just an |
|
331 * example. You can either expand this list (and the corresponding code in |
|
332 * GLXCreateWindow) or call the mixed model calls yourself, using |
|
333 * GLXCreateWindow as an example. |
|
334 */ |
|
335 |
|
336 static char *typeToName[] = { |
|
337 "color index single buffer", |
|
338 "color index double buffer", |
|
339 "rgb single buffer", |
|
340 "rgb double buffer", |
|
341 }; |
|
342 |
|
343 #ifndef VGL |
|
344 /* |
|
345 * Dorky little helper function used to build up a GLXconfig array. |
|
346 */ |
|
347 |
|
348 static void set_entry (GLXconfig* ptr, int b, int m, int a) |
|
349 { |
|
350 ptr->buffer = b; |
|
351 ptr->mode = m; |
|
352 ptr->arg = a; |
|
353 } |
|
354 #endif /* VGL */ |
|
355 |
|
356 static JMP_BUF errorReturn; |
|
357 |
|
358 static void |
|
359 glAbort() { |
|
360 longjmp(errorReturn, 1); |
|
361 } |
|
362 |
|
363 /* |
|
364 * GLXCreateWindow(dpy, parent, x, y, w, h, boderWidth, type) |
|
365 * |
|
366 * Return value is the X window id of the newly created window. |
|
367 * |
|
368 * Arguments are: |
|
369 * dpy The X "Display*" returned by XOpenDisplay |
|
370 * parent The parent of the newly created window, |
|
371 * a typical value for this is |
|
372 * RootWindow(dpy, DefaultScreen(dpy)) |
|
373 * x,y The location of the window to be created, |
|
374 * y coordinate is measured from the top down. |
|
375 * w,h size of the new window |
|
376 * borderWidth the X border size for this window, should probably |
|
377 * be zero. |
|
378 * type the GLXWindowType (see glxhelper.h) desribing the |
|
379 * typer of GL drawing to be done in this window |
|
380 */ |
|
381 static Window |
|
382 GLXCreateWindow(dpy, parent, x, y, w, h, borderWidth, type) |
|
383 Display* dpy; |
|
384 Window parent; |
|
385 GLXWindowType type; |
|
386 { |
|
387 #ifdef VGL |
|
388 Visual visual; |
|
389 #else |
|
390 GLXconfig params[50]; |
|
391 GLXconfig* next; |
|
392 GLXconfig* retconfig; |
|
393 Colormap cmap = DefaultColormap(dpy, DefaultScreen(dpy)); |
|
394 XVisualInfo *vis; |
|
395 #endif |
|
396 XVisualInfo template; |
|
397 XColor white; |
|
398 XSetWindowAttributes cwa; |
|
399 XWindowAttributes pwa; |
|
400 int scr, i, nret; |
|
401 Window win; |
|
402 extern __XErrorHandler__(); |
|
403 #ifdef IRIX5 |
|
404 SIG_PF oldSig; |
|
405 #else |
|
406 void *oldSig; |
|
407 #endif |
|
408 |
|
409 if (setjmp(errorReturn)) { |
|
410 printf("hard error in GL - return\n"); |
|
411 signal(SIGSEGV, oldSig); |
|
412 return 0; |
|
413 } |
|
414 __CONT__ |
|
415 |
|
416 #ifdef VGL |
|
417 /* |
|
418 * I know what VGL supports; its somewhat unclean to hard code it here |
|
419 */ |
|
420 switch (type) { |
|
421 case GLXcolorIndexSingleBuffer: |
|
422 case GLXcolorIndexDoubleBuffer: |
|
423 break; |
|
424 |
|
425 case GLXrgbSingleBuffer: |
|
426 case GLXrgbDoubleBuffer: |
|
427 printf("Sorry, VGL can't support %s type of windows\n", typeToName[type]); |
|
428 return 0; |
|
429 } |
|
430 |
|
431 scr = DefaultScreen(dpy); |
|
432 visual.visualid = CopyFromParent; |
|
433 cwa.border_pixel = 0; /* Even if we don't use it, it must be something */ |
|
434 if (w <= 0) { |
|
435 printf("VGL: bad width: %d\n", w); |
|
436 w = 1; |
|
437 } |
|
438 if (h <= 0) { |
|
439 printf("VGL: bad height: %d\n", h); |
|
440 h = 1; |
|
441 } |
|
442 win = XCreateWindow(dpy, parent, x, y, w, h, |
|
443 borderWidth, DisplayPlanes(dpy, scr), |
|
444 InputOutput, &visual, |
|
445 CWBorderPixel, &cwa); |
|
446 |
|
447 /* |
|
448 * on iris, seg-violations occur in te GL, if too many |
|
449 * views are created ... just to make certain, we catch those |
|
450 * in GL too. |
|
451 */ |
|
452 oldSig = signal(SIGSEGV, glAbort); |
|
453 i = GLXlink(dpy, win); |
|
454 signal(SIGSEGV, oldSig); |
|
455 |
|
456 if (i < 0) { |
|
457 printf("GLXlink returned %d\n", i); |
|
458 return 0; |
|
459 } |
|
460 #else /* not VGL */ |
|
461 /* |
|
462 * This builds an array in "params" that describes for GLXgetconfig(3G) |
|
463 * the type of GL drawing that will be done. |
|
464 */ |
|
465 next = params; |
|
466 switch (type) { |
|
467 case GLXcolorIndexSingleBuffer: |
|
468 set_entry(next++, GLX_NORMAL, GLX_RGB, FALSE); |
|
469 set_entry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE); |
|
470 break; |
|
471 case GLXcolorIndexDoubleBuffer: |
|
472 set_entry(next++, GLX_NORMAL, GLX_RGB, FALSE); |
|
473 set_entry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE); |
|
474 break; |
|
475 case GLXrgbSingleBuffer: |
|
476 set_entry(next++, GLX_NORMAL, GLX_RGB, TRUE); |
|
477 set_entry(next++, GLX_NORMAL, GLX_DOUBLE, FALSE); |
|
478 break; |
|
479 case GLXrgbDoubleBuffer: |
|
480 set_entry(next++, GLX_NORMAL, GLX_RGB, TRUE); |
|
481 set_entry(next++, GLX_NORMAL, GLX_DOUBLE, TRUE); |
|
482 break; |
|
483 } |
|
484 set_entry(next, 0, 0, 0); /* The input to GLXgetconfig is null terminated */ |
|
485 |
|
486 /* |
|
487 * Get configuration data for a window based on above parameters |
|
488 * First we have to find out which screen the parent window is on, |
|
489 * then we can call GXLgetconfig() |
|
490 */ |
|
491 XGetWindowAttributes(dpy, parent, &pwa); |
|
492 retconfig = GLXgetconfig(dpy, XScreenNumberOfScreen(pwa.screen), params); |
|
493 if (retconfig == 0) { |
|
494 printf("Sorry, can't support %s type of windows\n", typeToName[type]); |
|
495 return 0; |
|
496 } |
|
497 |
|
498 /* |
|
499 * Scan through config info, pulling info needed to create a window |
|
500 * that supports the rendering mode. |
|
501 */ |
|
502 for (next = retconfig; next->buffer; next++) { |
|
503 unsigned long buffer = next->buffer; |
|
504 unsigned long mode = next->mode; |
|
505 unsigned long value = next->arg; |
|
506 switch (mode) { |
|
507 case GLX_COLORMAP: |
|
508 if (buffer == GLX_NORMAL) { |
|
509 cmap = value; |
|
510 } |
|
511 break; |
|
512 case GLX_VISUAL: |
|
513 if (buffer == GLX_NORMAL) { |
|
514 template.visualid = value; |
|
515 template.screen = DefaultScreen(dpy); |
|
516 vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask, |
|
517 &template, &nret); |
|
518 } |
|
519 break; |
|
520 } |
|
521 } |
|
522 |
|
523 /* |
|
524 * Create the window |
|
525 */ |
|
526 cwa.colormap = cmap; |
|
527 cwa.border_pixel = 0; /* Even if we don't use it, it must be something */ |
|
528 win = XCreateWindow(dpy, parent, x, y, w, h, |
|
529 borderWidth, vis->depth, InputOutput, vis->visual, |
|
530 CWColormap|CWBorderPixel, &cwa); |
|
531 |
|
532 /* |
|
533 * Rescan configuration info and find window slot that getconfig |
|
534 * provided. Fill it in with the window we just created. |
|
535 */ |
|
536 for (next = retconfig; next->buffer; next++) { |
|
537 if ((next->buffer == GLX_NORMAL) && (next->mode == GLX_WINDOW)) { |
|
538 next->arg = win; |
|
539 break; |
|
540 } |
|
541 } |
|
542 |
|
543 /* |
|
544 * Now "retconfig" contains all the information the GL needs to |
|
545 * configure the window and its own internal state. |
|
546 */ |
|
547 /* |
|
548 * on iris, seg-violations occur in te GL, if too many |
|
549 * views are created ... |
|
550 */ |
|
551 oldSig = signal(SIGSEGV, glAbort); |
|
552 i = GLXlink(dpy, retconfig); |
|
553 signal(SIGSEGV, oldSig); |
|
554 |
|
555 if (i < 0) { |
|
556 printf("GLXlink returned %d\n", i); |
|
557 return 0; |
|
558 } |
|
559 |
|
560 /* |
|
561 * The GL sets its own X error handlers, which exits - this is not what we want |
|
562 */ |
|
563 XSetErrorHandler(__XErrorHandler__); |
|
564 #endif |
|
565 return win; |
|
566 } |
|
567 |
|
568 static |
|
569 GLXUnlinkWindow(dpy, win) |
|
570 Display* dpy; |
|
571 Window win; |
|
572 { |
|
573 /* |
|
574 * only needed for VGL - GLX does it automatically |
|
575 */ |
|
576 #ifdef VGL |
|
577 GLXunlink(dpy, win); |
|
578 #endif |
|
579 } |
|
580 |
|
581 #endif /* GLX or VGL */ |
|
582 |
|
583 /* |
|
584 * end moved from GLXsupport.c |
|
585 */ |
|
586 |
296 /* |
587 /* |
297 * helper for rotation - call rot() |
588 * helper for rotation - call rot() |
298 */ |
589 */ |
299 static OBJ |
590 static OBJ |
300 doRotate(angle, axis) |
591 doRotate(angle, axis) |