/gfx.c

https://github.com/blaws/Eye · C · 203 lines · 131 code · 48 blank · 24 comment · 20 complexity · 49454fd4ba52fd4f74e0cfef460397fc MD5 · raw file

  1. /*
  2. A simple graphics library for CSE 20211 by Douglas Thain
  3. For complete documentation, see:
  4. http://www.nd.edu/~dthain/courses/cse20211/fall2011/gfx
  5. Version 3, 11/07/2012 - Now much faster at changing colors rapidly.
  6. Version 2, 9/23/2011 - Fixes a bug that could result in jerky animation.
  7. */
  8. #include <X11/Xlib.h>
  9. #include <unistd.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "gfx.h"
  13. /*
  14. gfx_open creates several X11 objects, and stores them in globals
  15. for use by the other functions in the library.
  16. */
  17. static Display *gfx_display=0;
  18. static Window gfx_window;
  19. static GC gfx_gc;
  20. static Colormap gfx_colormap;
  21. static int gfx_fast_color_mode = 0;
  22. /* These values are saved by gfx_wait then retrieved later by gfx_xpos and gfx_ypos. */
  23. static int saved_xpos = 0;
  24. static int saved_ypos = 0;
  25. /* Open a new graphics window. */
  26. void gfx_open( int width, int height, const char *title )
  27. {
  28. gfx_display = XOpenDisplay(0);
  29. if(!gfx_display) {
  30. fprintf(stderr,"gfx_open: unable to open the graphics window.\n");
  31. exit(1);
  32. }
  33. Visual *visual = DefaultVisual(gfx_display,0);
  34. if(visual && visual->class==TrueColor) {
  35. gfx_fast_color_mode = 1;
  36. } else {
  37. gfx_fast_color_mode = 0;
  38. }
  39. int blackColor = BlackPixel(gfx_display, DefaultScreen(gfx_display));
  40. int whiteColor = WhitePixel(gfx_display, DefaultScreen(gfx_display));
  41. gfx_window = XCreateSimpleWindow(gfx_display, DefaultRootWindow(gfx_display), 0, 0, width, height, 0, blackColor, blackColor);
  42. XSetWindowAttributes attr;
  43. attr.backing_store = Always;
  44. XChangeWindowAttributes(gfx_display,gfx_window,CWBackingStore,&attr);
  45. XStoreName(gfx_display,gfx_window,title);
  46. XSelectInput(gfx_display, gfx_window, StructureNotifyMask|KeyPressMask|ButtonPressMask);
  47. XMapWindow(gfx_display,gfx_window);
  48. gfx_gc = XCreateGC(gfx_display, gfx_window, 0, 0);
  49. gfx_colormap = DefaultColormap(gfx_display,0);
  50. XSetForeground(gfx_display, gfx_gc, whiteColor);
  51. // Wait for the MapNotify event
  52. for(;;) {
  53. XEvent e;
  54. XNextEvent(gfx_display, &e);
  55. if (e.type == MapNotify)
  56. break;
  57. }
  58. }
  59. /* Draw a single point at (x,y) */
  60. void gfx_point( int x, int y )
  61. {
  62. XDrawPoint(gfx_display,gfx_window,gfx_gc,x,y);
  63. }
  64. /* Draw a line from (x1,y1) to (x2,y2) */
  65. void gfx_line( int x1, int y1, int x2, int y2 )
  66. {
  67. XDrawLine(gfx_display,gfx_window,gfx_gc,x1,y1,x2,y2);
  68. }
  69. /* Change the current drawing color. */
  70. void gfx_color( int r, int g, int b )
  71. {
  72. XColor color;
  73. if(gfx_fast_color_mode) {
  74. /* If this is a truecolor display, we can just pick the color directly. */
  75. color.pixel = ((b&0xff) | ((g&0xff)<<8) | ((r&0xff)<<16) );
  76. } else {
  77. /* Otherwise, we have to allocate it from the colormap of the display. */
  78. color.pixel = 0;
  79. color.red = r<<8;
  80. color.green = g<<8;
  81. color.blue = b<<8;
  82. XAllocColor(gfx_display,gfx_colormap,&color);
  83. }
  84. XSetForeground(gfx_display, gfx_gc, color.pixel);
  85. }
  86. /* Clear the graphics window to the background color. */
  87. void gfx_clear()
  88. {
  89. XClearWindow(gfx_display,gfx_window);
  90. }
  91. /* Change the current background color. */
  92. void gfx_clear_color( int r, int g, int b )
  93. {
  94. XColor color;
  95. color.pixel = 0;
  96. color.red = r<<8;
  97. color.green = g<<8;
  98. color.blue = b<<8;
  99. XAllocColor(gfx_display,gfx_colormap,&color);
  100. XSetWindowAttributes attr;
  101. attr.background_pixel = color.pixel;
  102. XChangeWindowAttributes(gfx_display,gfx_window,CWBackPixel,&attr);
  103. }
  104. int gfx_event_waiting()
  105. {
  106. XEvent event;
  107. gfx_flush();
  108. while (1) {
  109. if(XCheckMaskEvent(gfx_display,-1,&event)) {
  110. if(event.type==KeyPress) {
  111. XPutBackEvent(gfx_display,&event);
  112. return 1;
  113. } else if (event.type==ButtonPress) {
  114. XPutBackEvent(gfx_display,&event);
  115. return 1;
  116. } else {
  117. return 0;
  118. }
  119. } else {
  120. return 0;
  121. }
  122. }
  123. }
  124. /* Wait for the user to press a key or mouse button. */
  125. char gfx_wait()
  126. {
  127. XEvent event;
  128. gfx_flush();
  129. while(1) {
  130. XNextEvent(gfx_display,&event);
  131. if(event.type==KeyPress) {
  132. saved_xpos = event.xkey.x;
  133. saved_ypos = event.xkey.y;
  134. return XLookupKeysym(&event.xkey,0);
  135. } else if(event.type==ButtonPress) {
  136. saved_xpos = event.xkey.x;
  137. saved_ypos = event.xkey.y;
  138. return event.xbutton.button;
  139. }
  140. }
  141. }
  142. /* Return the X and Y coordinates of the last event. */
  143. int gfx_xpos()
  144. {
  145. return saved_xpos;
  146. }
  147. int gfx_ypos()
  148. {
  149. return saved_ypos;
  150. }
  151. /* Flush all previous output to the window. */
  152. void gfx_flush()
  153. {
  154. XFlush(gfx_display);
  155. }