aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-03-07 21:08:07 +0800
committerPo Lu2022-03-07 21:10:53 +0800
commit8a7df412a640c8b2334b78ec0ca872a6d11e8b0e (patch)
treeb8e0f6d4bc8ddf9bcc82178e67d6f3fafb12484c /src
parent4b0e1c6502534298465675a32ff65653c12df17d (diff)
downloademacs-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.c18
-rw-r--r--src/xterm.c43
-rw-r--r--src/xterm.h6
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)
9019int 9021int
9020XDisplayCells (Display *dpy, int screen_number) 9022XDisplayCells (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)