Mercurial > emacs
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 |