title: X11 Getting Title Bar Size
body: <p>I'm writing a simple text user interface with libX11 and I've got a set of code working for a basic library abstraction.</p>
  
  <p>The problem is when I try to draw text, the title bar blocks the first line. So now I have to offset the vertical printing by about 20 pixels. Is there a way to determine the exact size of the title bar, so that I can properly offset each line of text?</p>
  
  <p>Here's the code I have so far, and <code>tui_puts</code> is the function I need to do this for:</p>
  
  <pre><code>#include "tui.h"
  
  #include &lt;X11/Xlib.h&gt;
  #include &lt;unistd.h&gt;
  
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  struct tui_data {
  
      Display * display;
      Window id_window;
      GC context_graphics;
  
      XIM method_input;
      XIC context_input;
  
      XWindowAttributes spec_window;
      XFontStruct * spec_font;
  
      size_t offset_y;
      size_t offset_x;
  };
  
  int tui_init (struct tui_session * ptr_tui){
      memset (ptr_tui, 0, sizeof (struct tui_session));
  
      ptr_tui-&gt;ptr_data = calloc (sizeof (struct tui_data), 1);
      if (!ptr_tui-&gt;ptr_data) return -1;
  
      ptr_tui-&gt;ptr_data-&gt;display = XOpenDisplay (0);
      if (!ptr_tui-&gt;ptr_data-&gt;display) return -1;
  
      int color_black = BlackPixel(ptr_tui-&gt;ptr_data-&gt;display, DefaultScreen(ptr_tui-&gt;ptr_data-&gt;display));
      int color_white = WhitePixel(ptr_tui-&gt;ptr_data-&gt;display, DefaultScreen(ptr_tui-&gt;ptr_data-&gt;display));
  
      ptr_tui-&gt;ptr_data-&gt;id_window = XCreateSimpleWindow(ptr_tui-&gt;ptr_data-&gt;display,
                                                         DefaultRootWindow(ptr_tui-&gt;ptr_data-&gt;display),
                                                         0, 0, 640, 480, 0, color_black, color_black);
  
      XSelectInput (ptr_tui-&gt;ptr_data-&gt;display,
                    ptr_tui-&gt;ptr_data-&gt;id_window,
                    StructureNotifyMask);
  
      XMapWindow (ptr_tui-&gt;ptr_data-&gt;display,
                  ptr_tui-&gt;ptr_data-&gt;id_window);
  
      ptr_tui-&gt;ptr_data-&gt;context_graphics = XCreateGC(ptr_tui-&gt;ptr_data-&gt;display,
                                                      ptr_tui-&gt;ptr_data-&gt;id_window, 0, 0);
  
      for (;;){
          XEvent e;
          XNextEvent (ptr_tui-&gt;ptr_data-&gt;display, &amp;e);
          if (e.type == MapNotify) break;
      }
  
      XSetForeground (ptr_tui-&gt;ptr_data-&gt;display,
                      ptr_tui-&gt;ptr_data-&gt;context_graphics,
                      color_white);
  
      XGetWindowAttributes (ptr_tui-&gt;ptr_data-&gt;display,
                            ptr_tui-&gt;ptr_data-&gt;id_window,
                           &amp;ptr_tui-&gt;ptr_data-&gt;spec_window);
  
      XSelectInput (ptr_tui-&gt;ptr_data-&gt;display,
                    ptr_tui-&gt;ptr_data-&gt;id_window,
                    ExposureMask | KeyPressMask | ResizeRedirectMask);
  
      ptr_tui-&gt;ptr_data-&gt;method_input = XOpenIM (ptr_tui-&gt;ptr_data-&gt;display, 0, 0, 0);
  
      if (!ptr_tui-&gt;ptr_data-&gt;method_input){
          return -1;
      }
  
      ptr_tui-&gt;ptr_data-&gt;context_input = XCreateIC (ptr_tui-&gt;ptr_data-&gt;method_input,
                                                    XNInputStyle, XIMPreeditNothing
                                                  | XIMStatusNothing, XNClientWindow,
                                                    ptr_tui-&gt;ptr_data-&gt;id_window, NULL);
  
      if (!ptr_tui-&gt;ptr_data-&gt;context_input){
          return -1;
      }
  
      XSetICFocus (ptr_tui-&gt;ptr_data-&gt;context_input);
  
      ptr_tui-&gt;ptr_data-&gt;spec_font = XLoadQueryFont (ptr_tui-&gt;ptr_data-&gt;display,
                                                   "-misc-fixed-medium-"
                                                   "r-normal-*-*-120-*-*");
  
      if (!ptr_tui-&gt;ptr_data-&gt;spec_font){
          return -1;
      }
  
      XSetFont (ptr_tui-&gt;ptr_data-&gt;display,
                ptr_tui-&gt;ptr_data-&gt;context_graphics,
                ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;fid);
  
      ptr_tui-&gt;max_x = ptr_tui-&gt;ptr_data-&gt;spec_window.width
                     / ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;max_bounds.width;
      ptr_tui-&gt;max_y = ptr_tui-&gt;ptr_data-&gt;spec_window.height
                    / (ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;max_bounds.ascent
                    +  ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;max_bounds.descent);
      return 0;
  }
  
  int tui_free (struct tui_session * ptr_tui){
  
      if (ptr_tui-&gt;ptr_data){
  
          XFreeFont (ptr_tui-&gt;ptr_data-&gt;display, ptr_tui-&gt;ptr_data-&gt;spec_font);
          XFreeGC (ptr_tui-&gt;ptr_data-&gt;display, ptr_tui-&gt;ptr_data-&gt;context_graphics);
  
          XSetCloseDownMode(ptr_tui-&gt;ptr_data-&gt;display, DestroyAll);
          XCloseDisplay (ptr_tui-&gt;ptr_data-&gt;display);
  
          free (ptr_tui-&gt;ptr_data);
      }
  
      memset (ptr_tui, 0, sizeof (struct tui_session));
      return 0;
  }
  
  int tui_refresh (struct tui_session * ptr_tui){
      XFlush (ptr_tui-&gt;ptr_data-&gt;display);
      return 0;
  }
  
  int tui_clear (struct tui_session * ptr_tui){
      XClearWindow (ptr_tui-&gt;ptr_data-&gt;display,
                    ptr_tui-&gt;ptr_data-&gt;id_window);
      return 0;
  }
  
  int tui_puts (struct tui_session * ptr_tui,
                const void * ptr_data, size_t len_data,
                size_t index_x, size_t index_y, uint32_t flags){
  
      if (((index_x + len_data) &gt;= ptr_tui-&gt;max_x)
      ||  (index_y &gt;= ptr_tui-&gt;max_y)) return -1;
  
      XDrawImageString (ptr_tui-&gt;ptr_data-&gt;display,
                        ptr_tui-&gt;ptr_data-&gt;id_window,
                        ptr_tui-&gt;ptr_data-&gt;context_graphics,
                        ptr_tui-&gt;ptr_data-&gt;spec_window.border_width
                      + ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;max_bounds.width * index_x,
                       (ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;max_bounds.ascent
                      + ptr_tui-&gt;ptr_data-&gt;spec_font-&gt;max_bounds.descent)
                      * index_y + 20, ptr_data, len_data);
  
      return 0;
  }
  
  int tui_message (struct tui_session * ptr_tui, const char * format, ...){
      return -1;
  }
  
  int tui_prompt (struct tui_session * ptr_tui, const char * format, ...){
      return -1;
  }
  
  int tui_input (struct tui_session * ptr_tui, tui_event * ptr_event){
  
      XEvent event;
      Status status = 0;
      KeySym keysym = 0;
      char buffer[4];
      int count = 0;
  
      XNextEvent(ptr_tui-&gt;ptr_data-&gt;display, &amp;event);
  
      switch (event.type){
  
      case KeyPress:
  
          count = Xutf8LookupString (ptr_tui-&gt;ptr_data-&gt;context_input,
                                    (XKeyPressedEvent*) &amp;event, buffer,
                                     sizeof (buffer), &amp;keysym, &amp;status);
  
              if (count){
                  ptr_event-&gt;type = TUI_EVENT_KEYPRESS;
                  ptr_event-&gt;value = buffer[0];
              }
  
              break;
  
      case Expose:
          ptr_event-&gt;type = TUI_EVENT_REPRINT;
          ptr_event-&gt;value = 0;
          break;
  
      case ResizeRequest:
          XGetWindowAttributes (ptr_tui-&gt;ptr_data-&gt;display,
                                ptr_tui-&gt;ptr_data-&gt;id_window,
                               &amp;ptr_tui-&gt;ptr_data-&gt;spec_window);
          ptr_event-&gt;type = TUI_EVENT_REPRINT;
          ptr_event-&gt;value = 0;
          break;
  
      default:
          ptr_event-&gt;type = 0;
          ptr_event-&gt;value = 0;
      }
  
      return 0;
  }
  
  int tui_scroll (struct tui_session * ptr_tui, int offset){
      return -1;
  }
  </code></pre>
  
  <p>Also, here's an important structure:</p>
  
  <pre><code>typedef struct {
      int x, y;                        /* location of window */
      int width, height;               /* width and height of window */
      int border_width;                /* border width of window */
      int depth;                       /* depth of window */
      Visual *visual;                  /* the associated visual structure */
      Window root;                     /* root of screen containing window */
      int class;                       /* InputOutput, InputOnly*/
      int bit_gravity;                 /* one of the bit gravity values */
      int win_gravity;                 /* one of the window gravity values */
      int backing_store;               /* NotUseful, WhenMapped, Always */
      unsigned long backing_planes;    /* planes to be preserved if possible */
      unsigned long backing_pixel;     /* value to be used when restoring planes */
      Bool save_under;                 /* boolean, should bits under be saved? */
      Colormap colormap;               /* color map to be associated with window */
      Bool map_installed;              /* boolean, is color map currently installed*/
      int map_state;                   /* IsUnmapped, IsUnviewable, IsViewable */
      long all_event_masks;            /* set of events all people have interest in*/
      long your_event_mask;            /* my event mask */
      long do_not_propagate_mask;      /* set of events that should not propagate */
      Bool override_redirect;          /* boolean value for override-redirect */
      Screen *screen;                  /* back pointer to correct screen */
  } XWindowAttributes;
  </code></pre>
  
  <p>And this was helpful for getting the horizontal offset of the client area, but I don't see anything that would help me get the vertical offset.</p>