"Fossies" - the Fresh Open Source Software Archive

Member "dosemu-1.4.0/src/plugin/X/X_font.c" (4 May 2007, 8461 Bytes) of package /linux/misc/old/dosemu-1.4.0.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "X_font.c" see the Fossies "Dox" file reference documentation.

    1 /* 
    2  * (C) Copyright 1992, ..., 2007 the "DOSEMU-Development-Team".
    3  *
    4  * for details see file COPYING.DOSEMU in the DOSEMU distribution
    5  */
    6 
    7 /* X font handling. Generally X fonts are faster than bitmapped fonts
    8    but they can't be scaled or their images changed by DOS software */
    9 
   10 #include <string.h>
   11 #include <X11/X.h>
   12 #include <X11/Xlib.h>
   13 
   14 #include "emu.h"
   15 #include "translate.h"
   16 #include "vgaemu.h"
   17 #include "vgatext.h"
   18 #include "video.h"
   19 #include "X.h"
   20 
   21 static Display *text_display;
   22 static Window text_window;
   23 static XFontStruct *font = NULL;
   24 static int font_width, font_height, font_shift;
   25 static Colormap text_cmap;
   26 static int text_col_stats[16] = {0};
   27 static unsigned long text_colors[16];
   28 static GC text_gc;
   29 static int text_cmap_colors;
   30 
   31 /* 
   32  * Change color values in our graphics context 'gc'.
   33  */
   34 static void set_gc_attr(Bit8u attr)
   35 {
   36   XGCValues gcv;
   37 
   38   gcv.foreground = text_colors[ATTR_FG(attr)];
   39   gcv.background = text_colors[ATTR_BG(attr)];
   40   XChangeGC(text_display, text_gc, GCForeground | GCBackground, &gcv);
   41 }
   42 
   43 
   44 /*
   45  * Draw a non-bitmap text string.
   46  * The attribute is the VGA color/mono text attribute.
   47  */
   48 static void X_draw_string(int x, int y, unsigned char *text, int len, Bit8u attr)
   49 {
   50   set_gc_attr(attr);
   51   XDrawImageString(
   52     text_display, text_window, text_gc,
   53     font_width * x,
   54     font_height * y + font_shift,
   55     text,
   56     len
   57     );
   58 }
   59 
   60 static void X_draw_string16(int x, int y, unsigned char *text, int len, Bit8u attr)
   61 {
   62   XChar2b buff[len];
   63   t_unicode uni;
   64   struct char_set_state state;
   65   size_t i, d;
   66 
   67   set_gc_attr(attr);
   68   init_charset_state(&state, trconfig.video_mem_charset);
   69   d = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
   70   for (i = 0; i < len; i++) {
   71     if (charset_to_unicode(&state, &uni, &text[i], 1) != 1)
   72       break;
   73     buff[i].byte1 = uni / d + font->min_byte1;
   74     buff[i].byte2 = uni % d + font->min_char_or_byte2;
   75   }
   76   cleanup_charset_state(&state);
   77   XDrawImageString16(
   78     text_display, text_window, text_gc,
   79     font_width * x,
   80     font_height * y + font_shift,
   81     buff,
   82     i
   83     );
   84 }
   85 
   86 
   87 /*
   88  * Draw a horizontal line (for text modes)
   89  * The attribute is the VGA color/mono text attribute.
   90  */
   91 static void X_draw_line(int x, int y, int len)
   92 {
   93   XDrawLine(
   94       text_display, text_window, text_gc,
   95       font_width * x,
   96       font_height * y + font_shift,
   97       font_width * (x + len) - 1,
   98       font_height * y + font_shift
   99     );
  100 }
  101 
  102 
  103 /*
  104  * Draw the cursor (nothing in graphics modes, normal if we have focus,
  105  * rectangle otherwise).
  106  */
  107 static void X_draw_text_cursor(int x, int y, Bit8u attr, int start, int end,
  108                    Boolean focus)
  109 {
  110   int cstart, cend;
  111 
  112   /* no hardware cursor emulation in graphics modes (erik@sjoerd) */
  113   if(vga.mode_class == GRAPH) return;
  114 
  115   set_gc_attr(attr);
  116   if(!focus) {
  117     XDrawRectangle(
  118       text_display, text_window, text_gc,
  119       x * font_width,
  120       y * font_height,
  121       font_width - 1,
  122       font_height - 1
  123       );
  124   }
  125   else {
  126     cstart = ((start + 1) * font_height) / vga.char_height - 1;
  127     if (cstart == -1) cstart = 0;
  128     cend = ((end + 1) * font_height) / vga.char_height - 1;
  129     if (cend == -1) cend = 0;
  130     XFillRectangle(
  131       text_display, text_window, text_gc,
  132       x * font_width,
  133       y * font_height + cstart,
  134       font_width,
  135       cend - cstart + 1
  136     );
  137   }
  138 }
  139 
  140 /*
  141  * Scans the colormap cmap for the color closest to xc and
  142  * returns it in xc. The color values used by cmap are queried
  143  * from the X server only if read_cmap is set.
  144  */
  145 static void get_approx_color(XColor *xc, Colormap cmap, int read_cmap)
  146 {
  147   int i, d0, ind;
  148   unsigned d1, d2;
  149   static XColor xcols[256];
  150 
  151   if(read_cmap) {
  152     for(i = 0; i < text_cmap_colors; i++) xcols[i].pixel = i;
  153     XQueryColors(text_display, cmap, xcols, text_cmap_colors);
  154   }
  155 
  156   ind = -1; d2 = -1;
  157   for(i = 0; i < text_cmap_colors; i++) {
  158     /* Note: X color values are unsigned short, so using int for the sum (d1) should be ok. */
  159     d0 = (int) xc->red - xcols[i].red; d1 = abs(d0);
  160     d0 = (int) xc->green - xcols[i].green; d1 += abs(d0);
  161     d0 = (int) xc->blue - xcols[i].blue; d1 += abs(d0);
  162     if(d1 < d2) ind = i, d2 = d1;
  163   }
  164 
  165   if(ind >= 0) *xc = xcols[ind];
  166 }
  167 
  168 
  169 /*
  170  * Update the active X colormap for text modes DAC entry col.
  171  */
  172 static void X_set_text_palette(DAC_entry col)
  173 {
  174   int read_cmap = 1;
  175   int i, shift = 16 - vga.dac.bits;
  176   XColor xc;
  177 
  178   xc.flags = DoRed | DoGreen | DoBlue;
  179   xc.pixel = text_colors[i = col.index];
  180   xc.red   = col.r << shift;
  181   xc.green = col.g << shift;
  182   xc.blue  = col.b << shift;
  183 
  184   if(text_col_stats[i]) XFreeColors(text_display, text_cmap, &xc.pixel, 1, 0);
  185 
  186   if(!(text_col_stats[i] = XAllocColor(text_display, text_cmap, &xc))) {
  187     get_approx_color(&xc, text_cmap, read_cmap);
  188     read_cmap = 0;
  189     X_printf("X: refresh_text_palette: %d (%d -> app. %d)\n", i, (int) text_colors[i], (int) xc.pixel);
  190       
  191   }
  192   else {
  193     X_printf("X: refresh_text_palette: %d (%d -> %d)\n", i, (int) text_colors[i], (int) xc.pixel);
  194   }
  195   text_colors[i] = xc.pixel;
  196 }
  197 
  198 
  199 static struct text_system Text_X =
  200 {
  201    X_draw_string, 
  202    X_draw_line,
  203    X_draw_text_cursor,
  204    X_set_text_palette,
  205 };
  206 
  207 /*
  208  * Load the main text font. Try first the user specified font, then
  209  * vga, then 9x15 and finally fixed. If none of these exists and
  210  * is monospaced, give up (shouldn't happen).
  211  */
  212 void X_load_text_font(Display *dpy, int private_dpy, Window w,
  213               const char *p, int *width, int *height)
  214 {
  215   XFontStruct *xfont;
  216   XGCValues gcv;
  217   XWindowAttributes xwa;
  218   int depth;
  219 
  220   xfont = NULL;
  221   if (!private_dpy)
  222     text_display = dpy;
  223 
  224   if (p && *p) {
  225     /* Open a separate connection to receive expose events without
  226        SDL eating them. */
  227     if (private_dpy && text_display == NULL)
  228       text_display = XOpenDisplay(NULL);
  229     xfont = XLoadQueryFont(text_display, p);
  230     if (xfont == NULL) {
  231       error("X: Unable to open font \"%s\", using builtin\n", p);
  232     } else if (xfont->min_bounds.width != xfont->max_bounds.width) {
  233       error("X: Font \"%s\" isn't monospaced, using builtin\n", p);
  234       XFreeFont(text_display, xfont);
  235       xfont = NULL;
  236     }
  237   }
  238 
  239   if(font != NULL) {
  240     XFreeFont(text_display, font);
  241     XFreeGC(text_display, text_gc);
  242     if (xfont == NULL && private_dpy) {
  243       /* called from SDL:
  244      set expose events back from text_display to the main one */
  245       XSelectInput(text_display, w, 0);
  246       XGetWindowAttributes(dpy, w, &xwa);
  247       XSelectInput(dpy, w, xwa.your_event_mask | ExposureMask);
  248     }
  249   }
  250 
  251   font = xfont;
  252   use_bitmap_font = (font == NULL);
  253   dirty_all_vga_colors();
  254   if (use_bitmap_font) {
  255     if (p == NULL) {
  256       if (private_dpy && text_display)
  257     XCloseDisplay(text_display);
  258       return;
  259     }
  260     X_printf("X: X_change_config: font \"%s\" not found, "
  261          "using builtin\n", p);
  262     X_printf("X: NOT loading a font. Using EGA/VGA builtin/RAM fonts.\n");
  263     X_printf("X: EGA/VGA font size is %d x %d\n",
  264          vga.char_width, vga.char_height);
  265     return;
  266   }
  267 
  268   depth = DefaultDepth(text_display, DefaultScreen(text_display));
  269   if(depth > 8) depth = 8;
  270   text_cmap_colors = 1 << depth;
  271   text_cmap = DefaultColormap(text_display, DefaultScreen(text_display));
  272   text_window = w;
  273 
  274   gcv.font = font->fid;
  275   text_gc = XCreateGC(text_display, w, GCFont, &gcv);
  276   font_width = font->max_bounds.width;
  277   font_height = font->max_bounds.ascent + font->max_bounds.descent;
  278   font_shift = font->max_bounds.ascent;
  279   X_printf("X: Using font \"%s\", size = %d x %d\n", p, font_width, font_height);
  280   if (font->min_byte1 || font->max_byte1) {
  281     Text_X.Draw_string = X_draw_string16;
  282     X_printf("X: Assuming unicode font\n");
  283   } else
  284     Text_X.Draw_string = X_draw_string;
  285   register_text_system(&Text_X);
  286   if (width)
  287     *width = font_width;
  288   if (height)
  289     *height = font_height;
  290 
  291   if (private_dpy) { /* called from SDL */
  292     XSelectInput(text_display, w, ExposureMask);
  293     XGetWindowAttributes(dpy, w, &xwa);
  294     XSelectInput(dpy, w, xwa.your_event_mask & ~ExposureMask);
  295   }
  296 }
  297 
  298 /*
  299  *  handle expose events (called from SDL only)
  300  */
  301 int X_handle_text_expose(void)
  302 {
  303   int ret = 0;
  304   if (!text_display)
  305     return ret;
  306   while (XPending(text_display) > 0) {
  307     XEvent e;
  308     XNextEvent(text_display, &e);
  309     switch(e.type) {
  310     case Expose:
  311       X_printf("X: text_display expose event\n");
  312       ret = 1;
  313       break;
  314     default:
  315       v_printf("SDL: some other X event (ignored)\n");
  316       break;
  317     }
  318   }
  319   return ret;
  320 }