title: C++/Linux - Drawing to a Window
body: <p>I"m taking an object oriented programming class, and we just did a project where we had to implement <a href="http://www.conwaylife.com/wiki/Main_Page" rel="nofollow">Conway's Game of Life</a>. The project specification was just to output lines of text to the terminal, which shows the evolution of the cells, but it's not very pretty. I thought it would be fun to modify the program so, instead of sending lines of text to the terminal, a drawing window is updated with the current state of our cells. I'm not looking to delve too deeply into graphics...I'm fine with using the textual representation of cells that the original project specified. As the title of this question implies, the program is written in C++ and is made to work on Linux boxes. What's the easiest way for me to make this happen.</p>
  
  <p>EDIT: Okay, so I think I'm pretty close. The problem is that line breaks aren't appearing. In my Life "toString" operator I've tried <code>endl</code> and <code>\n</code>, but neither seems to work. Here is the code...</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;X11/Xlib.h&gt;
  #include &lt;sstream&gt;
  
  #include "Cell.h"
  #include "Life.h"
  
  int main (int argc, char *argv[])
  {
      Display                 *display;
      Visual                  *visual;
      int                     depth;
      int                     text_x;
      int                     text_y;
      XSetWindowAttributes    frame_attributes;
      Window                  frame_window;
      XFontStruct             *fontinfo;
      XGCValues               gr_values;
      GC                      graphical_context;
      XEvent                  event;
      char                    hello_string[] = "Hello World";
      int                     hello_string_length = strlen(hello_string);
  
      display = XOpenDisplay(NULL);
      visual = DefaultVisual(display, 0);
      depth  = DefaultDepth(display, 0);
  
      frame_attributes.background_pixel = XWhitePixel(display, 0);
      /* create the application window */
      frame_window = XCreateWindow(display, XRootWindow(display, 0),
                                   0, 0, 400, 400, 5, depth,
                                   InputOutput, visual, CWBackPixel,
                                   &amp;frame_attributes);
      XStoreName(display, frame_window, "The Game of Life");
      XSelectInput(display, frame_window, ExposureMask | StructureNotifyMask);
  
      fontinfo = XLoadQueryFont(display, "10x20");
      gr_values.font = fontinfo-&gt;fid;
      gr_values.foreground = XBlackPixel(display, 0);
      graphical_context = XCreateGC(display, frame_window, 
                                    GCFont+GCForeground, &amp;gr_values);
      XMapWindow(display, frame_window);
  
      Life &lt;ConwayCell&gt; aLife (21, 21);
  
      aLife.animate (10, 5, '*');
      aLife.animate (10, 6, '*');
      aLife.animate (10, 7, '*');
      aLife.animate (10, 8, '*');
      aLife.animate (10, 9, '*');
      aLife.animate (10, 10, '*');
      aLife.animate (10, 11, '*');
      aLife.animate (10, 12, '*');
      aLife.animate (10, 13, '*');
      aLife.animate (10, 14, '*');
  
      std::ostringstream outStream;
      outStream &lt;&lt; aLife;
      string aString = outStream.str ();
      const char* aChar = aString.c_str ();
      int len = outStream.str ().size ();
  
      while ( 1 ) {
          XNextEvent(display, (XEvent *)&amp;event);
          switch ( event.type ) {
              case Expose:
              {
                  XWindowAttributes window_attributes;
                  int font_direction, font_ascent, font_descent;
                  XCharStruct text_structure;
                  XTextExtents(fontinfo, aChar, len, 
                               &amp;font_direction, &amp;font_ascent, &amp;font_descent, 
                               &amp;text_structure);
                  XGetWindowAttributes(display, frame_window, &amp;window_attributes);
                  text_x = (window_attributes.width - text_structure.width)/2;
                  text_y = (window_attributes.height - 
                            (text_structure.ascent+text_structure.descent))/2;
  
                  outStream &lt;&lt; aLife;
  
                  XDrawString(display, frame_window, graphical_context,
                              text_x, text_y, aChar, len);
                  break;
              }
              default:
                  break;
          }
      }
      return(0);
  }
  </code></pre>