comparison src/xterm.c @ 37143:187f754d89cc

(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.
author Gerd Moellmann <gerd@gnu.org>
date Mon, 02 Apr 2001 15:49:25 +0000
parents fe7885cc9458
children 3799cab1815b
comparison
equal deleted inserted replaced
37142:e107572ba2dd 37143:187f754d89cc
393 DRAW_MOUSE_FACE, 393 DRAW_MOUSE_FACE,
394 DRAW_IMAGE_RAISED, 394 DRAW_IMAGE_RAISED,
395 DRAW_IMAGE_SUNKEN 395 DRAW_IMAGE_SUNKEN
396 }; 396 };
397 397
398 static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
398 static void x_set_window_size_1 P_ ((struct frame *, int, int, int)); 399 static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
399 static const XColor *x_color_cells P_ ((struct frame *, int *)); 400 static const XColor *x_color_cells P_ ((Display *, int *));
400 static void x_update_window_end P_ ((struct window *, int, int)); 401 static void x_update_window_end P_ ((struct window *, int, int));
401 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); 402 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
402 void x_delete_display P_ ((struct x_display_info *)); 403 void x_delete_display P_ ((struct x_display_info *));
403 static unsigned int x_x_to_emacs_modifiers P_ ((struct x_display_info *, 404 static unsigned int x_x_to_emacs_modifiers P_ ((struct x_display_info *,
404 unsigned)); 405 unsigned));
3242 3243
3243 3244
3244 #ifdef USE_X_TOOLKIT 3245 #ifdef USE_X_TOOLKIT
3245 3246
3246 static struct frame *x_frame_of_widget P_ ((Widget)); 3247 static struct frame *x_frame_of_widget P_ ((Widget));
3248 static Boolean cvt_string_to_pixel P_ ((Display *, XrmValue *, Cardinal *,
3249 XrmValue *, XrmValue *, XtPointer *));
3250 static void cvt_pixel_dtor P_ ((XtAppContext, XrmValue *, XtPointer,
3251 XrmValue *, Cardinal *));
3247 3252
3248 3253
3249 /* Return the frame on which widget WIDGET is used.. Abort if frame 3254 /* Return the frame on which widget WIDGET is used.. Abort if frame
3250 cannot be determined. */ 3255 cannot be determined. */
3251 3256
3315 struct frame *f = x_frame_of_widget (widget); 3320 struct frame *f = x_frame_of_widget (widget);
3316 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta); 3321 return x_alloc_lighter_color (f, display, cmap, pixel, factor, delta);
3317 } 3322 }
3318 3323
3319 3324
3325 /* Structure specifying which arguments should be passed by Xt to
3326 cvt_string_to_pixel. We want the widget's screen and colormap. */
3327
3328 static XtConvertArgRec cvt_string_to_pixel_args[] =
3329 {
3330 {XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.screen),
3331 sizeof (Screen *)},
3332 {XtWidgetBaseOffset, (XtPointer) XtOffset (Widget, core.colormap),
3333 sizeof (Colormap)}
3334 };
3335
3336
3337 /* The address of this variable is returned by
3338 cvt_string_to_pixel. */
3339
3340 static Pixel cvt_string_to_pixel_value;
3341
3342
3343 /* Convert a color name to a pixel color.
3344
3345 DPY is the display we are working on.
3346
3347 ARGS is an array of *NARGS XrmValue structures holding additional
3348 information about the widget for which the conversion takes place.
3349 The contents of this array are determined by the specification
3350 in cvt_string_to_pixel_args.
3351
3352 FROM is a pointer to an XrmValue which points to the color name to
3353 convert. TO is an XrmValue in which to return the pixel color.
3354
3355 CLOSURE_RET is a pointer to user-data, in which we record if
3356 we allocated the color or not.
3357
3358 Value is True if successful, False otherwise. */
3359
3360 static Boolean
3361 cvt_string_to_pixel (dpy, args, nargs, from, to, closure_ret)
3362 Display *dpy;
3363 XrmValue *args;
3364 Cardinal *nargs;
3365 XrmValue *from, *to;
3366 XtPointer *closure_ret;
3367 {
3368 Screen *screen;
3369 Colormap cmap;
3370 Pixel pixel;
3371 String color_name;
3372 XColor color;
3373
3374 if (*nargs != 2)
3375 {
3376 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
3377 "wrongParameters", "cvt_string_to_pixel",
3378 "XtToolkitError",
3379 "Screen and colormap args required", NULL, NULL);
3380 return False;
3381 }
3382
3383 screen = *(Screen **) args[0].addr;
3384 cmap = *(Colormap *) args[1].addr;
3385 color_name = (String) from->addr;
3386
3387 if (strcmp (color_name, XtDefaultBackground) == 0)
3388 {
3389 *closure_ret = (XtPointer) False;
3390 pixel = WhitePixelOfScreen (screen);
3391 }
3392 else if (strcmp (color_name, XtDefaultForeground) == 0)
3393 {
3394 *closure_ret = (XtPointer) False;
3395 pixel = BlackPixelOfScreen (screen);
3396 }
3397 else if (XParseColor (dpy, cmap, color_name, &color)
3398 && x_alloc_nearest_color_1 (dpy, cmap, &color))
3399 {
3400 pixel = color.pixel;
3401 *closure_ret = (XtPointer) True;
3402 }
3403 else
3404 {
3405 String params[1];
3406 Cardinal nparams = 1;
3407
3408 params[0] = color_name;
3409 XtAppWarningMsg (XtDisplayToApplicationContext (dpy),
3410 "badValue", "cvt_string_to_pixel",
3411 "XtToolkitError", "Invalid color `%s'",
3412 params, &nparams);
3413 return False;
3414 }
3415
3416 if (to->addr != NULL)
3417 {
3418 if (to->size < sizeof (Pixel))
3419 {
3420 to->size = sizeof (Pixel);
3421 return False;
3422 }
3423
3424 *(Pixel *) to->addr = pixel;
3425 }
3426 else
3427 {
3428 cvt_string_to_pixel_value = pixel;
3429 to->addr = (XtPointer) &cvt_string_to_pixel_value;
3430 }
3431
3432 to->size = sizeof (Pixel);
3433 return True;
3434 }
3435
3436
3437 /* Free a pixel color which was previously allocated via
3438 cvt_string_to_pixel. This is registered as the destructor
3439 for this type of resource via XtSetTypeConverter.
3440
3441 APP is the application context in which we work.
3442
3443 TO is a pointer to an XrmValue holding the color to free.
3444 CLOSURE is the value we stored in CLOSURE_RET for this color
3445 in cvt_string_to_pixel.
3446
3447 ARGS and NARGS are like for cvt_string_to_pixel. */
3448
3449 static void
3450 cvt_pixel_dtor (app, to, closure, args, nargs)
3451 XtAppContext app;
3452 XrmValuePtr to;
3453 XtPointer closure;
3454 XrmValuePtr args;
3455 Cardinal *nargs;
3456 {
3457 if (*nargs != 2)
3458 {
3459 XtAppWarningMsg (app, "wrongParameters", "cvt_pixel_dtor",
3460 "XtToolkitError",
3461 "Screen and colormap arguments required",
3462 NULL, NULL);
3463 }
3464 else if (closure != NULL)
3465 {
3466 /* We did allocate the pixel, so free it. */
3467 Screen *screen = *(Screen **) args[0].addr;
3468 Colormap cmap = *(Colormap *) args[1].addr;
3469 x_free_dpy_colors (DisplayOfScreen (screen), screen, cmap,
3470 (Pixel *) to->addr, 1, 0);
3471 }
3472 }
3473
3474
3320 #endif /* USE_X_TOOLKIT */ 3475 #endif /* USE_X_TOOLKIT */
3321 3476
3322 3477
3323 /* Value is an array of XColor structures for the contents of the 3478 /* Value is an array of XColor structures for the contents of the
3324 color map of frame F. Set *NCELLS to the size of the array. 3479 color map of display DPY. Set *NCELLS to the size of the array.
3325 Note that this probably shouldn't be called for large color maps, 3480 Note that this probably shouldn't be called for large color maps,
3326 say a 24-bit TrueColor map. */ 3481 say a 24-bit TrueColor map. */
3327 3482
3328 static const XColor * 3483 static const XColor *
3329 x_color_cells (f, ncells) 3484 x_color_cells (dpy, ncells)
3330 struct frame *f; 3485 Display *dpy;
3331 int *ncells; 3486 int *ncells;
3332 { 3487 {
3333 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 3488 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
3334 3489
3335 if (dpyinfo->color_cells == NULL) 3490 if (dpyinfo->color_cells == NULL)
3336 { 3491 {
3337 Display *display = FRAME_X_DISPLAY (f); 3492 Screen *screen = dpyinfo->screen;
3338 Screen *screen = FRAME_X_SCREEN (f);
3339 int i; 3493 int i;
3340 3494
3341 dpyinfo->ncolor_cells 3495 dpyinfo->ncolor_cells
3342 = XDisplayCells (display, XScreenNumberOfScreen (screen)); 3496 = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
3343 dpyinfo->color_cells 3497 dpyinfo->color_cells
3344 = (XColor *) xmalloc (dpyinfo->ncolor_cells 3498 = (XColor *) xmalloc (dpyinfo->ncolor_cells
3345 * sizeof *dpyinfo->color_cells); 3499 * sizeof *dpyinfo->color_cells);
3346 3500
3347 for (i = 0; i < dpyinfo->ncolor_cells; ++i) 3501 for (i = 0; i < dpyinfo->ncolor_cells; ++i)
3348 dpyinfo->color_cells[i].pixel = i; 3502 dpyinfo->color_cells[i].pixel = i;
3349 3503
3350 XQueryColors (display, FRAME_X_COLORMAP (f), 3504 XQueryColors (dpy, dpyinfo->cmap,
3351 dpyinfo->color_cells, dpyinfo->ncolor_cells); 3505 dpyinfo->color_cells, dpyinfo->ncolor_cells);
3352 } 3506 }
3353 3507
3354 *ncells = dpyinfo->ncolor_cells; 3508 *ncells = dpyinfo->ncolor_cells;
3355 return dpyinfo->color_cells; 3509 return dpyinfo->color_cells;
3393 { 3547 {
3394 x_query_colors (f, color, 1); 3548 x_query_colors (f, color, 1);
3395 } 3549 }
3396 3550
3397 3551
3398 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap 3552 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an
3399 CMAP. If an exact match can't be allocated, try the nearest color 3553 exact match can't be allocated, try the nearest color available.
3400 available. Value is non-zero if successful. Set *COLOR to the 3554 Value is non-zero if successful. Set *COLOR to the color
3401 color allocated. */ 3555 allocated. */
3402 3556
3403 int 3557 static int
3404 x_alloc_nearest_color (f, cmap, color) 3558 x_alloc_nearest_color_1 (dpy, cmap, color)
3405 struct frame *f; 3559 Display *dpy;
3406 Colormap cmap; 3560 Colormap cmap;
3407 XColor *color; 3561 XColor *color;
3408 { 3562 {
3409 Display *display = FRAME_X_DISPLAY (f);
3410 Screen *screen = FRAME_X_SCREEN (f);
3411 int rc; 3563 int rc;
3412 3564
3413 gamma_correct (f, color); 3565 rc = XAllocColor (dpy, cmap, color);
3414 rc = XAllocColor (display, cmap, color);
3415 if (rc == 0) 3566 if (rc == 0)
3416 { 3567 {
3417 /* If we got to this point, the colormap is full, so we're going 3568 /* If we got to this point, the colormap is full, so we're going
3418 to try to get the next closest color. The algorithm used is 3569 to try to get the next closest color. The algorithm used is
3419 a least-squares matching, which is what X uses for closest 3570 a least-squares matching, which is what X uses for closest
3420 color matching with StaticColor visuals. */ 3571 color matching with StaticColor visuals. */
3421 int nearest, i; 3572 int nearest, i;
3422 unsigned long nearest_delta = ~0; 3573 unsigned long nearest_delta = ~0;
3423 int ncells; 3574 int ncells;
3424 const XColor *cells = x_color_cells (f, &ncells); 3575 const XColor *cells = x_color_cells (dpy, &ncells);
3425 3576
3426 for (nearest = i = 0; i < ncells; ++i) 3577 for (nearest = i = 0; i < ncells; ++i)
3427 { 3578 {
3428 long dred = (color->red >> 8) - (cells[i].red >> 8); 3579 long dred = (color->red >> 8) - (cells[i].red >> 8);
3429 long dgreen = (color->green >> 8) - (cells[i].green >> 8); 3580 long dgreen = (color->green >> 8) - (cells[i].green >> 8);
3438 } 3589 }
3439 3590
3440 color->red = cells[nearest].red; 3591 color->red = cells[nearest].red;
3441 color->green = cells[nearest].green; 3592 color->green = cells[nearest].green;
3442 color->blue = cells[nearest].blue; 3593 color->blue = cells[nearest].blue;
3443 rc = XAllocColor (display, cmap, color); 3594 rc = XAllocColor (dpy, cmap, color);
3444 } 3595 }
3445 else 3596 else
3446 { 3597 {
3447 /* If allocation succeeded, and the allocated pixel color is not 3598 /* If allocation succeeded, and the allocated pixel color is not
3448 equal to a cached pixel color recorded earlier, there was a 3599 equal to a cached pixel color recorded earlier, there was a
3449 change in the colormap, so clear the color cache. */ 3600 change in the colormap, so clear the color cache. */
3450 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 3601 struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
3451 XColor *cached_color; 3602 XColor *cached_color;
3452 3603
3453 if (dpyinfo->color_cells 3604 if (dpyinfo->color_cells
3454 && (cached_color = &dpyinfo->color_cells[color->pixel], 3605 && (cached_color = &dpyinfo->color_cells[color->pixel],
3455 (cached_color->red != color->red 3606 (cached_color->red != color->red
3466 if (rc) 3617 if (rc)
3467 register_color (color->pixel); 3618 register_color (color->pixel);
3468 #endif /* DEBUG_X_COLORS */ 3619 #endif /* DEBUG_X_COLORS */
3469 3620
3470 return rc; 3621 return rc;
3622 }
3623
3624
3625 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an
3626 exact match can't be allocated, try the nearest color available.
3627 Value is non-zero if successful. Set *COLOR to the color
3628 allocated. */
3629
3630 int
3631 x_alloc_nearest_color (f, cmap, color)
3632 struct frame *f;
3633 Colormap cmap;
3634 XColor *color;
3635 {
3636 gamma_correct (f, color);
3637 return x_alloc_nearest_color_1 (FRAME_X_DISPLAY (f), cmap, color);
3471 } 3638 }
3472 3639
3473 3640
3474 /* Allocate color PIXEL on frame F. PIXEL must already be allocated. 3641 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3475 It's necessary to do this instead of just using PIXEL directly to 3642 It's necessary to do this instead of just using PIXEL directly to
14164 /* Try to use interrupt input; if we can't, then start polling. */ 14331 /* Try to use interrupt input; if we can't, then start polling. */
14165 Fset_input_mode (Qt, Qnil, Qt, Qnil); 14332 Fset_input_mode (Qt, Qnil, Qt, Qnil);
14166 14333
14167 #ifdef USE_X_TOOLKIT 14334 #ifdef USE_X_TOOLKIT
14168 XtToolkitInitialize (); 14335 XtToolkitInitialize ();
14336
14169 Xt_app_con = XtCreateApplicationContext (); 14337 Xt_app_con = XtCreateApplicationContext ();
14338
14339 /* Register a converter from strings to pixels, which uses
14340 Emacs' color allocation infrastructure. */
14341 XtAppSetTypeConverter (Xt_app_con,
14342 XtRString, XtRPixel, cvt_string_to_pixel,
14343 cvt_string_to_pixel_args,
14344 XtNumber (cvt_string_to_pixel_args),
14345 XtCacheByDisplay, cvt_pixel_dtor);
14346
14170 XtAppSetFallbackResources (Xt_app_con, Xt_default_resources); 14347 XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
14171 14348
14172 /* Install an asynchronous timer that processes Xt timeout events 14349 /* Install an asynchronous timer that processes Xt timeout events
14173 every 0.1s. This is necessary because some widget sets use 14350 every 0.1s. This is necessary because some widget sets use
14174 timeouts internally, for example the LessTif menu bar, or the 14351 timeouts internally, for example the LessTif menu bar, or the