1/*
2 * Copyright (c) 2003 by the XFree86 Project, Inc.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28/*
29 * Create a window and use the DMX extension to query the window's
30 * back-end properties.  Display the info inside the window itself.
31 *
32 * Brian Paul
33 * 23 Jan 2003
34 */
35
36#include <assert.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <X11/Xlib.h>
41#include <X11/Xutil.h>
42#include <X11/Xmu/SysUtil.h>
43#include <X11/extensions/dmxext.h>
44
45static const char *FontName = "fixed";
46
47
48static void
49EventLoop(Display *dpy, Window win, GC gc)
50{
51   XEvent ev;
52   while (1) {
53      XNextEvent( dpy, &ev );
54      switch (ev.type) {
55      case ReparentNotify:
56         break;
57      case MapNotify:
58         break;
59      case ConfigureNotify:
60      case Expose:
61         {
62            int numScreens, count, i;
63            DMXWindowAttributes *winInfo;
64            int x, y;
65            const char *msg = "DMX window info:";
66
67            DMXGetScreenCount(dpy, &numScreens);
68            winInfo
69                = (DMXWindowAttributes *)
70                malloc(numScreens * sizeof(DMXWindowAttributes));
71            assert(winInfo);
72            if (!DMXGetWindowAttributes(dpy, win, &count,
73                                        numScreens, winInfo)) {
74               printf("Could not get window information for 0x%08lx\n",
75                      (long unsigned)win);
76            }
77            x = y = 50;
78            XClearWindow(dpy, win);
79            XDrawString(dpy, win, gc, x, y, msg, strlen(msg));
80            y += 20;
81            for (i = 0; i < count; i++) {
82               char str[500];
83               XmuSnprintf(str, sizeof(str),
84                       "screen %d:  pos: %dx%d+%d+%d  visible: %dx%d+%d+%d",
85                       winInfo[i].screen,
86                       winInfo[i].pos.width, winInfo[i].pos.height,
87                       winInfo[i].pos.x, winInfo[i].pos.y,
88                       winInfo[i].vis.width, winInfo[i].vis.height,
89                       winInfo[i].vis.x, winInfo[i].vis.y);
90               XDrawString(dpy, win, gc, x, y, str, strlen(str));
91               y += 20;
92            }
93            free(winInfo);
94         }
95         break;
96      default:
97         printf("Event type 0x%x\n", ev.type);
98      }
99   }
100}
101
102int
103main(int argc, char *argv[])
104{
105   const char *displayName = NULL;
106   Display *dpy;
107   int event_base, error_base;
108   int scr, n;
109   long vinfoMask, attrMask;
110   XVisualInfo vinfoTemp, *visInfo;
111   Visual *vis;
112   Window win, root;
113   XSetWindowAttributes attr;
114   XFontStruct *fontInfo;
115   GC gc;
116
117   if (argc > 1) {
118      displayName = argv[1];
119   }
120
121   dpy = XOpenDisplay(displayName);
122   if (!dpy) {
123      fprintf(stderr, "Unable to open display %s\n", displayName);
124      return -1;
125   }
126
127   if (!DMXQueryExtension(dpy, &event_base, &error_base)) {
128      fprintf(stderr, "DMX extension not available on this display.\n");
129      return -1;
130   }
131
132   scr = DefaultScreen(dpy);
133   root = RootWindow(dpy, scr);
134   vis = DefaultVisual(dpy, scr);
135
136   vinfoMask = VisualIDMask;
137   vinfoTemp.visualid = vis->visualid;
138   visInfo = XGetVisualInfo(dpy, vinfoMask, &vinfoTemp, &n);
139   if (!visInfo || n != 1) {
140      fprintf(stderr, "Unable to get visual!\n");
141      XCloseDisplay(dpy);
142      return -1;
143   }
144
145   attr.background_pixel = 0;
146   attr.border_pixel = 0;
147   attr.colormap = XCreateColormap(dpy, root, visInfo->visual, AllocNone);
148   attr.event_mask = StructureNotifyMask | ExposureMask;
149   attrMask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
150
151   win = XCreateWindow(dpy, root,
152                       500, 500, 600, 400,  /* x, y, w, h */
153                       0, /* border_width */
154                       visInfo->depth, InputOutput,
155		       visInfo->visual, attrMask, &attr);
156
157
158   if (!win) {
159      fprintf(stderr, "Unable to create window!\n");
160      XCloseDisplay(dpy);
161      return -1;
162   }
163
164   fontInfo = XLoadQueryFont(dpy, FontName);
165   if (!fontInfo) {
166      fprintf(stderr, "Error: font %s not found\n", FontName);
167      exit(0);
168   }
169
170   gc = XCreateGC(dpy, win, 0, NULL);
171   XSetBackground(dpy, gc, BlackPixel(dpy, scr));
172   XSetForeground(dpy, gc, WhitePixel(dpy, scr));
173   XSetFont(dpy, gc, fontInfo->fid);
174
175   XMapWindow(dpy, win);
176
177   EventLoop(dpy, win, gc);
178
179   XDestroyWindow(dpy, win);
180   XCloseDisplay(dpy);
181   return 0;
182}
183
184#if 00
185
186static void make_window( char *title, int color_flag )
187{
188   int x = 10, y = 10, width = 400, height = 300;
189   Display *dpy;
190   int scr;
191   Window root, win;
192   Colormap cmap;
193   XColor xcolor;
194   int attr_flags;
195   XVisualInfo *visinfo;
196   XSetWindowAttributes attr;
197   XTextProperty tp;
198   XSizeHints sh;
199   XEvent e;
200   XMesaContext context;
201   XMesaVisual visual;
202   XMesaBuffer buffer;
203
204
205   /*
206    * Do the usual X things to make a window.
207    */
208
209   dpy = XOpenDisplay(NULL);
210   if (!dpy) {
211      printf("Couldn't open default display!\n");
212      exit(1);
213   }
214
215   scr = DefaultScreen(dpy);
216   root = RootWindow(dpy, scr);
217
218   /* alloc visinfo struct */
219   visinfo = (XVisualInfo *) malloc( sizeof(XVisualInfo) );
220
221   /* Get a visual and colormap */
222   if (color_flag) {
223      /* Open TrueColor window */
224
225/*
226      if (!XMatchVisualInfo( dpy, scr, 24, TrueColor, visinfo )) {
227	 printf("Couldn't get 24-bit TrueColor visual!\n");
228	 exit(1);
229      }
230*/
231      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
232	 printf("Couldn't get 8-bit PseudoColor visual!\n");
233	 exit(1);
234      }
235
236      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
237      Black = Red = Green = Blue = 0;
238   }
239   else {
240      /* Open color index window */
241
242      if (!XMatchVisualInfo( dpy, scr, 8, PseudoColor, visinfo )) {
243	 printf("Couldn't get 8-bit PseudoColor visual\n");
244	 exit(1);
245      }
246
247      cmap = XCreateColormap( dpy, root, visinfo->visual, AllocNone );
248
249      /* Allocate colors */
250      xcolor.red   = 0x0;
251      xcolor.green = 0x0;
252      xcolor.blue  = 0x0;
253      xcolor.flags = DoRed | DoGreen | DoBlue;
254      if (!XAllocColor( dpy, cmap, &xcolor )) {
255	 printf("Couldn't allocate black!\n");
256	 exit(1);
257      }
258      Black = xcolor.pixel;
259
260      xcolor.red   = 0xffff;
261      xcolor.green = 0x0;
262      xcolor.blue  = 0x0;
263      xcolor.flags = DoRed | DoGreen | DoBlue;
264      if (!XAllocColor( dpy, cmap, &xcolor )) {
265	 printf("Couldn't allocate red!\n");
266	 exit(1);
267      }
268      Red = xcolor.pixel;
269
270      xcolor.red   = 0x0;
271      xcolor.green = 0xffff;
272      xcolor.blue  = 0x0;
273      xcolor.flags = DoRed | DoGreen | DoBlue;
274      if (!XAllocColor( dpy, cmap, &xcolor )) {
275	 printf("Couldn't allocate green!\n");
276	 exit(1);
277      }
278      Green = xcolor.pixel;
279
280      xcolor.red   = 0x0;
281      xcolor.green = 0x0;
282      xcolor.blue  = 0xffff;
283      xcolor.flags = DoRed | DoGreen | DoBlue;
284      if (!XAllocColor( dpy, cmap, &xcolor )) {
285	 printf("Couldn't allocate blue!\n");
286	 exit(1);
287      }
288      Blue = xcolor.pixel;
289   }
290
291   /* set window attributes */
292   attr.colormap = cmap;
293   attr.event_mask = ExposureMask | StructureNotifyMask;
294   attr.border_pixel = BlackPixel( dpy, scr );
295   attr.background_pixel = BlackPixel( dpy, scr );
296   attr_flags = CWColormap | CWEventMask | CWBorderPixel | CWBackPixel;
297
298   /* Create the window */
299   win = XCreateWindow( dpy, root, x,y, width, height, 0,
300			    visinfo->depth, InputOutput,
301			    visinfo->visual,
302			    attr_flags, &attr);
303   if (!win) {
304      printf("Couldn't open window!\n");
305      exit(1);
306   }
307
308   XStringListToTextProperty(&title, 1, &tp);
309   sh.flags = USPosition | USSize;
310   XSetWMProperties(dpy, win, &tp, &tp, 0, 0, &sh, 0, 0);
311   XMapWindow(dpy, win);
312   while (1) {
313      XNextEvent( dpy, &e );
314      if (e.type == MapNotify && e.xmap.window == win) {
315	 break;
316      }
317   }
318
319
320   /*
321    * Now do the special Mesa/Xlib stuff!
322    */
323
324   visual = XMesaCreateVisual( dpy, visinfo,
325                              (GLboolean) color_flag,
326                               GL_FALSE,  /* alpha_flag */
327                               GL_FALSE,  /* db_flag */
328                               GL_FALSE,  /* stereo flag */
329                               GL_FALSE,  /* ximage_flag */
330                               0,         /* depth size */
331                               0,         /* stencil size */
332                               0,0,0,0,   /* accum_size */
333                               0,         /* num samples */
334                               0,         /* level */
335                               0          /* caveat */
336                              );
337   if (!visual) {
338      printf("Couldn't create Mesa/X visual!\n");
339      exit(1);
340   }
341
342   /* Create a Mesa rendering context */
343   context = XMesaCreateContext( visual,
344                                 NULL       /* share_list */
345                               );
346   if (!context) {
347      printf("Couldn't create Mesa/X context!\n");
348      exit(1);
349   }
350
351   buffer = XMesaCreateWindowBuffer( visual, win );
352   if (!buffer) {
353      printf("Couldn't create Mesa/X buffer!\n");
354      exit(1);
355   }
356
357
358   XMesaMakeCurrent( context, buffer );
359
360   /* Ready to render! */
361}
362
363
364
365static void draw_cube( void )
366{
367   /* X faces */
368   glIndexi( Red );
369   glColor3f( 1.0, 0.0, 0.0 );
370   glBegin( GL_POLYGON );
371   glVertex3f( 1.0, 1.0, 1.0 );
372   glVertex3f( 1.0, -1.0, 1.0 );
373   glVertex3f( 1.0, -1.0, -1.0 );
374   glVertex3f( 1.0, 1.0, -1.0 );
375   glEnd();
376
377   glBegin( GL_POLYGON );
378   glVertex3f( -1.0, 1.0, 1.0 );
379   glVertex3f( -1.0, 1.0, -1.0 );
380   glVertex3f( -1.0, -1.0, -1.0 );
381   glVertex3f( -1.0, -1.0, 1.0 );
382   glEnd();
383
384   /* Y faces */
385   glIndexi( Green );
386   glColor3f( 0.0, 1.0, 0.0 );
387   glBegin( GL_POLYGON );
388   glVertex3f(  1.0, 1.0,  1.0 );
389   glVertex3f(  1.0, 1.0, -1.0 );
390   glVertex3f( -1.0, 1.0, -1.0 );
391   glVertex3f( -1.0, 1.0,  1.0 );
392   glEnd();
393
394   glBegin( GL_POLYGON );
395   glVertex3f(  1.0, -1.0,  1.0 );
396   glVertex3f( -1.0, -1.0,  1.0 );
397   glVertex3f( -1.0, -1.0, -1.0 );
398   glVertex3f(  1.0, -1.0, -1.0 );
399   glEnd();
400
401   /* Z faces */
402   glIndexi( Blue );
403   glColor3f( 0.0, 0.0, 1.0 );
404   glBegin( GL_POLYGON );
405   glVertex3f(  1.0,  1.0,  1.0 );
406   glVertex3f( -1.0,  1.0,  1.0 );
407   glVertex3f( -1.0, -1.0,  1.0 );
408   glVertex3f(  1.0, -1.0,  1.0 );
409   glEnd();
410
411   glBegin( GL_POLYGON );
412   glVertex3f(  1.0, 1.0, -1.0 );
413   glVertex3f(  1.0,-1.0, -1.0 );
414   glVertex3f( -1.0,-1.0, -1.0 );
415   glVertex3f( -1.0, 1.0, -1.0 );
416   glEnd();
417}
418
419
420
421
422static void display_loop( void )
423{
424   GLfloat xrot, yrot, zrot;
425
426   xrot = yrot = zrot = 0.0;
427
428   glClearColor( 0.0, 0.0, 0.0, 0.0 );
429   glClearIndex( Black );
430
431   glMatrixMode( GL_PROJECTION );
432   glLoadIdentity();
433   glFrustum( -1.0, 1.0,  -1.0, 1.0,  1.0, 10.0 );
434   glTranslatef( 0.0, 0.0, -5.0 );
435
436   glMatrixMode( GL_MODELVIEW );
437   glLoadIdentity();
438
439   glCullFace( GL_BACK );
440   glEnable( GL_CULL_FACE );
441
442   glShadeModel( GL_FLAT );
443
444   while (1) {
445      glClear( GL_COLOR_BUFFER_BIT );
446      glPushMatrix();
447      glRotatef( xrot, 1.0, 0.0, 0.0 );
448      glRotatef( yrot, 0.0, 1.0, 0.0 );
449      glRotatef( zrot, 0.0, 0.0, 1.0 );
450
451      draw_cube();
452
453      glPopMatrix();
454      glFinish();
455
456      xrot += 10.0;
457      yrot += 7.0;
458      zrot -= 3.0;
459   }
460
461}
462
463
464
465
466int main( int argc, char *argv[] )
467{
468   int mode = 0;
469
470   if (argc >= 2)
471   {
472        if (strcmp(argv[1],"-ci")==0)
473           mode = 0;
474        else if (strcmp(argv[1],"-rgb")==0)
475           mode = 1;
476        else
477        {
478           printf("Bad flag: %s\n", argv[1]);
479           printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
480           exit(1);
481        }
482   }
483   else
484   {
485        printf("Specify -ci for 8-bit color index or -rgb for RGB mode\n");
486        printf("Defaulting to  8-bit color index\n");
487   }
488
489   make_window( argv[0], mode );
490
491   display_loop();
492   return 0;
493}
494
495
496#endif
497