modernc.org/xcb@v1.0.15/examples/fontcompleteexample/fontcompleteexample.c (about)

     1  // +build ignore
     2  
     3  // src: https://www.x.org/releases/current/doc/libxcb/tutorial/index.html#fontcompleteexample
     4  
     5  #include <stdlib.h>
     6  #include <stdio.h>
     7  #include <string.h>
     8  
     9  #include <xcb/xcb.h>
    10  
    11  #define WIDTH 300
    12  #define HEIGHT 100
    13  
    14  
    15  
    16  static xcb_gc_t gc_font_get (xcb_connection_t *c,
    17                               xcb_screen_t     *screen,
    18                               xcb_window_t      window,
    19                               const char       *font_name);
    20  
    21  static void text_draw (xcb_connection_t *c,
    22                         xcb_screen_t     *screen,
    23                         xcb_window_t      window,
    24                         int16_t           x1,
    25                         int16_t           y1,
    26                         const char       *label);
    27  
    28  static void
    29  text_draw (xcb_connection_t *c,
    30             xcb_screen_t     *screen,
    31             xcb_window_t      window,
    32             int16_t           x1,
    33             int16_t           y1,
    34             const char       *label)
    35  {
    36    xcb_void_cookie_t    cookie_gc;
    37    xcb_void_cookie_t    cookie_text;
    38    xcb_generic_error_t *error;
    39    xcb_gcontext_t       gc;
    40    uint8_t              length;
    41  
    42    length = strlen (label);
    43  
    44    gc = gc_font_get(c, screen, window, "7x13");
    45  
    46    cookie_text = xcb_image_text_8_checked (c, length, window, gc,
    47                                            x1,
    48                                            y1, label);
    49    error = xcb_request_check (c, cookie_text);
    50    if (error) {
    51      fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
    52      xcb_disconnect (c);
    53      exit (-1);
    54    }
    55  
    56    cookie_gc = xcb_free_gc (c, gc);
    57    error = xcb_request_check (c, cookie_gc);
    58    if (error) {
    59      fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
    60      xcb_disconnect (c);
    61      exit (-1);
    62    }
    63  }
    64  
    65  static xcb_gc_t
    66  gc_font_get (xcb_connection_t *c,
    67               xcb_screen_t     *screen,
    68               xcb_window_t      window,
    69               const char       *font_name)
    70  {
    71    uint32_t             value_list[3];
    72    xcb_void_cookie_t    cookie_font;
    73    xcb_void_cookie_t    cookie_gc;
    74    xcb_generic_error_t *error;
    75    xcb_font_t           font;
    76    xcb_gcontext_t       gc;
    77    uint32_t             mask;
    78  
    79    font = xcb_generate_id (c);
    80    cookie_font = xcb_open_font_checked (c, font,
    81                                         strlen (font_name),
    82                                         font_name);
    83  
    84    error = xcb_request_check (c, cookie_font);
    85    if (error) {
    86      fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
    87      xcb_disconnect (c);
    88      return -1;
    89    }
    90  
    91    gc = xcb_generate_id (c);
    92    mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
    93    value_list[0] = screen->black_pixel;
    94    value_list[1] = screen->white_pixel;
    95    value_list[2] = font;
    96    cookie_gc = xcb_create_gc_checked (c, gc, window, mask, value_list);
    97    error = xcb_request_check (c, cookie_gc);
    98    if (error) {
    99      fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
   100      xcb_disconnect (c);
   101      exit (-1);
   102    }
   103  
   104    cookie_font = xcb_close_font_checked (c, font);
   105    error = xcb_request_check (c, cookie_font);
   106    if (error) {
   107      fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
   108      xcb_disconnect (c);
   109      exit (-1);
   110    }
   111  
   112    return gc;
   113  }
   114  
   115  int main ()
   116  {
   117    xcb_screen_iterator_t screen_iter;
   118    xcb_connection_t     *c;
   119    const xcb_setup_t    *setup;
   120    xcb_screen_t         *screen;
   121    xcb_generic_event_t  *e;
   122    xcb_generic_error_t  *error;
   123    xcb_void_cookie_t     cookie_window;
   124    xcb_void_cookie_t     cookie_map;
   125    xcb_window_t          window;
   126    uint32_t              mask;
   127    uint32_t              values[2];
   128    int                   screen_number;
   129  
   130    /* getting the connection */
   131    c = xcb_connect (NULL, &screen_number);
   132    if (!c) {
   133      fprintf (stderr, "ERROR: can't connect to an X server\n");
   134      return -1;
   135    }
   136  
   137    /* getting the current screen */
   138    setup = xcb_get_setup (c);
   139  
   140    screen = NULL;
   141    screen_iter = xcb_setup_roots_iterator (setup);
   142    for (; screen_iter.rem != 0; --screen_number, xcb_screen_next (&screen_iter))
   143      if (screen_number == 0)
   144        {
   145          screen = screen_iter.data;
   146          break;
   147        }
   148    if (!screen) {
   149      fprintf (stderr, "ERROR: can't get the current screen\n");
   150      xcb_disconnect (c);
   151      return -1;
   152    }
   153  
   154    /* creating the window */
   155    window = xcb_generate_id (c);
   156    mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
   157    values[0] = screen->white_pixel;
   158    values[1] =
   159      XCB_EVENT_MASK_KEY_RELEASE |
   160      XCB_EVENT_MASK_BUTTON_PRESS |
   161      XCB_EVENT_MASK_EXPOSURE |
   162      XCB_EVENT_MASK_POINTER_MOTION;
   163    cookie_window = xcb_create_window_checked (c,
   164                                               screen->root_depth,
   165                                               window, screen->root,
   166                                               20, 200, WIDTH, HEIGHT,
   167                                               0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
   168                                               screen->root_visual,
   169                                               mask, values);
   170    cookie_map = xcb_map_window_checked (c, window);
   171  
   172    /* error managing */
   173    error = xcb_request_check (c, cookie_window);
   174    if (error) {
   175      fprintf (stderr, "ERROR: can't create window : %d\n", error->error_code);
   176      xcb_disconnect (c);
   177      return -1;
   178    }
   179    error = xcb_request_check (c, cookie_map);
   180    if (error) {
   181      fprintf (stderr, "ERROR: can't map window : %d\n", error->error_code);
   182      xcb_disconnect (c);
   183      return -1;
   184    }
   185  
   186    xcb_flush(c);
   187  
   188    while (1) {
   189      e = xcb_poll_for_event(c);
   190      if (e) {
   191        switch (e->response_type & ~0x80) {
   192        case XCB_EXPOSE: {
   193          char *text;
   194  
   195          text = "Press ESC key to exit...";
   196          text_draw (c, screen, window, 10, HEIGHT - 10, text);
   197          break;
   198        }
   199        case XCB_KEY_RELEASE: {
   200          xcb_key_release_event_t *ev;
   201  
   202          ev = (xcb_key_release_event_t *)e;
   203  
   204          switch (ev->detail) {
   205            /* ESC */
   206          case 9:
   207            free (e);
   208            xcb_disconnect (c);
   209            return 0;
   210          }
   211        }
   212        }
   213        free (e);
   214      }
   215    }
   216  
   217    return 0;
   218  }