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