diff options
| author | Po Lu | 2022-03-07 21:08:07 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-07 21:10:53 +0800 |
| commit | 8a7df412a640c8b2334b78ec0ca872a6d11e8b0e (patch) | |
| tree | b8e0f6d4bc8ddf9bcc82178e67d6f3fafb12484c /src | |
| parent | 4b0e1c6502534298465675a32ff65653c12df17d (diff) | |
| download | emacs-8a7df412a640c8b2334b78ec0ca872a6d11e8b0e.tar.gz emacs-8a7df412a640c8b2334b78ec0ca872a6d11e8b0e.zip | |
Improve color handling on colormapped displays
* src/xfns.c (select_visual): Set `visual_info' field whenever
appropriate.
(x_create_tip_frame, XDisplayCells): Don't access private fields
of Visual.
* src/xterm.c (x_color_cells, x_alloc_nearest_color_1): Use
colormap_size instead of default cell count.
(XTflash, x_bitmap_icon, x_term_init):
* src/xterm.h (struct x_display_info, FRAME_X_VISUAL_INFO): Stop
accessing private fields of Visual.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 18 | ||||
| -rw-r--r-- | src/xterm.c | 43 | ||||
| -rw-r--r-- | src/xterm.h | 6 |
3 files changed, 44 insertions, 23 deletions
diff --git a/src/xfns.c b/src/xfns.c index e288f797fbd..3d1fa926096 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -6605,6 +6605,7 @@ select_visual (struct x_display_info *dpyinfo) | |||
| 6605 | SSDATA (ENCODE_SYSTEM (value))); | 6605 | SSDATA (ENCODE_SYSTEM (value))); |
| 6606 | 6606 | ||
| 6607 | dpyinfo->visual = vinfo.visual; | 6607 | dpyinfo->visual = vinfo.visual; |
| 6608 | dpyinfo->visual_info = vinfo; | ||
| 6608 | } | 6609 | } |
| 6609 | else | 6610 | else |
| 6610 | { | 6611 | { |
| @@ -6638,6 +6639,7 @@ select_visual (struct x_display_info *dpyinfo) | |||
| 6638 | { | 6639 | { |
| 6639 | dpyinfo->n_planes = vinfo[i].depth; | 6640 | dpyinfo->n_planes = vinfo[i].depth; |
| 6640 | dpyinfo->visual = vinfo[i].visual; | 6641 | dpyinfo->visual = vinfo[i].visual; |
| 6642 | dpyinfo->visual_info = vinfo[i]; | ||
| 6641 | dpyinfo->pict_format = format; | 6643 | dpyinfo->pict_format = format; |
| 6642 | 6644 | ||
| 6643 | XFree (vinfo); | 6645 | XFree (vinfo); |
| @@ -6658,7 +6660,7 @@ select_visual (struct x_display_info *dpyinfo) | |||
| 6658 | &vinfo_template, &n_visuals); | 6660 | &vinfo_template, &n_visuals); |
| 6659 | if (n_visuals <= 0) | 6661 | if (n_visuals <= 0) |
| 6660 | fatal ("Can't get proper X visual info"); | 6662 | fatal ("Can't get proper X visual info"); |
| 6661 | 6663 | dpyinfo->visual_info = *vinfo; | |
| 6662 | dpyinfo->n_planes = vinfo->depth; | 6664 | dpyinfo->n_planes = vinfo->depth; |
| 6663 | XFree (vinfo); | 6665 | XFree (vinfo); |
| 6664 | } | 6666 | } |
| @@ -7540,8 +7542,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) | |||
| 7540 | 7542 | ||
| 7541 | if (FRAME_DISPLAY_INFO (f)->n_planes == 1) | 7543 | if (FRAME_DISPLAY_INFO (f)->n_planes == 1) |
| 7542 | disptype = Qmono; | 7544 | disptype = Qmono; |
| 7543 | else if (FRAME_DISPLAY_INFO (f)->visual->class == GrayScale | 7545 | else if (FRAME_X_VISUAL_INFO (f)->class == GrayScale |
| 7544 | || FRAME_DISPLAY_INFO (f)->visual->class == StaticGray) | 7546 | || FRAME_X_VISUAL_INFO (f)->class == StaticGray) |
| 7545 | disptype = intern ("grayscale"); | 7547 | disptype = intern ("grayscale"); |
| 7546 | else | 7548 | else |
| 7547 | disptype = intern ("color"); | 7549 | disptype = intern ("color"); |
| @@ -9019,7 +9021,15 @@ XkbFreeNames (XkbDescPtr xkb, unsigned int which, Bool free_map) | |||
| 9019 | int | 9021 | int |
| 9020 | XDisplayCells (Display *dpy, int screen_number) | 9022 | XDisplayCells (Display *dpy, int screen_number) |
| 9021 | { | 9023 | { |
| 9022 | return 1677216; | 9024 | struct x_display_info *dpyinfo = x_display_info_for_display (dpy); |
| 9025 | |||
| 9026 | if (!dpyinfo) | ||
| 9027 | emacs_abort (); | ||
| 9028 | |||
| 9029 | /* Not strictly correct, since the display could be using a | ||
| 9030 | non-default visual, but it satisfies the callers we need to care | ||
| 9031 | about. */ | ||
| 9032 | return dpyinfo->visual_info.colormap_size; | ||
| 9023 | } | 9033 | } |
| 9024 | #endif | 9034 | #endif |
| 9025 | 9035 | ||
diff --git a/src/xterm.c b/src/xterm.c index 30229c45a47..6682d3c9a46 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -3641,8 +3641,7 @@ x_color_cells (Display *dpy, int *ncells) | |||
| 3641 | 3641 | ||
| 3642 | if (dpyinfo->color_cells == NULL) | 3642 | if (dpyinfo->color_cells == NULL) |
| 3643 | { | 3643 | { |
| 3644 | Screen *screen = dpyinfo->screen; | 3644 | int ncolor_cells = dpyinfo->visual_info.colormap_size; |
| 3645 | int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); | ||
| 3646 | int i; | 3645 | int i; |
| 3647 | 3646 | ||
| 3648 | dpyinfo->color_cells = xnmalloc (ncolor_cells, | 3647 | dpyinfo->color_cells = xnmalloc (ncolor_cells, |
| @@ -3841,7 +3840,7 @@ x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color) | |||
| 3841 | eassume (dpyinfo); | 3840 | eassume (dpyinfo); |
| 3842 | rc = XAllocColor (dpy, cmap, color) != 0; | 3841 | rc = XAllocColor (dpy, cmap, color) != 0; |
| 3843 | 3842 | ||
| 3844 | if (dpyinfo->visual->class == DirectColor) | 3843 | if (dpyinfo->visual_info.class == DirectColor) |
| 3845 | return rc; | 3844 | return rc; |
| 3846 | 3845 | ||
| 3847 | if (rc == 0) | 3846 | if (rc == 0) |
| @@ -3900,7 +3899,7 @@ x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color) | |||
| 3900 | retry = true; | 3899 | retry = true; |
| 3901 | xfree (dpyinfo->color_cells); | 3900 | xfree (dpyinfo->color_cells); |
| 3902 | 3901 | ||
| 3903 | ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (dpyinfo->screen)); | 3902 | ncolor_cells = dpyinfo->visual_info.colormap_size; |
| 3904 | 3903 | ||
| 3905 | dpyinfo->color_cells = xnmalloc (ncolor_cells, | 3904 | dpyinfo->color_cells = xnmalloc (ncolor_cells, |
| 3906 | sizeof *dpyinfo->color_cells); | 3905 | sizeof *dpyinfo->color_cells); |
| @@ -5735,7 +5734,7 @@ XTflash (struct frame *f) | |||
| 5735 | 5734 | ||
| 5736 | block_input (); | 5735 | block_input (); |
| 5737 | 5736 | ||
| 5738 | if (FRAME_X_VISUAL (f)->class == TrueColor) | 5737 | if (FRAME_X_VISUAL_INFO (f)->class == TrueColor) |
| 5739 | { | 5738 | { |
| 5740 | values.function = GXxor; | 5739 | values.function = GXxor; |
| 5741 | values.foreground = (FRAME_FOREGROUND_PIXEL (f) | 5740 | values.foreground = (FRAME_FOREGROUND_PIXEL (f) |
| @@ -5821,7 +5820,7 @@ XTflash (struct frame *f) | |||
| 5821 | flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), | 5820 | flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), |
| 5822 | width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); | 5821 | width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); |
| 5823 | 5822 | ||
| 5824 | if (FRAME_X_VISUAL (f)->class == TrueColor) | 5823 | if (FRAME_X_VISUAL_INFO (f)->class == TrueColor) |
| 5825 | XFreeGC (FRAME_X_DISPLAY (f), gc); | 5824 | XFreeGC (FRAME_X_DISPLAY (f), gc); |
| 5826 | x_flush (f); | 5825 | x_flush (f); |
| 5827 | 5826 | ||
| @@ -13986,11 +13985,17 @@ x_bitmap_icon (struct frame *f, Lisp_Object file) | |||
| 13986 | } | 13985 | } |
| 13987 | 13986 | ||
| 13988 | #elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) | 13987 | #elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) |
| 13989 | 13988 | /* This allocates too many colors. */ | |
| 13990 | rc = x_create_bitmap_from_xpm_data (f, gnu_xpm_bits); | 13989 | if (FRAME_X_VISUAL_INFO (f)->class == TrueColor |
| 13991 | if (rc != -1) | 13990 | /* That pixmap needs about 240 colors, and we should |
| 13992 | FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc; | 13991 | also leave some more space for other colors as |
| 13993 | 13992 | well. */ | |
| 13993 | || FRAME_X_VISUAL_INFO (f)->colormap_size >= (240 * 4)) | ||
| 13994 | { | ||
| 13995 | rc = x_create_bitmap_from_xpm_data (f, gnu_xpm_bits); | ||
| 13996 | if (rc != -1) | ||
| 13997 | FRAME_DISPLAY_INFO (f)->icon_bitmap_id = rc; | ||
| 13998 | } | ||
| 13994 | #endif | 13999 | #endif |
| 13995 | 14000 | ||
| 13996 | /* If all else fails, use the (black and white) xbm image. */ | 14001 | /* If all else fails, use the (black and white) xbm image. */ |
| @@ -17306,7 +17311,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 17306 | /* See if a private colormap is requested. */ | 17311 | /* See if a private colormap is requested. */ |
| 17307 | if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen)) | 17312 | if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen)) |
| 17308 | { | 17313 | { |
| 17309 | if (dpyinfo->visual->class == PseudoColor) | 17314 | if (dpyinfo->visual_info.class == PseudoColor) |
| 17310 | { | 17315 | { |
| 17311 | AUTO_STRING (privateColormap, "privateColormap"); | 17316 | AUTO_STRING (privateColormap, "privateColormap"); |
| 17312 | AUTO_STRING (PrivateColormap, "PrivateColormap"); | 17317 | AUTO_STRING (PrivateColormap, "PrivateColormap"); |
| @@ -17324,13 +17329,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 17324 | dpyinfo->visual, AllocNone); | 17329 | dpyinfo->visual, AllocNone); |
| 17325 | 17330 | ||
| 17326 | /* See if we can construct pixel values from RGB values. */ | 17331 | /* See if we can construct pixel values from RGB values. */ |
| 17327 | if (dpyinfo->visual->class == TrueColor) | 17332 | if (dpyinfo->visual_info.class == TrueColor) |
| 17328 | { | 17333 | { |
| 17329 | get_bits_and_offset (dpyinfo->visual->red_mask, | 17334 | get_bits_and_offset (dpyinfo->visual_info.red_mask, |
| 17330 | &dpyinfo->red_bits, &dpyinfo->red_offset); | 17335 | &dpyinfo->red_bits, &dpyinfo->red_offset); |
| 17331 | get_bits_and_offset (dpyinfo->visual->blue_mask, | 17336 | get_bits_and_offset (dpyinfo->visual_info.blue_mask, |
| 17332 | &dpyinfo->blue_bits, &dpyinfo->blue_offset); | 17337 | &dpyinfo->blue_bits, &dpyinfo->blue_offset); |
| 17333 | get_bits_and_offset (dpyinfo->visual->green_mask, | 17338 | get_bits_and_offset (dpyinfo->visual_info.green_mask, |
| 17334 | &dpyinfo->green_bits, &dpyinfo->green_offset); | 17339 | &dpyinfo->green_bits, &dpyinfo->green_offset); |
| 17335 | 17340 | ||
| 17336 | #ifdef HAVE_XRENDER | 17341 | #ifdef HAVE_XRENDER |
| @@ -17357,9 +17362,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 17357 | if (XAllocColor (dpyinfo->display, | 17362 | if (XAllocColor (dpyinfo->display, |
| 17358 | dpyinfo->cmap, &xc) != 0) | 17363 | dpyinfo->cmap, &xc) != 0) |
| 17359 | { | 17364 | { |
| 17360 | alpha_mask = xc.pixel & ~(dpyinfo->visual->red_mask | 17365 | alpha_mask = xc.pixel & ~(dpyinfo->visual_info.red_mask |
| 17361 | | dpyinfo->visual->blue_mask | 17366 | | dpyinfo->visual_info.blue_mask |
| 17362 | | dpyinfo->visual->green_mask); | 17367 | | dpyinfo->visual_info.green_mask); |
| 17363 | 17368 | ||
| 17364 | if (alpha_mask) | 17369 | if (alpha_mask) |
| 17365 | get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits, | 17370 | get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits, |
diff --git a/src/xterm.h b/src/xterm.h index dd510ae2576..846df03277c 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -283,6 +283,9 @@ struct x_display_info | |||
| 283 | /* The Visual being used for this display. */ | 283 | /* The Visual being used for this display. */ |
| 284 | Visual *visual; | 284 | Visual *visual; |
| 285 | 285 | ||
| 286 | /* The visual information corresponding to VISUAL. */ | ||
| 287 | XVisualInfo visual_info; | ||
| 288 | |||
| 286 | #ifdef HAVE_XRENDER | 289 | #ifdef HAVE_XRENDER |
| 287 | /* The picture format for this display. */ | 290 | /* The picture format for this display. */ |
| 288 | XRenderPictFormat *pict_format; | 291 | XRenderPictFormat *pict_format; |
| @@ -1031,6 +1034,9 @@ extern void x_mark_frame_dirty (struct frame *f); | |||
| 1031 | /* This is the Visual which frame F is on. */ | 1034 | /* This is the Visual which frame F is on. */ |
| 1032 | #define FRAME_X_VISUAL(f) FRAME_DISPLAY_INFO (f)->visual | 1035 | #define FRAME_X_VISUAL(f) FRAME_DISPLAY_INFO (f)->visual |
| 1033 | 1036 | ||
| 1037 | /* And its corresponding visual info. */ | ||
| 1038 | #define FRAME_X_VISUAL_INFO(f) (&FRAME_DISPLAY_INFO (f)->visual_info) | ||
| 1039 | |||
| 1034 | #ifdef HAVE_XRENDER | 1040 | #ifdef HAVE_XRENDER |
| 1035 | #define FRAME_X_PICTURE_FORMAT(f) FRAME_DISPLAY_INFO (f)->pict_format | 1041 | #define FRAME_X_PICTURE_FORMAT(f) FRAME_DISPLAY_INFO (f)->pict_format |
| 1036 | #define FRAME_X_PICTURE(f) ((f)->output_data.x->picture) | 1042 | #define FRAME_X_PICTURE(f) ((f)->output_data.x->picture) |