diff options
author | Midare Kiyura <puce@gmx.com> | 2008-05-24 16:04:33 -0500 |
---|---|---|
committer | Shawn <sabetts@juicebox.(none)> | 2008-05-24 23:41:09 -0700 |
commit | d37c7484ab881b0283fd4573235b24fe7d1e7af9 (patch) | |
tree | 981341de090bb7834ab4617aed763218d9c7e8f5 | |
parent | c7ec59674cfe315f2a0ea54fc7444b4a6a6a8a67 (diff) | |
download | ratpoison-d37c7484ab881b0283fd4573235b24fe7d1e7af9.zip |
Add xft support
-rw-r--r-- | configure.in | 14 | ||||
-rw-r--r-- | src/actions.c | 95 | ||||
-rw-r--r-- | src/bar.c | 40 | ||||
-rw-r--r-- | src/conf.h | 2 | ||||
-rw-r--r-- | src/data.h | 9 | ||||
-rw-r--r-- | src/globals.c | 46 | ||||
-rw-r--r-- | src/globals.h | 17 | ||||
-rw-r--r-- | src/input.c | 34 | ||||
-rw-r--r-- | src/main.c | 13 | ||||
-rw-r--r-- | src/screen.c | 23 | ||||
-rw-r--r-- | src/split.c | 12 |
11 files changed, 226 insertions, 79 deletions
diff --git a/configure.in b/configure.in index 0af99b7..c850575 100644 --- a/configure.in +++ b/configure.in @@ -42,6 +42,20 @@ AC_ARG_WITH(xterm, [ --with-xterm=PROG set the x terminal emulator used b term_prog=$withval, term_prog="xterm") AC_DEFINE_UNQUOTED(TERM_PROG, "$term_prog", X terminal emulator to use) +dnl Use the Xft library if desired. +AC_MSG_CHECKING(whether to use Xft) +AC_ARG_WITH(xft, + AC_HELP_STRING([--with-xft], [use the Xft library for fonts]), + [if test "x$withval" != "xno"; then + AC_DEFINE_UNQUOTED(USE_XFT_FONT, 1, [Define this to use Xft]) + CFLAGS="$CFLAGS `pkg-config --cflags xft`" + LDFLAGS="$LDFLAGS `pkg-config --libs xft`" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi], + [AC_MSG_RESULT(no)]) + dnl Checks for programs. AC_CHECK_TOOL(CC, gcc) AC_PROG_CC diff --git a/src/actions.c b/src/actions.c index 84fdd49..2b54ad2 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1718,8 +1718,8 @@ read_frame (struct argspec *spec, struct sbuf *s, struct cmdarg **arg) determine the height and width of the window. */ /* num = xsprintf (" %d ", cur->number); */ num = frame_selector (cur->number); - width = defaults.bar_x_padding * 2 + XmbTextEscapement (defaults.font, num, strlen (num)); - height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2); + width = defaults.bar_x_padding * 2 + rp_text_width (s, defaults.font, num, -1); + height = (FONT_HEIGHT (s) + defaults.bar_y_padding * 2); /* Create and map the window. */ wins[i] = XCreateWindow (dpy, s->root, s->left + cur->x, s->top + cur->y, width, height, 1, @@ -1730,10 +1730,10 @@ read_frame (struct argspec *spec, struct sbuf *s, struct cmdarg **arg) XClearWindow (dpy, wins[i]); /* Display the frame's number inside the window. */ - XmbDrawString (dpy, wins[i], defaults.font, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + rp_font_ascent, - num, strlen (num)); + rp_draw_string (s, wins[i], s->normal_gc, + defaults.bar_x_padding, + defaults.bar_y_padding + FONT_ASCENT(s), + num, -1); free (num); i++; @@ -3199,25 +3199,25 @@ cmd_license (int interactive, struct cmdarg **args) { int tmp; - tmp = XmbTextEscapement (defaults.font, license_text[i], strlen (license_text[i])); + tmp = rp_text_width (s, defaults.font, license_text[i], -1); if (tmp > max_width) max_width = tmp; } /* Offset the text so its in the center. */ x = s->left + (s->width - max_width) / 2; - y = s->top + (s->height - i * FONT_HEIGHT (defaults.font)) / 2; + y = s->top + (s->height - i * FONT_HEIGHT (s)) / 2; if (x < 0) x = 0; if (y < 0) y = 0; /* Print the text. */ for(i=0; license_text[i]; i++) { - XmbDrawString (dpy, s->help_window, defaults.font, s->normal_gc, - x, y + rp_font_ascent, - license_text[i], strlen (license_text[i])); + rp_draw_string (s, s->help_window, s->normal_gc, + x, y + FONT_ASCENT(s), + license_text[i], -1); - y += FONT_HEIGHT (defaults.font); + y += FONT_HEIGHT (s); } /* Wait for a key press. */ @@ -3265,24 +3265,25 @@ cmd_help (int interactive, struct cmdarg **args) XMapRaised (dpy, s->help_window); - XmbDrawString (dpy, s->help_window, defaults.font, s->normal_gc, - 10, y + rp_font_ascent, - "ratpoison key bindings", strlen ("ratpoison key bindings")); + rp_draw_string (s, s->help_window, s->normal_gc, + 10, y + FONT_ASCENT(s), + "ratpoison key bindings", -1); - y += FONT_HEIGHT (defaults.font) * 2; + y += FONT_HEIGHT (s) * 2; + + rp_draw_string (s, s->help_window, s->normal_gc, + 10, y + FONT_ASCENT(s), + "Command key: ", -1); - XmbDrawString (dpy, s->help_window, defaults.font, s->normal_gc, - 10, y + rp_font_ascent, - "Command key: ", strlen ("Command key: ")); keysym_name = keysym_to_string (prefix_key.sym, prefix_key.state); - XmbDrawString (dpy, s->help_window, defaults.font, s->normal_gc, - 10 + XmbTextEscapement (defaults.font, "Command key: ", strlen ("Command key: ")), - y + rp_font_ascent, - keysym_name, strlen (keysym_name)); + rp_draw_string (s, s->help_window, s->normal_gc, + 10 + rp_text_width (s, defaults.font, "Command key: ", -1), + y + FONT_ASCENT(s), + keysym_name, -1); free (keysym_name); - y += FONT_HEIGHT (defaults.font) * 2; + y += FONT_HEIGHT (s) * 2; i = 0; old_i = 0; @@ -3292,30 +3293,30 @@ cmd_help (int interactive, struct cmdarg **args) { keysym_name = keysym_to_string (map->actions[i].key, map->actions[i].state); - XmbDrawString (dpy, s->help_window, defaults.font, s->normal_gc, - x, y + rp_font_ascent, - keysym_name, strlen (keysym_name)); + rp_draw_string (s, s->help_window, s->normal_gc, + x, y + FONT_ASCENT(s), + keysym_name, -1); - if (XmbTextEscapement (defaults.font, keysym_name, strlen (keysym_name)) > max_width) - max_width = XmbTextEscapement (defaults.font, keysym_name, strlen (keysym_name)); + if (rp_text_width (s, defaults.font, keysym_name, -1) > max_width) + max_width = rp_text_width (s, defaults.font, keysym_name, -1); free (keysym_name); } else { - XmbDrawString (dpy, s->help_window, defaults.font, s->normal_gc, - x, y + rp_font_ascent, - map->actions[i].data, strlen (map->actions[i].data)); + rp_draw_string (s, s->help_window, s->normal_gc, + x, y + FONT_ASCENT(s), + map->actions[i].data, -1); - if (XmbTextEscapement (defaults.font, map->actions[i].data, strlen (map->actions[i].data)) > max_width) + if (rp_text_width (s, defaults.font, map->actions[i].data, -1) > max_width) { - max_width = XmbTextEscapement (defaults.font, map->actions[i].data, strlen (map->actions[i].data)); + max_width = rp_text_width (s, defaults.font, map->actions[i].data, -1); } } - y += FONT_HEIGHT (defaults.font); + y += FONT_HEIGHT (s); /* Make sure the next line fits entirely within the window. */ - if (y + FONT_HEIGHT (defaults.font) >= (s->top + s->height)) + if (y + FONT_HEIGHT (s) >= (s->top + s->height)) { if (drawing_keys) { @@ -3332,7 +3333,7 @@ cmd_help (int interactive, struct cmdarg **args) } max_width = 0; - y = FONT_HEIGHT (defaults.font) * 4; + y = FONT_HEIGHT (s) * 4; } else { @@ -3341,7 +3342,7 @@ cmd_help (int interactive, struct cmdarg **args) { x += max_width + 10; drawing_keys = 0; - y = FONT_HEIGHT (defaults.font) * 4; + y = FONT_HEIGHT (s) * 4; i = old_i; max_width = 0; } @@ -3545,6 +3546,7 @@ update_gc (rp_screen *s) | GCSubwindowMode, &gv); } +#ifndef USE_XFT_FONT static void update_all_gcs (void) { @@ -3555,10 +3557,26 @@ update_all_gcs (void) update_gc (&screens[i]); } } +#endif static cmdret * set_font (struct cmdarg **args) { +#ifdef USE_XFT_FONT + XftFont *font; + rp_screen *s = current_screen (); + + if (args[0] == NULL) + return cmdret_new (RET_SUCCESS, "%s", defaults.font_string); + + font = XftFontOpenName (dpy, s->screen_num, ARG_STRING (0)); + + if (font == NULL) + return cmdret_new (RET_FAILURE, "deffont: unknown font"); + + XftFontClose (dpy, s->ft_font); + s->ft_font = font; +#else XFontSet font; if (args[0] == NULL) @@ -3573,6 +3591,7 @@ set_font (struct cmdarg **args) defaults.font = font; set_extents_of_fontset(font); update_all_gcs(); +#endif free (defaults.font_string); defaults.font_string = xstrdup (ARG_STRING(0)); @@ -25,6 +25,10 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> +#ifdef USE_XFT_FONT +#include <X11/Xft/Xft.h> +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -245,6 +249,7 @@ count_lines (char* msg, int len) static int max_line_length (char* msg) { + rp_screen *s = current_screen (); size_t i; size_t start; int ret = 0; @@ -257,7 +262,7 @@ max_line_length (char* msg) int current_width; /* Check if this line is the longest so far. */ - current_width = XmbTextEscapement (defaults.font, msg + start, i - start); + current_width = rp_text_width (s, defaults.font, msg + start, -1); if(current_width > ret) { ret = current_width; @@ -321,7 +326,7 @@ draw_string (rp_screen *s, char *msg) size_t i; int line_no; int start; - int line_height = FONT_HEIGHT (defaults.font); + int line_height = FONT_HEIGHT (s); /* Walk through the string, print each line. */ start = 0; @@ -332,22 +337,20 @@ draw_string (rp_screen *s, char *msg) line, and move down one line. */ if (msg[i] == '\n') { - XmbDrawString (dpy, s->bar_window, defaults.font, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + rp_font_ascent - + line_no * line_height, - msg + start, i - start); + rp_draw_string (s, s->bar_window, s->normal_gc, + defaults.bar_x_padding, + defaults.bar_y_padding + FONT_ASCENT(s), + msg + start, -1); line_no++; start = i + 1; } } /* Print the last line. */ - XmbDrawString (dpy, s->bar_window, defaults.font, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + rp_font_ascent - + line_no * line_height, - msg + start, strlen (msg) - start); + rp_draw_string (s, s->bar_window, s->normal_gc, + defaults.bar_x_padding, + defaults.bar_y_padding + FONT_ASCENT(s), + msg + start, -1); XSync (dpy, False); } @@ -412,6 +415,7 @@ static void get_mark_box (char *msg, size_t mark_start, size_t mark_end, int *x, int *y, int *width, int *height) { + rp_screen *s = current_screen (); int start, end; int mark_end_is_new_line = 0; int start_line; @@ -445,11 +449,11 @@ get_mark_box (char *msg, size_t mark_start, size_t mark_end, if (mark_start == 0 || start_pos_in_line == 0) start = 0; else - start = XmbTextEscapement (defaults.font, + start = rp_text_width (s, defaults.font, &msg[start_line_beginning], start_pos_in_line) + defaults.bar_x_padding; - - end = XmbTextEscapement (defaults.font, + + end = rp_text_width (s, defaults.font, &msg[end_line_beginning], end_pos_in_line) + defaults.bar_x_padding * 2; @@ -468,8 +472,8 @@ get_mark_box (char *msg, size_t mark_start, size_t mark_end, } *x = start; - *y = (start_line - 1) * FONT_HEIGHT (defaults.font) + defaults.bar_y_padding; - *height = (end_line - start_line + 1) * FONT_HEIGHT (defaults.font); + *y = (start_line - 1) * FONT_HEIGHT (s) + defaults.bar_y_padding; + *height = (end_line - start_line + 1) * FONT_HEIGHT (s); } static void @@ -542,7 +546,7 @@ marked_message_internal (char *msg, int mark_start, int mark_end) /* Calculate the width and height of the window. */ num_lines = count_lines (msg, strlen(msg)); width = defaults.bar_x_padding * 2 + max_line_length(msg); - height = FONT_HEIGHT (defaults.font) * num_lines + defaults.bar_y_padding * 2; + height = FONT_HEIGHT (s) * num_lines + defaults.bar_y_padding * 2; /* Display the string. */ prepare_bar (s, width, height); @@ -123,6 +123,8 @@ #define DEFAULT_FONT "-*-fixed-bold-r-normal-*-15-*-*-*-c-*-*-*" #define BACKUP_FONT "*" +#define DEFAULT_XFT_FONT "Mono-11" + /* maximum xvsprintf result string length for systems with pre-C99 snprintf: * on errors that are either permanent or cannot be distinguished from those * as libc's snprintf might by returning -1 for too small buffers, at most @@ -29,6 +29,10 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> +#ifdef USE_XFT_FONT +#include <X11/Xft/Xft.h> +#endif + typedef struct rp_window rp_window; typedef struct rp_screen rp_screen; typedef struct rp_action rp_action; @@ -168,6 +172,11 @@ struct rp_screen /* The number of the currently focused frame. One for each screen so when you switch screens the focus doesn't get frobbed. */ int current_frame; + +#ifdef USE_XFT_FONT + XftFont *ft_font; + XftColor color; +#endif }; struct rp_action diff --git a/src/globals.c b/src/globals.c index 844e9d4..91467c3 100644 --- a/src/globals.c +++ b/src/globals.c @@ -264,3 +264,49 @@ init_globals (void) selection.text = NULL; selection.len = 0; } + +/* Wrapper font functions to support Xft */ + +void +rp_draw_string (rp_screen *s, Drawable d, GC gc, int x, int y, char *string, int length) +{ + if (length < 0) + length = strlen (string); + +#ifdef USE_XFT_FONT + if (s->ft_font) + { + XftDraw *draw; + draw = XftDrawCreate (dpy, d, DefaultVisual (dpy, s->screen_num), + DefaultColormap (dpy, s->screen_num)); + if (draw) + { + XftDrawString8 (draw, &s->color, s->ft_font, x, y, (FcChar8*) string, length); + XftDrawDestroy (draw); + } + else + PRINT_ERROR(("Failed to allocate XftDraw object\n")); + } + else +#endif + XmbDrawString (dpy, d, defaults.font, gc, x, y, string, length); +} + +int +rp_text_width (rp_screen *s, XFontSet font, char *string, int count) +{ + if (count < 0) + count = strlen (string); + +#ifdef USE_XFT_FONT + if (s->ft_font) + { + XGlyphInfo extents; + XftTextExtents8 (dpy, s->ft_font, (FcChar8*) string, count, &extents); + return extents.xOff; + } + else +#endif + return XmbTextEscapement (font, string, count); +} + diff --git a/src/globals.h b/src/globals.h index f4215d3..2f0126f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -27,7 +27,19 @@ #define RET_SUCCESS 1 #define RET_FAILURE 0 +#ifdef USE_XFT_FONT +#include <X11/Xft/Xft.h> + +#define FONT_HEIGHT(s) ((s)->ft_font->ascent + (s)->ft_font->descent) +#define FONT_ASCENT(s) ((s)->ft_font->ascent) + +#else + #define FONT_HEIGHT(f) (rp_font_ascent + rp_font_descent) +#define FONT_ASCENT(f) (rp_font_ascent) + +#endif + #define MAX_FONT_WIDTH(f) (rp_font_width) #define WIN_EVENTS (StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | FocusChangeMask) @@ -176,4 +188,9 @@ char *get_selection (void); void init_globals (void); +/* Wrapper font functions to support Xft */ + +void rp_draw_string (rp_screen *s, Drawable d, GC gc, int x, int y, char *string, int length); +int rp_text_width (rp_screen *s, XFontSet font, char *string, int count); + #endif diff --git a/src/input.c b/src/input.c index d1ae47c..94d09dd 100644 --- a/src/input.c +++ b/src/input.c @@ -424,15 +424,15 @@ read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len) static void update_input_window (rp_screen *s, rp_input_line *line) { - int prompt_width = XmbTextEscapement (defaults.font, line->prompt, strlen (line->prompt)); - int input_width = XmbTextEscapement (defaults.font, line->buffer, line->length); + int prompt_width = rp_text_width (s, defaults.font, line->prompt, -1); + int input_width = rp_text_width (s, defaults.font, line->buffer, line->length); int total_width; GC lgc; XGCValues gv; int height; total_width = defaults.bar_x_padding * 2 + prompt_width + input_width + MAX_FONT_WIDTH (defaults.font); - height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2); + height = (FONT_HEIGHT (s) + defaults.bar_y_padding * 2); if (total_width < defaults.input_window_size + prompt_width) { @@ -441,22 +441,22 @@ update_input_window (rp_screen *s, rp_input_line *line) XMoveResizeWindow (dpy, s->input_window, bar_x (s, total_width), bar_y (s, height), total_width, - (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2)); + (FONT_HEIGHT (s) + defaults.bar_y_padding * 2)); XClearWindow (dpy, s->input_window); XSync (dpy, False); - XmbDrawString (dpy, s->input_window, defaults.font, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + rp_font_ascent, - line->prompt, - strlen (line->prompt)); + rp_draw_string (s, s->input_window, s->normal_gc, + defaults.bar_x_padding, + defaults.bar_y_padding + FONT_ASCENT(s), + line->prompt, + -1); - XmbDrawString (dpy, s->input_window, defaults.font, s->normal_gc, - defaults.bar_x_padding + prompt_width, - defaults.bar_y_padding + rp_font_ascent, - line->buffer, - line->length); + rp_draw_string (s, s->input_window, s->normal_gc, + defaults.bar_x_padding + prompt_width, + defaults.bar_y_padding + FONT_ASCENT(s), + line->buffer, + line->length); gv.function = GXxor; gv.foreground = s->fg_color ^ s->bg_color; @@ -464,10 +464,10 @@ update_input_window (rp_screen *s, rp_input_line *line) /* Draw a cheap-o cursor - MkII */ XFillRectangle (dpy, s->input_window, lgc, - defaults.bar_x_padding + prompt_width + XmbTextEscapement (defaults.font, line->buffer, line->position), + defaults.bar_x_padding + prompt_width + rp_text_width (s, defaults.font, line->buffer, line->position), defaults.bar_y_padding, - XmbTextEscapement (defaults.font, &line->buffer[line->position], 1), - FONT_HEIGHT (defaults.font)); + rp_text_width (s, defaults.font, &line->buffer[line->position], 1), + FONT_HEIGHT (s)); XFlush (dpy); XFreeGC (dpy, lgc); @@ -526,6 +526,9 @@ init_defaults (void) defaults.padding_top = 0; defaults.padding_bottom = 0; +#ifdef USE_XFT_FONT + defaults.font_string = xstrdup (DEFAULT_XFT_FONT); +#else /* Attempt to load a font */ defaults.font = load_query_font_set (dpy, DEFAULT_FONT); if (defaults.font == NULL) @@ -541,6 +544,7 @@ init_defaults (void) defaults.font_string = xstrdup (DEFAULT_FONT); set_extents_of_fontset (defaults.font); +#endif defaults.fgcolor_string = xstrdup ("black"); defaults.bgcolor_string = xstrdup ("white"); @@ -761,6 +765,15 @@ free_screen (rp_screen *s) XDestroyWindow (dpy, s->frame_window); XDestroyWindow (dpy, s->help_window); +#ifdef USE_XFT_FONT + if (s->ft_font) + { + XftColorFree (dpy, DefaultVisual (dpy, s->screen_num), + DefaultColormap (dpy, s->screen_num), &s->color); + XftFontClose (dpy, s->ft_font); + } +#endif + XFreeCursor (dpy, s->rat); XFreeColormap (dpy, s->def_cmap); XFreeGC (dpy, s->normal_gc); diff --git a/src/screen.c b/src/screen.c index 7d2fc6e..88b95b7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -343,6 +343,29 @@ init_screen (rp_screen *s, int screen_num) XSelectInput (dpy, s->help_window, KeyPressMask); XSync (dpy, 0); + +#ifdef USE_XFT_FONT + { + XRenderColor rc = {0, 0, 0, 0xFFFF}; + + if (!XftColorAllocValue (dpy, DefaultVisual (dpy, screen_num), + DefaultColormap (dpy, screen_num), &rc, &s->color)) + { + PRINT_ERROR(("Failed to allocate font color\n")); + s->ft_font = NULL; + } + else + { + s->ft_font = XftFontOpenName (dpy, screen_num, DEFAULT_XFT_FONT); + if (!s->ft_font) + { + PRINT_ERROR(("Failed to open font\n")); + XftColorFree (dpy, DefaultVisual (dpy, screen_num), + DefaultColormap (dpy, screen_num), &s->color); + } + } + } +#endif } static int diff --git a/src/split.c b/src/split.c index f5012d8..45671c2 100644 --- a/src/split.c +++ b/src/split.c @@ -1000,9 +1000,9 @@ show_frame_message (char *msg) sbuf_concat (msgbuf, EMPTY_FRAME_MESSAGE); } - width = defaults.bar_x_padding * 2 + XmbTextEscapement (defaults.font, msgbuf->data, + width = defaults.bar_x_padding * 2 + rp_text_width (s, defaults.font, msgbuf->data, msgbuf->len); - height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2); + height = (FONT_HEIGHT (s) + defaults.bar_y_padding * 2); /* We don't want another frame indicator to be displayed on another * screen at the same time, so we hide it before bringing it back again. @@ -1018,10 +1018,10 @@ show_frame_message (char *msg) XClearWindow (dpy, s->frame_window); XSync (dpy, False); - XmbDrawString (dpy, s->frame_window, defaults.font, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + rp_font_ascent, - msgbuf->data, msgbuf->len); + rp_draw_string (s, s->frame_window, s->normal_gc, + defaults.bar_x_padding, + defaults.bar_y_padding + FONT_ASCENT(s), + msgbuf->data, -1); sbuf_free (msgbuf); } |