[Xcb-commit] tutorial

XCB site xcb at freedesktop.org
Mon Nov 12 00:09:25 PST 2007


 tutorial/fonts.mdwn |  293 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 292 insertions(+), 1 deletion(-)

New commits:
commit 29653e49bc76b5b9cdcad73c42122062f0c8e60d
Author: brian.thomas.will <brian.thomas.will at gmail.com>
Date:   Mon Nov 12 00:09:24 2007 -0800

    seriously refactored long example (which was section 11.5 of the original tutorial)

diff --git a/tutorial/fonts.mdwn b/tutorial/fonts.mdwn
index 30d74d2..dd8f7b3 100644
--- a/tutorial/fonts.mdwn
+++ b/tutorial/fonts.mdwn
@@ -1 +1,292 @@
-test
\ No newline at end of file
+# Handling text and fonts
+
+Besides drawing graphics on a window, we often want to draw text. Text strings have two major properties: the characters to be drawn and the font with which they are drawn. In order to draw text, we need to first request the X server to load a font. We then assign a font to a Graphic Context, and finally, we draw the text in a window using the Graphic Context.
+
+### 1. The Font structure
+
+In order to support flexible fonts, a font type is defined, and guess what, it's an Id:
+
+		typedef uint32_t xcb_font_t;
+
+A font id is passed to several functions that handle fonts selection and text drawing. We ask the X server to attribute an Id to our font with the function:
+
+		xcb_font_t xcb_generate_id (xcb_connection_t *c);
+
+
+### 2. Opening a Font
+
+To open a font, we use the following function:
+
+		xcb_void_cookie_t xcb_open_font (xcb_connection_t *c,
+										 xcb_font_t        fid,
+										 uint16_t          name_len,
+										 const char       *name);
+
+The fid parameter is the font Id defined by xcb_generate_id() (see above). The name parameter is the name of the font you want to open. Use the command xlsfonts in a terminal to know which are the fonts available on your computer. The parameter name_len is the length of the name of the font (given by strlen()).
+
+### 3. Assigning a Font to a Graphic Context
+
+Once a font is opened, you have to create a Graphic Context that will contain the informations about the color of the foreground and the background used when you draw a text in a Drawable. Here is an exemple of a Graphic Context that will allow us to draw an opened font with a black foreground and a white background:
+
+              /*
+               * c is the connection
+               * screen is the screen where the window is displayed
+               * window is the window in which we will draw the text
+               * font is the opened font
+               */
+
+              uint32_t             value_list[3];
+              xcb_gcontext_t       gc;
+              uint32_t             mask;
+
+              gc = xcb_generate_id (c);
+              mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+              value_list[0] = screen->black_pixel;
+              value_list[1] = screen->white_pixel;
+              value_list[2] = font;
+              xcb_create_gc (c, gc, window, mask, value_list);
+
+              /* The font is not needed anymore, so we close it */
+              xcb_close_font (c, font);
+
+### 4. Drawing text in a drawable
+
+To draw a text in a drawable, we use the following function:
+
+            xcb_void_cookie_t xcb_image_text_8 (xcb_connection_t *c,
+                                                uint8_t           string_len,
+                                                xcb_drawable_t    drawable,
+                                                xcb_gcontext_t    gc,
+                                                int16_t           x,
+                                                int16_t           y,
+                                                const char       *string);
+
+The string parameter is the text to draw. The location of the drawing is given by the parameters x and y. The base line of the text is exactly the parameter y.
+
+### 5. Complete example
+
+This example draw a text at 10 pixels (for the base line) of the bottom of a window. Pressing the Esc key exits the program.
+
+		#include <stdlib.h>
+		#include <stdio.h>
+		#include <string.h>
+
+		#include <xcb/xcb.h>
+
+		#define WIDTH 300
+		#define HEIGHT 100
+
+
+		static xcb_gc_t getFontGC (xcb_connection_t *c,
+									 xcb_screen_t     *screen,
+									 xcb_window_t      window,
+									 const char       *font_name );
+
+
+		static void drawText (xcb_connection_t *c,
+							   xcb_screen_t     *screen,
+							   xcb_window_t      window,
+							   int16_t           x1,
+							   int16_t           y1,
+							   const char       *label );
+
+
+		static void
+		testCookie (xcb_void_cookie_t cookie,
+					xcb_connection_t *connection,
+					char *errMessage )
+		{
+			xcb_generic_error_t *error = xcb_request_check (connection, cookie);
+			if (error) {
+				fprintf (stderr, "ERROR: %s : %d\n", errMessage , error->error_code);
+				xcb_disconnect (connection);
+				exit (-1);
+			}
+		}
+
+
+
+		/*
+		*/
+		static void
+		drawText (xcb_connection_t  *connection,
+				   xcb_screen_t     *screen,
+				   xcb_window_t      window,
+				   int16_t           x1,
+				   int16_t           y1,
+				   const char       *label )
+		{
+			xcb_generic_error_t *error;     // used by TEST_SUCCESS();
+		
+
+			/* get graphics context */
+			
+			xcb_gcontext_t gc = getFontGC (connection, screen, window, "7x13");
+			
+			
+			/* draw the text */
+
+			xcb_void_cookie_t textCookie = xcb_image_text_8_checked (connection,
+																	 strlen (label),
+																	 window,
+																	 gc,
+																	 x1, y1,
+																	 label );
+
+			testCookie(textCookie, connection, "can't paste text");
+
+
+			/* free the gc */
+
+			xcb_void_cookie_t gcCookie = xcb_free_gc (connection, gc);
+
+			testCookie(gcCookie, connection, "can't free gc");
+		}
+		
+		
+		/*
+		*/
+		static xcb_gc_t
+		getFontGC (xcb_connection_t  *connection,
+				   xcb_screen_t      *screen,
+				   xcb_window_t       window,
+				   const char        *font_name )
+		{
+			/* get font */
+		
+			xcb_font_t font = xcb_generate_id (connection);
+			xcb_void_cookie_t fontCookie = xcb_open_font_checked (connection,
+																  font,
+																  strlen (font_name),
+																  font_name );
+			
+			testCookie(fontCookie, connection, "can't open font");
+
+
+			/* create graphics context */
+			
+			xcb_gcontext_t  gc            = xcb_generate_id (connection);
+			uint32_t        mask          = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+			uint32_t        value_list[3] = { screen->black_pixel,
+											  screen->white_pixel,
+											  font };
+
+			xcb_void_cookie_t gcCookie = xcb_create_gc_checked (connection,
+																gc,
+																window,
+																mask,
+																value_list );
+											   
+			testCookie(gcCookie, connection, "can't create gc");
+			
+			
+			/* close font */
+			
+			fontCookie = xcb_close_font_checked (connection, font);
+			
+			testCookie(fontCookie, connection, "can't close font");
+
+			return gc;
+		}
+
+
+		/*
+		*/
+		int
+		main ()
+		{
+			/* get the connection */
+			
+			int screenNum;
+			xcb_connection_t *connection = xcb_connect (NULL, &screenNum);
+			if (!connection) {
+				fprintf (stderr, "ERROR: can't connect to an X server\n");
+				return -1;
+			}
+
+
+			/* get the current screen */
+			
+			
+			xcb_screen_iterator_t iter = xcb_setup_roots_iterator (xcb_get_setup (connection));
+			
+			// we want the screen at index screenNum of the iterator
+			for (int i = 0; i < screenNum; ++i) {
+			    xcb_screen_next (&iter);
+			}
+			
+			xcb_screen_t *screen = iter.data;
+			
+			if (!screen) {
+				fprintf (stderr, "ERROR: can't get the current screen\n");
+				xcb_disconnect (connection);
+				return -1;
+			}
+
+
+			/* create the window */
+			
+			xcb_window_t window = xcb_generate_id (connection);
+
+			uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+			uint32_t values[2];
+			values[0] = screen->white_pixel;
+			values[1] = XCB_EVENT_MASK_KEY_RELEASE |
+						XCB_EVENT_MASK_BUTTON_PRESS |
+						XCB_EVENT_MASK_EXPOSURE |
+						XCB_EVENT_MASK_POINTER_MOTION;
+
+			xcb_void_cookie_t windowCookie = xcb_create_window_checked (connection,
+																		screen->root_depth,
+																		window, screen->root,
+																		20, 200, 
+																		WIDTH, HEIGHT,
+																		0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
+																		screen->root_visual,
+																		mask, values);
+																		 
+ 			testCookie(windowCookie, connection, "can't create window");
+																		 
+			xcb_void_cookie_t mapCookie = xcb_map_window_checked (connection, window);
+
+			testCookie(mapCookie, connection, "can't map window");
+
+			xcb_flush(connection);  // make sure window is drawn
+
+
+			/* event loop */
+
+			xcb_generic_event_t  *event;
+			
+			while (1) {	;
+				if (event = xcb_poll_for_event(connection)) {
+					switch (event->response_type & ~0x80) {
+						case XCB_EXPOSE: {
+							drawText (connection, 
+									  screen,
+									  window,
+									  10, HEIGHT - 10,
+									  "Press ESC key to exit..." );
+							break;
+						}
+						case XCB_KEY_RELEASE: {
+							xcb_key_release_event_t *kr;
+
+							kr = (xcb_key_release_event_t *)event;
+
+							switch (kr->detail) {
+								/* ESC */
+								case 9:	{
+									free (event);
+									xcb_disconnect (connection);
+									return 0;
+								{
+							}
+						}
+					}
+					free (event);
+				}
+			}
+
+			return 0;
+		}


More information about the xcb-commit mailing list