Commit 651f03b6 authored by Gerd Moellmann's avatar Gerd Moellmann
Browse files

(x_alloc_nearest_color_1): New function.

(x_alloc_nearest_color): Use it.
(x_color_cells): Take a Display as argument, instead of a frame.
(string_to_pixel_args, cvt_string_to_pixel_value): New variables.
(cvt_string_to_pixel, cvt_pixel_dtor): New functions.
(x_initialize): Register cvt_string_to_pixel as resource converter
string -> Pixel and cvt_pixel_dtor as pixel resource destructor.
parent 3ade370a
2001-04-02 Gerd Moellmann <gerd@gnu.org>
* xterm.c (x_alloc_nearest_color_1): New function.
(x_alloc_nearest_color): Use it.
(x_color_cells): Take a Display as argument, instead of a frame.
(cvt_string_to_pixel_args, cvt_string_to_pixel_value): New variables.
(cvt_string_to_pixel, cvt_pixel_dtor): New functions.
(x_initialize): Register cvt_string_to_pixel as resource converter
string -> Pixel and cvt_pixel_dtor as pixel resource destructor.
2001-03-30 Gerd Moellmann <gerd@gnu.org> 2001-03-30 Gerd Moellmann <gerd@gnu.org>
* xdisp.c (get_overlay_strings): Set iterator's end_charpos. * xdisp.c (get_overlay_strings): Set iterator's end_charpos.
......
...@@ -395,8 +395,9 @@ enum draw_glyphs_face ...@@ -395,8 +395,9 @@ enum draw_glyphs_face
DRAW_IMAGE_SUNKEN DRAW_IMAGE_SUNKEN
}; };
static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
static void x_set_window_size_1 P_ ((struct frame *, int, int, int)); static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
static const XColor *x_color_cells P_ ((struct frame *, int *)); static const XColor *x_color_cells P_ ((Display *, int *));
static void x_update_window_end P_ ((struct window *, int, int)); static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
void x_delete_display P_ ((struct x_display_info *)); void x_delete_display P_ ((struct x_display_info *));
...@@ -3244,6 +3245,10 @@ x_draw_composite_glyph_string_foreground (s) ...@@ -3244,6 +3245,10 @@ x_draw_composite_glyph_string_foreground (s)
#ifdef USE_X_TOOLKIT #ifdef USE_X_TOOLKIT
static struct frame *x_frame_of_widget P_ ((Widget)); static struct frame *x_frame_of_widget P_ ((Widget));
static Boolean cvt_string_to_pixel P_ ((Display *, XrmValue *, Cardinal *,
XrmValue *, XrmValue *, XtPointer *));
static void cvt_pixel_dtor P_ ((XtAppContext, XrmValue *, XtPointer,
XrmValue *, Cardinal *));
/* Return the frame on which widget WIDGET is used.. Abort if frame /* Return the frame on which widget WIDGET is used.. Abort if frame
...@@ -3317,29 +3322,178 @@ x_alloc_lighter_color_for_widget (widget, display, cmap, pixel, factor, delta) ...@@ -3317,29 +3322,178 @@ x_alloc_lighter_color_for_widget (widget, display, cmap, pixel, factor, delta)
} }
/* Structure specifying which arguments should be passed by Xt to
cvt_string_to_pixel. We want the widget's screen and colormap. */
static XtConvertArgRec cvt_string_to_pixel_args[] =
{
{XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.screen),
sizeof (Screen *)},
{XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.colormap),
sizeof (Colormap)}
};
/* The address of this variable is returned by
cvt_string_to_pixel. */
static Pixel cvt_string_to_pixel_value;
/* Convert a color name to a pixel color.
DPY is the display we are working on.
ARGS is an array of *NARGS XrmValue structures holding additional
information about the widget for which the conversion takes place.
The contents of this array are determined by the specification
in cvt_string_to_pixel_args.
FROM is a pointer to an XrmValue which points to the color name to
convert. TO is an XrmValue in which to return the pixel color.
CLOSURE_RET is a pointer to user-data, in which we record if
we allocated the color or not.
Value is True if successful, False otherwise. */
static Boolean
cvt_string_to_pixel (dpy, args, nargs, from, to, closure_ret)
Display *dpy;
XrmValue *args;
Cardinal *nargs;
XrmValue *from, *to;
XtPointer *closure_ret;
{
Screen *screen;
Colormap cmap;
Pixel pixel;
String color_name;
XColor color;
if (*nargs != 2)
{
XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
"wrongParameters", "cvt_string_to_pixel",
"XtToolkitError",
"Screen and colormap args required", NULL, NULL);
return False;
}
screen = *(Screen **) args[0].addr;
cmap = *(Colormap *) args[1].addr;
color_name = (String) from->addr;
if (strcmp (color_name, XtDefaultBackground) == 0)
{
*closure_ret = (XtPointer) False;
pixel = WhitePixelOfScreen (screen);
}
else if (strcmp (color_name, XtDefaultForeground) == 0)
{
*closure_ret = (XtPointer) False;
pixel = BlackPixelOfScreen (screen);
}
else if (XParseColor (dpy, cmap, color_name, &color)
&& x_alloc_nearest_color_1 (dpy, cmap, &color))
{
pixel = color.pixel;
*closure_ret = (XtPointer) True;
}
else
{
String params[1];
Cardinal nparams = 1;
params[0] = color_name;
XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
"badValue", "cvt_string_to_pixel",
"XtToolkitError", "Invalid color `%s'",
params, &nparams);
return False;
}
if (to->addr != NULL)
{
if (to->size < sizeof (Pixel))
{
to->size = sizeof (Pixel);
return False;
}
*(Pixel *) to->addr = pixel;
}
else
{
cvt_string_to_pixel_value = pixel;
to->addr = (XtPointer) &cvt_string_to_pixel_value;
}
to->size = sizeof (Pixel);
return True;
}
/* Free a pixel color which was previously allocated via
cvt_string_to_pixel. This is registered as the destructor
for this type of resource via XtSetTypeConverter.
APP is the application context in which we work.
TO is a pointer to an XrmValue holding the color to free.
CLOSURE is the value we stored in CLOSURE_RET for this color
in cvt_string_to_pixel.
ARGS and NARGS are like for cvt_string_to_pixel. */
static void
cvt_pixel_dtor (app, to, closure, args, nargs)
XtAppContext app;
XrmValuePtr to;
XtPointer closure;
XrmValuePtr args;
Cardinal *nargs;
{
if (*nargs != 2)
{
XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
"XtToolkitError",
"Screen and colormap arguments required",
NULL, NULL);
}
else if (closure != NULL)
{
/* We did allocate the pixel, so free it. */
Screen *screen = *(Screen **) args[0].addr;
Colormap cmap = *(Colormap *) args[1].addr;
x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
(Pixel *) to->addr, 1, 0);
}
}
#endif /* USE_X_TOOLKIT */ #endif /* USE_X_TOOLKIT */
/* Value is an array of XColor structures for the contents of the /* Value is an array of XColor structures for the contents of the
color map of frame F. Set *NCELLS to the size of the array. color map of display DPY. Set *NCELLS to the size of the array.
Note that this probably shouldn't be called for large color maps, Note that this probably shouldn't be called for large color maps,
say a 24-bit TrueColor map. */ say a 24-bit TrueColor map. */
static const XColor * static const XColor *
x_color_cells (f, ncells) x_color_cells (dpy, ncells)
struct frame *f; Display *dpy;
int *ncells; int *ncells;
{ {
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
if (dpyinfo->color_cells == NULL) if (dpyinfo->color_cells == NULL)
{ {
Display *display = FRAME_X_DISPLAY (f); Screen *screen = dpyinfo->screen;
Screen *screen = FRAME_X_SCREEN (f);
int i; int i;
dpyinfo->ncolor_cells dpyinfo->ncolor_cells
= XDisplayCells (display, XScreenNumberOfScreen (screen)); = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
dpyinfo->color_cells dpyinfo->color_cells
= (XColor *) xmalloc (dpyinfo->ncolor_cells = (XColor *) xmalloc (dpyinfo->ncolor_cells
* sizeof *dpyinfo->color_cells); * sizeof *dpyinfo->color_cells);
...@@ -3347,7 +3501,7 @@ x_color_cells (f, ncells) ...@@ -3347,7 +3501,7 @@ x_color_cells (f, ncells)
for (i = 0; i < dpyinfo->ncolor_cells; ++i) for (i = 0; i < dpyinfo->ncolor_cells; ++i)
dpyinfo->color_cells[i].pixel = i; dpyinfo->color_cells[i].pixel = i;
XQueryColors (display, FRAME_X_COLORMAP (f), XQueryColors (dpy, dpyinfo->cmap,
dpyinfo->color_cells, dpyinfo->ncolor_cells); dpyinfo->color_cells, dpyinfo->ncolor_cells);
} }
...@@ -3395,23 +3549,20 @@ x_query_color (f, color) ...@@ -3395,23 +3549,20 @@ x_query_color (f, color)
} }
/* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
CMAP. If an exact match can't be allocated, try the nearest color exact match can't be allocated, try the nearest color available.
available. Value is non-zero if successful. Set *COLOR to the Value is non-zero if successful. Set *COLOR to the color
color allocated. */ allocated. */
int static int
x_alloc_nearest_color (f, cmap, color) x_alloc_nearest_color_1 (dpy, cmap, color)
struct frame *f; Display *dpy;
Colormap cmap; Colormap cmap;
XColor *color; XColor *color;
{ {
Display *display = FRAME_X_DISPLAY (f);
Screen *screen = FRAME_X_SCREEN (f);
int rc; int rc;
gamma_correct (f, color); rc = XAllocColor (dpy, cmap, color);
rc = XAllocColor (display, cmap, color);
if (rc == 0) if (rc == 0)
{ {
/* If we got to this point, the colormap is full, so we're going /* If we got to this point, the colormap is full, so we're going
...@@ -3421,7 +3572,7 @@ x_alloc_nearest_color (f, cmap, color) ...@@ -3421,7 +3572,7 @@ x_alloc_nearest_color (f, cmap, color)
int nearest, i; int nearest, i;
unsigned long nearest_delta = ~0; unsigned long nearest_delta = ~0;
int ncells; int ncells;
const XColor *cells = x_color_cells (f, &ncells); const XColor *cells = x_color_cells (dpy, &ncells);
for (nearest = i = 0; i < ncells; ++i) for (nearest = i = 0; i < ncells; ++i)
{ {
...@@ -3440,14 +3591,14 @@ x_alloc_nearest_color (f, cmap, color) ...@@ -3440,14 +3591,14 @@ x_alloc_nearest_color (f, cmap, color)
color->red = cells[nearest].red; color->red = cells[nearest].red;
color->green = cells[nearest].green; color->green = cells[nearest].green;
color->blue = cells[nearest].blue; color->blue = cells[nearest].blue;
rc = XAllocColor (display, cmap, color); rc = XAllocColor (dpy, cmap, color);
} }
else else
{ {
/* If allocation succeeded, and the allocated pixel color is not /* If allocation succeeded, and the allocated pixel color is not
equal to a cached pixel color recorded earlier, there was a equal to a cached pixel color recorded earlier, there was a
change in the colormap, so clear the color cache. */ change in the colormap, so clear the color cache. */
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
XColor *cached_color; XColor *cached_color;
if (dpyinfo->color_cells if (dpyinfo->color_cells
...@@ -3471,6 +3622,22 @@ x_alloc_nearest_color (f, cmap, color) ...@@ -3471,6 +3622,22 @@ x_alloc_nearest_color (f, cmap, color)
} }
/* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
exact match can't be allocated, try the nearest color available.
Value is non-zero if successful. Set *COLOR to the color
allocated. */
int
x_alloc_nearest_color (f, cmap, color)
struct frame *f;
Colormap cmap;
XColor *color;
{
gamma_correct (f, color);
return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
}
/* Allocate color PIXEL on frame F. PIXEL must already be allocated. /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
It's necessary to do this instead of just using PIXEL directly to It's necessary to do this instead of just using PIXEL directly to
get color reference counts right. */ get color reference counts right. */
...@@ -14166,7 +14333,17 @@ x_initialize () ...@@ -14166,7 +14333,17 @@ x_initialize ()
#ifdef USE_X_TOOLKIT #ifdef USE_X_TOOLKIT
XtToolkitInitialize (); XtToolkitInitialize ();
Xt_app_con = XtCreateApplicationContext (); Xt_app_con = XtCreateApplicationContext ();
/* Register a converter from strings to pixels, which uses
Emacs' color allocation infrastructure. */
XtAppSetTypeConverter (Xt_app_con,
XtRString, XtRPixel, cvt_string_to_pixel,
cvt_string_to_pixel_args,
XtNumber (cvt_string_to_pixel_args),
XtCacheByDisplay, cvt_pixel_dtor);
XtAppSetFallbackResources (Xt_app_con, Xt_default_resources); XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
/* Install an asynchronous timer that processes Xt timeout events /* Install an asynchronous timer that processes Xt timeout events
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment