typedef struct
{
- unsigned short r, g, b;
+ unsigned int rgb; /* (red << 16) | (green << 8) | blue */
GC gc;
} MColorGC;
Colormap cmap;
- unsigned long foreground, background;
+ GC gc_fore, gc_back, gc_scratch;
/** List of pointers to realized faces on the frame. */
MPlist *realized_face_list;
#define FRAME_DISPLAY(frame) (frame->device->display_info->display)
#define FRAME_SCREEN(frame) (frame->device->screen_num)
+enum face_gc
+ {
+ MFACE_GC_NORMAL,
+ MFACE_GC_INVERSE,
+ MFACE_GC_HLINE,
+ MFACE_GC_BOX_TOP,
+ MFACE_GC_BOX_BOTTOM,
+ MFACE_GC_BOX_LEFT,
+ MFACE_GC_BOX_RIGHT,
+ MFACE_GCS
+ };
+
static void
free_display_info (void *object)
{
mface__free_realized ((MRealizedFace *) mplist_value (plist));
M17N_OBJECT_UNREF (device->realized_face_list);
+ MPLIST_DO (plist, device->gc_list)
+ {
+ XFreeGC (device->display_info->display,
+ ((MColorGC *) MPLIST_VAL (plist))->gc);
+ free (MPLIST_VAL (plist));
+ }
+ M17N_OBJECT_UNREF (device->gc_list);
+
XFreePixmap (device->display_info->display, device->drawable);
M17N_OBJECT_UNREF (device->display_info);
+
free (object);
}
XFreeModifiermap (mods);
}
-static unsigned long
-get_color (Display *display, Colormap cmap,
- MSymbol color_name, MSymbol default_name,
- unsigned long default_pixel)
-{
- XColor exact_def;
-
- if (XParseColor (display, cmap, msymbol_name (color_name), &exact_def)
- && XAllocColor (display, cmap, &exact_def))
- return exact_def.pixel;
-
- if (XParseColor (display, cmap, msymbol_name (default_name), &exact_def)
- && XAllocColor (display, cmap, &exact_def))
- return exact_def.pixel;
-
- return default_pixel;
-}
-
\f
/** X font handler */
}
static GC
-set_region (Display *display, MRealizedFace *rface, GC gc, MDrawRegion region)
+set_region (MFrame *frame, GC gc, MDrawRegion region)
{
- GC gc1;
- XRectangle xrect;
+ unsigned long valuemask = GCForeground;
- XClipBox (region, &xrect);
- gc1 = ((GC *) rface->info)[MFACE_GC_SCRATCH];
- XCopyGC (display, gc, GCFont | GCForeground | GCBackground, gc1);
- XSetRegion (display, gc1, region);
- return gc1;
+ XCopyGC (FRAME_DISPLAY (frame), gc, valuemask, frame->device->gc_scratch);
+ XSetRegion (FRAME_DISPLAY (frame), frame->device->gc_scratch, region);
+ return frame->device->gc_scratch;
}
/* The X font driver function RENDER. */
display = FRAME_DISPLAY (rface->frame);
if (region)
- gc = set_region (display, rface, gc, region);
+ gc = set_region (rface->frame, gc, region);
+ XSetFont (display, gc, ((MXFontInfo *) (rface->rfont->info))->f->fid);
if (from->code == MCHAR_INVALID_CODE)
{
\f
-#if 1
+#ifdef X_SET_ERROR_HANDLER
static int
x_error_handler (Display *display, XErrorEvent *error)
{
M17N_OBJECT_REF (device);
else
{
+ unsigned long valuemask = GCForeground;
+ XGCValues values;
+
M17N_OBJECT (device, free_device, MERROR_WIN);
device->display_info = disp_info;
device->screen_num = screen_num;
device->cmap = cmap;
device->realized_face_list = mplist ();
device->realized_fontset_list = mplist ();
- device->foreground = BlackPixel (display, screen_num);
- device->background = WhitePixel (display, screen_num);
+ values.foreground = BlackPixel (display, screen_num);
+ device->gc_fore = XCreateGC (display, device->drawable,
+ valuemask, &values);
+ device->gc_scratch = XCreateGC (display, device->drawable,
+ valuemask, &values);
+ values.foreground = WhitePixel (display, screen_num);
+ device->gc_back = XCreateGC (display, device->drawable,
+ valuemask, &values);
+ device->gc_list = mplist ();
}
frame->realized_font_list = disp_info->realized_font_list;
XFreeFontNames (names);
}
+ if (! face)
+ face = mface ();
+ mface_put_prop (face, Mforeground, msymbol (app_data.foreground));
+ mface_put_prop (face, Mbackground, msymbol (app_data.background));
if (app_data.reverse_video == True)
- {
- if (! face)
- face = mface ();
- mface_put_prop (face, Mvideomode, Mreverse);
- }
- if (face)
- {
- mplist_push (param, Mface, face);
- M17N_OBJECT_UNREF (face);
- }
- device->foreground
- = get_color (display, cmap, msymbol (app_data.foreground), Mnil,
- device->foreground);
- device->background
- = get_color (display, cmap, msymbol (app_data.background), Mnil,
- device->background);
+ mface_put_prop (face, Mvideomode, Mreverse);
+ mplist_push (param, Mface, face);
+ M17N_OBJECT_UNREF (face);
}
+
+#ifdef X_SET_ERROR_HANDLER
XSetErrorHandler (x_error_handler);
- /* XSetIOErrorHandler (x_io_error_handler); */
+ XSetIOErrorHandler (x_io_error_handler);
+#endif
return device;
}
GC *gc_table;
} gc_list;
-#define REGISTER_GC(gc) \
- do { \
- if (! gc_list.size) \
- MLIST_INIT1 (&gc_list, gc_table, 100); \
- MLIST_APPEND1 (&gc_list, gc_table, gc, MERROR_WIN); \
- } while (0)
-
-
-#define UNREGISTER_GC(gc) \
- do { \
- int j; \
- for (j = 0; j < gc_list.used; j++) \
- if (gc_list.gc_table[j] == gc) \
- gc_list.gc_table[j] = (GC) NULL; \
- } while (0)
-
static GC
-get_gc (MWDevice *device, XColor *color)
+get_gc (MFrame *frame, MSymbol color, int for_foreground)
{
+ MWDevice *device = frame->device;
+ XColor xcolor;
MPlist *plist;
unsigned long valuemask = GCForeground;
XGCValues values;
GC gc;
MColorGC *color_gc;
+ unsigned int rgb;
+
+ if (! XParseColor (FRAME_DISPLAY (frame), device->cmap,
+ msymbol_name (color), &xcolor))
+ return (for_foreground ? device->gc_fore : device->gc_back);
+ rgb = (((xcolor.red >> 8) << 16) | ((xcolor.green >> 8) << 8)
+ | (xcolor.blue >> 8));
MPLIST_DO (plist, device->gc_list)
{
color_gc = MPLIST_VAL (plist);
- if (color->red == color_gc->r
- && color->green == color_gc->g
- && color->blue == color_gc->b)
+ if (color_gc->rgb == rgb)
return color_gc->gc;
+ if (color_gc->rgb > rgb)
+ break;
}
- if (! XAllocColor (device->display_info->display, device->cmap, color))
- return DefaultGC (device->display_info->display, device->screen_num);
- values.foreground = color->pixel;
- gc = XCreateGC (device->display_info->display, device->drawable,
- valuemask, &values);
+ if (! XAllocColor (FRAME_DISPLAY (frame), device->cmap, &xcolor))
+ return (for_foreground ? device->gc_fore : device->gc_back);
+ values.foreground = xcolor.pixel;
+ gc = XCreateGC (FRAME_DISPLAY (frame), device->drawable, valuemask, &values);
color_gc = malloc (sizeof (MColorGC));
- color_gc->r = color->red;
- color_gc->g = color->green;
- color_gc->b = color->blue;
+ color_gc->rgb = rgb;
color_gc->gc = gc;
mplist_push (plist, Mt, color_gc);
return gc;
mwin__realize_face (MRealizedFace *rface)
{
MFrame *frame = rface->frame;
- MWDevice *device = frame->device;
- Display *display = FRAME_DISPLAY (frame);
- XGCValues values;
- int mask = GCForeground | GCBackground;
MSymbol foreground = rface->face.property[MFACE_FOREGROUND];
MSymbol background = rface->face.property[MFACE_BACKGROUND];
MFaceHLineProp *hline = rface->hline;
MFaceBoxProp *box = rface->box;
MFaceHookFunc func = (MFaceHookFunc) rface->face.property[MFACE_HOOK_FUNC];
- MSymbol default_foreground
- = (MSymbol) mface_get_prop (frame->face, Mforeground);
- MSymbol default_background
- = (MSymbol) mface_get_prop (frame->face, Mbackground);
GC *gcs;
- unsigned long pixel;
- MTABLE_CALLOC (gcs, MFACE_GCS, MERROR_WIN);
+ MTABLE_CALLOC (gcs, MFACE_GCS + 1, MERROR_WIN);
- values.foreground = get_color (display, device->cmap, foreground,
- default_foreground, device->foreground);
- values.background = get_color (display, device->cmap, background,
- default_background, device->background);
- if (rface->face.property[MFACE_VIDEOMODE] == Mreverse)
- pixel = values.foreground,
- values.foreground = values.background,
- values.background = pixel;
+ gcs[MFACE_GC_NORMAL] = get_gc (frame, foreground, 1);
+ gcs[MFACE_GC_INVERSE] = get_gc (frame, background, 0);
- if (rface->rfont
- && rface->rfont->font.property[MFONT_TYPE] - 1 == MFONT_TYPE_WIN)
+ if (rface->face.property[MFACE_VIDEOMODE] == Mreverse)
{
- values.font = ((MXFontInfo *) (rface->rfont->info))->f->fid;
- mask |= GCFont;
+ GC gc = gcs[MFACE_GC_NORMAL];
+ gcs[MFACE_GC_NORMAL] = gcs[MFACE_GC_INVERSE];
+ gcs[MFACE_GC_INVERSE] = gc;
}
- gcs[MFACE_GC_NORMAL] = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_NORMAL]);
-
- gcs[MFACE_GC_SCRATCH] = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_SCRATCH]);
-
- pixel = values.foreground;
- values.foreground = values.background;
- values.background = pixel;
- gcs[MFACE_GC_INVERSE] = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_INVERSE]);
- values.background = values.foreground;
- values.foreground = pixel;
-
- mask &= ~GCFont;
-
if (rface == rface->ascii_rface)
{
/* This realized face is for ASCII. Setup GCs for hline and
box. */
if (hline && hline->color != foreground)
- {
- values.foreground
- = get_color (display, device->cmap, hline->color,
- default_foreground, device->foreground);
- gcs[MFACE_GC_HLINE]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_HLINE]);
- values.foreground = pixel;
- }
+ gcs[MFACE_GC_HLINE] = get_gc (frame, hline->color, 1);
if (box)
{
if (box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_top,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_TOP]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_TOP]);
- }
+ gcs[MFACE_GC_BOX_TOP] = get_gc (frame, box->color_top, 1);
+ else
+ gcs[MFACE_GC_BOX_TOP] = gcs[MFACE_GC_NORMAL];
- if (box->color_left
- && box->color_left != box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_left,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_LEFT]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_LEFT]);
- }
+ if (box->color_left && box->color_left != box->color_top)
+ gcs[MFACE_GC_BOX_LEFT] = get_gc (frame, box->color_left, 1);
+ else
+ gcs[MFACE_GC_BOX_LEFT] = gcs[MFACE_GC_BOX_TOP];
- if (box->color_right
- && box->color_right != box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_right,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_RIGHT]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_RIGHT]);
- }
+ if (box->color_bottom && box->color_bottom != box->color_top)
+ gcs[MFACE_GC_BOX_BOTTOM] = get_gc (frame, box->color_bottom, 1);
+ else
+ gcs[MFACE_GC_BOX_BOTTOM] = gcs[MFACE_GC_BOX_TOP];
- if (box->color_bottom
- && box->color_bottom != box->color_top)
- {
- values.foreground
- = get_color (display, device->cmap, box->color_bottom,
- default_foreground, device->foreground);
- gcs[MFACE_GC_BOX_BOTTOM]
- = XCreateGC (display, device->drawable, mask, &values);
- REGISTER_GC (gcs[MFACE_GC_BOX_BOTTOM]);
- }
+ if (box->color_right && box->color_right != box->color_top)
+ gcs[MFACE_GC_BOX_RIGHT] = get_gc (frame, box->color_right, 1);
+ else
+ gcs[MFACE_GC_BOX_RIGHT] = gcs[MFACE_GC_BOX_BOTTOM];
}
}
else
void
mwin__free_realized_face (MRealizedFace *rface)
{
- GC *gcs = rface->info;
- enum face_gc limit
- = rface == rface->ascii_rface ? MFACE_GCS : MFACE_GC_HLINE;
- int i;
-
- for (i = 0; i < limit; i++)
- if (gcs[i])
- {
- UNREGISTER_GC (gcs[i]);
- XFreeGC (FRAME_DISPLAY (rface->frame), gcs[i]);
- }
- free (gcs);
+ free (rface->info);
}
GC gc = gcs[reverse ? MFACE_GC_NORMAL : MFACE_GC_INVERSE];
if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
+ gc = set_region (frame, gc, region);
XFillRectangle (FRAME_DISPLAY (frame), (Window) win, gc,
x, y, width, height);
gc = gcs[MFACE_GC_NORMAL];
if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
+ gc = set_region (frame, gc, region);
for (i = 0; i < rface->hline->width; i++)
XDrawLine (FRAME_DISPLAY (frame), (Window) win, gc,
if (! gc_top)
gc_top = gcs[MFACE_GC_NORMAL];
if (region)
- gc_top = set_region (FRAME_DISPLAY (frame), rface, gc_top, region);
+ gc_top = set_region (frame, gc_top, region);
gc_btm = gcs[MFACE_GC_BOX_BOTTOM];
if (! gc_btm)
gc_btm = gc_top;
/* Draw the bottom side. */
if (region)
- gc_btm = set_region (display, rface, gc_btm, region);
+ gc_btm = set_region (frame, gc_btm, region);
for (i = 0; i < box->width; i++)
XDrawLine (display, (Window) win, gc_btm, x0, y1 - i, x1, y1 - i);
if (! gc_left)
gc_left = gc_top;
else if (region)
- gc_left = set_region (display, rface, gc_left, region);
+ gc_left = set_region (frame, gc_left, region);
for (i = 0; i < rface->box->width; i++)
XDrawLine (display, (Window) win, gc_left,
x0 + i, y0 + i, x0 + i, y1 - i);
if (! gc_right)
gc_right = gc_top;
else if (region)
- gc_right = set_region (display, rface, gc_right, region);
+ gc_right = set_region (frame, gc_right, region);
for (i = 0; i < rface->box->width; i++)
XDrawLine (display, (Window) win, gc_right,
x1 - i, y0 + i, x1 - i, y1 - i);
/* Draw the bottom side. */
if (region)
- gc_btm = set_region (display, rface, gc_btm, region);
+ gc_btm = set_region (frame, gc_btm, region);
for (i = 0; i < box->width; i++)
XDrawLine (display, (Window) win, gc_btm,
x, y1 - i, x + width - 1, y1 - i);
GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
+ gc = set_region (frame, gc, region);
for (i = 0; i < height; i++, bmp += row_bytes)
for (j = 0; j < width; j++)
Display *display = FRAME_DISPLAY (frame);
int i, j;
GC *gcs = rface->info;
- GC gc = gcs[reverse ? MFACE_GC_INVERSE : MFACE_GC_NORMAL];
+ GC gc;
unsigned long valuemask = GCForeground | GCBackground;
XGCValues values;
XColor fore_color, back_color, color;
- if (region)
- gc = set_region (FRAME_DISPLAY (frame), rface, gc, region);
-
XGetGCValues (FRAME_DISPLAY (frame), gc, valuemask, &values);
fore_color.pixel = values.foreground;
back_color.pixel = values.background;
XQueryColor (FRAME_DISPLAY (frame), frame->device->cmap, &fore_color);
XQueryColor (FRAME_DISPLAY (frame), frame->device->cmap, &back_color);
+ if (! gcs[MFACE_GCS])
+ {
+ GC *new_gcs;
+
+ MTABLE_CALLOC (new_gcs, MFACE_GCS + 6, MERROR_WIN);
+ memcpy (new_gcs, gcs, sizeof (GC) * MFACE_GCS);
+ for (i = 0; i < 6; i++)
+ {
+
+ }
+
+ }
+
+ if (region)
+ gc = set_region (frame, gc, region);
+
+
+
for (i = 0; i < height; i++, pmp += row_bytes)
for (j = 0; j < width; j++)
if (pmp[j])
void
mwin__verify_region (MFrame *frame, MDrawRegion region)
{
- set_region (FRAME_DISPLAY (frame), frame->rface,
- ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region);
+ set_region (frame, ((GC *) frame->rface->info)[MFACE_GC_NORMAL], region);
}
MDrawWindow
mwin__create_window (MFrame *frame, MDrawWindow parent)
{
- MWDevice *device = frame->device;
Display *display = FRAME_DISPLAY (frame);
- int screen = FRAME_SCREEN (frame);
Window win;
XWMHints wm_hints = { InputHint, False };
XClassHint class_hints = { "M17N-IM", "m17n-im" };
- XSetWindowAttributes attrs;
+ XWindowAttributes win_attrs;
+ XSetWindowAttributes set_attrs;
unsigned long mask;
- MSymbol background = mface_get_prop (frame->face, Mbackground);
-
- attrs.background_pixel = get_color (display, device->cmap,
- background, background,
- WhitePixel (display, screen));
- attrs.backing_store = Always;
- attrs.override_redirect = True;
- attrs.save_under = True;
- mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
+
if (! parent)
- parent = (MDrawWindow) RootWindow (display, screen);
+ parent = (MDrawWindow) RootWindow (display, FRAME_SCREEN (frame));
+ XGetWindowAttributes (display, (Window) parent, &win_attrs);
+ set_attrs.background_pixel = win_attrs.backing_pixel;
+ set_attrs.backing_store = Always;
+ set_attrs.override_redirect = True;
+ set_attrs.save_under = True;
+ mask = CWBackPixel | CWBackingStore | CWOverrideRedirect | CWSaveUnder;
win = XCreateWindow (display, (Window) parent, 0, 0, 1, 1, 0,
CopyFromParent, InputOutput, CopyFromParent,
- mask, &attrs);
+ mask, &set_attrs);
XSetWMProperties (display, (Window) win, NULL, NULL, NULL, 0,
NULL, &wm_hints, &class_hints);
XSelectInput (display, (Window) win, StructureNotifyMask | ExposureMask);
GC *gcs = rface->info;
int i;
- for (i = 0; i <= MFACE_GC_SCRATCH; i++)
+ for (i = 0; i <= MFACE_GC_INVERSE; i++)
{
XGetGCValues (display, gcs[i], valuemask, &values);
fprintf (stderr, "GC%d: fore/#%lX back/#%lX", i,