Mercurial > hg > xemacs-beta
annotate src/redisplay-x.c @ 5090:0ca81354c4c7
Further frame-geometry cleanups
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-03 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Intro to Window and Frame Geometry):
* internals/internals.texi (The Paned Area):
* internals/internals.texi (The Displayable Area):
Update to make note of e.g. the fact that the bottom gutter is
actually above the minibuffer.
src/ChangeLog addition:
2010-03-03 Ben Wing <ben@xemacs.org>
* emacs.c:
* emacs.c (assert_equal_failed):
* lisp.h:
* lisp.h (assert_equal):
New fun assert_equal, asserting that two values == each other, and
printing out both values upon failure.
* frame-gtk.c (gtk_initialize_frame_size):
* frame-impl.h:
* frame-impl.h (FRAME_TOP_INTERNAL_BORDER_START):
* frame-impl.h (FRAME_BOTTOM_INTERNAL_BORDER_START):
* frame-impl.h (FRAME_LEFT_INTERNAL_BORDER_START):
* frame-impl.h (FRAME_PANED_TOP_EDGE):
* frame-impl.h (FRAME_NONPANED_SIZE):
* frame-x.c (x_initialize_frame_size):
* frame.c:
* gutter.c (get_gutter_coords):
* gutter.c (calculate_gutter_size):
* gutter.h:
* gutter.h (WINDOW_REAL_TOP_GUTTER_BOUNDS):
* gutter.h (FRAME_TOP_GUTTER_BOUNDS):
* input-method-xlib.c:
* input-method-xlib.c (XIM_SetGeometry):
* redisplay-output.c (clear_left_border):
* redisplay-output.c (clear_right_border):
* redisplay-output.c (redisplay_output_pixmap):
* redisplay-output.c (redisplay_clear_region):
* redisplay-output.c (redisplay_clear_top_of_window):
* redisplay-output.c (redisplay_clear_to_window_end):
* redisplay-xlike-inc.c (XLIKE_clear_frame):
* redisplay.c:
* redisplay.c (UPDATE_CACHE_RETURN):
* redisplay.c (pixel_to_glyph_translation):
* toolbar.c (update_frame_toolbars_geometry):
* window.c (Fwindow_pixel_edges):
Get rid of some redundant macros. Consistently use the
FRAME_TOP_*_START, FRAME_RIGHT_*_END, etc. format. Rename
FRAME_*_BORDER_* to FRAME_*_INTERNAL_BORDER_*. Comment out
FRAME_BOTTOM_* for gutters and the paned area due to the
uncertainty over where the paned area actually begins. (Eventually
we should probably move the gutters outside the minibuffer so that
the paned area is contiguous.) Use FRAME_PANED_* more often in the
code to make things clearer.
Update the diagram to show that the bottom gutter is inside the
minibuffer (!) and that there are "junk boxes" when you have left
and/or right gutters (dead boxes that are mistakenly left uncleared,
unlike the corresponding scrollbar dead boxes). Update the text
appropriately to cover the bottom gutter position, etc.
Rewrite gutter-geometry code to use the FRAME_*_GUTTER_* in place of
equivalent expressions referencing other frame elements, to make the
code more portable in case we move around the gutter location.
Cleanup FRAME_*_GUTTER_BOUNDS() in gutter.h.
Add some #### GEOM! comments where I think code is incorrect --
typically, it wasn't fixed up properly when the gutter was added.
Some cosmetic changes.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 03 Mar 2010 05:07:47 -0600 |
parents | b3ce27ca7647 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* X output and frame manipulation routines. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1994 Lucid, Inc. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
1318 | 5 Copyright (C) 2002, 2003 Ben Wing. |
428 | 6 |
7 This file is part of XEmacs. | |
8 | |
9 XEmacs is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 2, or (at your option) any | |
12 later version. | |
13 | |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with XEmacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 Boston, MA 02111-1307, USA. */ | |
23 | |
24 /* Synched up with: Not in FSF. */ | |
25 | |
26 /* Author: Chuck Thompson */ | |
27 | |
28 /* Lots of work done by Ben Wing for Mule */ | |
29 | |
30 | |
31 /* Number of pixels below each line. */ | |
3094 | 32 int x_interline_space; /* #### this needs to be implemented, but per-font */ |
428 | 33 |
4882
eab9498ecc0e
merge most of rest of redisplay-x.c and redisplay-gtk.c into redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4881
diff
changeset
|
34 #define THIS_IS_X |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
35 #include "redisplay-xlike-inc.c" |
3094 | 36 |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
37 static void x_output_shadows (struct frame *f, int x, int y, int width, |
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
38 int height, GC top_shadow_gc, |
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
39 GC bottom_shadow_gc, GC background_gc, |
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
40 int shadow_thickness, int edges); |
428 | 41 |
42 /***************************************************************************** | |
442 | 43 x_window_output_begin |
428 | 44 |
45 Perform any necessary initialization prior to an update. | |
46 ****************************************************************************/ | |
47 static void | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
48 XLIKE_window_output_begin (struct window *UNUSED (w)) |
428 | 49 { |
50 } | |
51 | |
52 /***************************************************************************** | |
442 | 53 x_window_output_end |
428 | 54 |
55 Perform any necessary flushing of queues when an update has completed. | |
56 ****************************************************************************/ | |
57 static void | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
58 XLIKE_window_output_end (struct window *w) |
428 | 59 { |
1204 | 60 if (!(check_if_pending_expose_event (WINDOW_XDEVICE (w)))) |
61 XFlush (DEVICE_X_DISPLAY (WINDOW_XDEVICE (w))); | |
428 | 62 } |
63 | |
64 /***************************************************************************** | |
65 x_bevel_area | |
66 | |
450 | 67 Draw shadows for the given area in the given face. |
428 | 68 ****************************************************************************/ |
69 static void | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
70 XLIKE_bevel_area (struct window *w, face_index findex, |
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
71 int x, int y, int width, int height, |
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
72 int shadow_thickness, int edges, enum edge_style style) |
428 | 73 { |
74 struct frame *f = XFRAME (w->frame); | |
75 struct device *d = XDEVICE (f->device); | |
76 | |
77 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | |
78 Display *dpy = DEVICE_X_DISPLAY (d); | |
79 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | |
80 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel; | |
81 Lisp_Object tmp_pixel; | |
82 XColor tmp_color; | |
83 XGCValues gcv; | |
84 GC top_shadow_gc, bottom_shadow_gc, background_gc; | |
85 | |
86 int use_pixmap = 0; | |
87 int flip_gcs = 0; | |
88 unsigned long mask; | |
89 | |
90 assert (shadow_thickness >=0); | |
91 memset (&gcv, ~0, sizeof (XGCValues)); | |
92 | |
93 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | |
94 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
95 | |
96 /* First, get the GC's. */ | |
97 top_shadow_pixel = tmp_color.pixel; | |
98 bottom_shadow_pixel = tmp_color.pixel; | |
99 background_pixel = tmp_color.pixel; | |
100 | |
101 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel, | |
102 background_pixel, ef->core.background_pixel); | |
103 | |
104 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); | |
105 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
106 gcv.background = tmp_color.pixel; | |
107 gcv.graphics_exposures = False; | |
108 mask = GCForeground | GCBackground | GCGraphicsExposures; | |
109 | |
110 /* If we can't distinguish one of the shadows (the color is the same as the | |
111 background), it's better to use a pixmap to generate a dithered gray. */ | |
112 if (top_shadow_pixel == background_pixel || | |
113 bottom_shadow_pixel == background_pixel) | |
114 use_pixmap = 1; | |
115 | |
116 if (use_pixmap) | |
117 { | |
118 if (DEVICE_X_GRAY_PIXMAP (d) == None) | |
119 { | |
120 DEVICE_X_GRAY_PIXMAP (d) = | |
121 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits, | |
122 gray_width, gray_height, 1, 0, 1); | |
123 } | |
124 | |
125 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | |
126 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
127 gcv.foreground = tmp_color.pixel; | |
128 /* this is needed because the GC draws with a pixmap here */ | |
129 gcv.fill_style = FillOpaqueStippled; | |
130 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d); | |
131 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, | |
132 (mask | GCStipple | GCFillStyle)); | |
133 | |
134 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); | |
135 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | |
136 bottom_shadow_pixel = tmp_color.pixel; | |
137 | |
138 flip_gcs = (bottom_shadow_pixel == | |
139 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy))); | |
140 } | |
141 else | |
142 { | |
143 gcv.foreground = top_shadow_pixel; | |
144 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | |
145 } | |
146 | |
147 gcv.foreground = bottom_shadow_pixel; | |
148 bottom_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | |
149 | |
150 if (use_pixmap && flip_gcs) | |
151 { | |
152 GC tmp_gc = bottom_shadow_gc; | |
153 bottom_shadow_gc = top_shadow_gc; | |
154 top_shadow_gc = tmp_gc; | |
155 } | |
156 | |
157 gcv.foreground = background_pixel; | |
158 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | |
159 | |
160 /* possibly revert the GC's This will give a depressed look to the | |
161 divider */ | |
162 if (style == EDGE_ETCHED_IN || style == EDGE_BEVEL_IN) | |
163 { | |
164 GC temp; | |
165 | |
166 temp = top_shadow_gc; | |
167 top_shadow_gc = bottom_shadow_gc; | |
168 bottom_shadow_gc = temp; | |
169 } | |
170 | |
171 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) | |
172 shadow_thickness /= 2; | |
173 | |
174 /* Draw the shadows around the divider line */ | |
175 x_output_shadows (f, x, y, width, height, | |
176 top_shadow_gc, bottom_shadow_gc, | |
177 background_gc, shadow_thickness, edges); | |
178 | |
179 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) | |
180 { | |
181 /* Draw the shadows around the divider line */ | |
182 x_output_shadows (f, x + shadow_thickness, y + shadow_thickness, | |
183 width - 2*shadow_thickness, height - 2*shadow_thickness, | |
184 bottom_shadow_gc, top_shadow_gc, | |
185 background_gc, shadow_thickness, edges); | |
186 } | |
187 } | |
188 | |
189 /***************************************************************************** | |
190 x_output_shadows | |
191 | |
192 Draw a shadow around the given area using the given GC's. It is the | |
193 callers responsibility to set the GC's appropriately. | |
194 ****************************************************************************/ | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
195 static void |
428 | 196 x_output_shadows (struct frame *f, int x, int y, int width, int height, |
2286 | 197 GC top_shadow_gc, GC bottom_shadow_gc, |
198 GC UNUSED (background_gc), int shadow_thickness, int edges) | |
428 | 199 { |
200 struct device *d = XDEVICE (f->device); | |
201 | |
202 Display *dpy = DEVICE_X_DISPLAY (d); | |
203 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | |
204 | |
205 XSegment top_shadow[20], bottom_shadow[20]; | |
206 int elt; | |
207 | |
208 if (shadow_thickness > 10) | |
209 shadow_thickness = 10; | |
210 else if (shadow_thickness < 0) | |
211 shadow_thickness = 0; | |
212 if (shadow_thickness > (width / 2)) | |
213 shadow_thickness = width / 2; | |
214 if (shadow_thickness > (height / 2)) | |
215 shadow_thickness = height / 2; | |
216 | |
217 for (elt = 0; elt < shadow_thickness; elt++) | |
218 { | |
219 int seg1 = elt; | |
220 int seg2 = (edges & EDGE_TOP) ? elt + shadow_thickness : elt; | |
221 int bot_seg2 = (edges & EDGE_BOTTOM) ? elt + shadow_thickness : elt; | |
222 | |
223 if (edges & EDGE_TOP) | |
224 { | |
225 top_shadow[seg1].x1 = x + elt; | |
226 top_shadow[seg1].x2 = x + width - elt - 1; | |
227 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; | |
228 } | |
229 if (edges & EDGE_LEFT) | |
230 { | |
231 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; | |
232 top_shadow[seg2].y1 = y + elt; | |
233 top_shadow[seg2].y2 = y + height - elt - 1; | |
234 } | |
235 if (edges & EDGE_BOTTOM) | |
236 { | |
237 bottom_shadow[seg1].x1 = x + elt; | |
238 bottom_shadow[seg1].x2 = x + width - elt - 1; | |
239 bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; | |
240 } | |
241 if (edges & EDGE_RIGHT) | |
242 { | |
243 bottom_shadow[bot_seg2].x1 = bottom_shadow[bot_seg2].x2 = x + width - elt - 1; | |
244 bottom_shadow[bot_seg2].y1 = y + elt; | |
245 bottom_shadow[bot_seg2].y2 = y + height - elt - 1; | |
246 } | |
247 } | |
248 | |
249 XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, | |
250 ((edges & EDGE_TOP) ? shadow_thickness : 0) | |
251 + ((edges & EDGE_LEFT) ? shadow_thickness : 0)); | |
252 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, | |
253 ((edges & EDGE_BOTTOM) ? shadow_thickness : 0) | |
254 + ((edges & EDGE_RIGHT) ? shadow_thickness : 0)); | |
255 } | |
256 | |
257 /***************************************************************************** | |
258 x_generate_shadow_pixels | |
259 | |
260 Given three pixels (top shadow, bottom shadow, background) massage | |
261 the top and bottom shadow colors to guarantee that they differ. The | |
262 background pixels are not allowed to be modified. | |
263 | |
264 This function modifies its parameters. | |
265 | |
266 This code is modified from code blatantly stolen from lwlib/xlwmenu.c | |
267 ****************************************************************************/ | |
268 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ | |
269 ? ((unsigned long) (x)) : ((unsigned long) (y))) | |
270 | |
271 void | |
272 x_generate_shadow_pixels (struct frame *f, unsigned long *top_shadow, | |
273 unsigned long *bottom_shadow, | |
274 unsigned long background, | |
275 unsigned long core_background) | |
276 { | |
277 struct device *d = XDEVICE (f->device); | |
278 Display *dpy = DEVICE_X_DISPLAY (d); | |
279 Colormap cmap = DEVICE_X_COLORMAP (d); | |
280 Visual *visual = DEVICE_X_VISUAL (d); | |
281 | |
282 XColor topc, botc; | |
283 int top_frobbed = 0, bottom_frobbed = 0; | |
284 | |
285 /* If the top shadow is the same color as the background, try to | |
286 adjust it. */ | |
287 if (*top_shadow == background) | |
288 { | |
289 topc.pixel = background; | |
290 XQueryColor (dpy, cmap, &topc); | |
291 /* don't overflow/wrap! */ | |
292 topc.red = MINL (65535, (unsigned long) topc.red * 6 / 5); | |
293 topc.green = MINL (65535, (unsigned long) topc.green * 6 / 5); | |
294 topc.blue = MINL (65535, (unsigned long) topc.blue * 6 / 5); | |
3094 | 295 if (x_allocate_nearest_color (dpy, cmap, visual, &topc)) |
428 | 296 { |
297 *top_shadow = topc.pixel; | |
298 top_frobbed = 1; | |
299 } | |
300 } | |
301 | |
302 /* If the bottom shadow is the same color as the background, try to | |
303 adjust it. */ | |
304 if (*bottom_shadow == background) | |
305 { | |
306 botc.pixel = background; | |
307 XQueryColor (dpy, cmap, &botc); | |
308 botc.red = (unsigned short) ((unsigned long) botc.red * 3 / 5); | |
309 botc.green = (unsigned short) ((unsigned long) botc.green * 3 / 5); | |
310 botc.blue = (unsigned short) ((unsigned long) botc.blue * 3 / 5); | |
3094 | 311 if (x_allocate_nearest_color (dpy, cmap, visual, &botc)) |
428 | 312 { |
313 *bottom_shadow = botc.pixel; | |
314 bottom_frobbed = 1; | |
315 } | |
316 } | |
317 | |
318 /* If we had to adjust both shadows, then we have to do some | |
319 additional work. */ | |
320 if (top_frobbed && bottom_frobbed) | |
321 { | |
322 int top_avg = ((topc.red / 3) + (topc.green / 3) + (topc.blue / 3)); | |
323 int bot_avg = ((botc.red / 3) + (botc.green / 3) + (botc.blue / 3)); | |
324 if (bot_avg > top_avg) | |
325 { | |
326 Pixel tmp = *top_shadow; | |
327 | |
328 *top_shadow = *bottom_shadow; | |
329 *bottom_shadow = tmp; | |
330 } | |
331 else if (topc.pixel == botc.pixel) | |
332 { | |
333 if (botc.pixel == background) | |
334 *top_shadow = core_background; | |
335 else | |
336 *bottom_shadow = background; | |
337 } | |
338 } | |
339 } | |
340 | |
341 | |
342 /* Make audible bell. */ | |
343 | |
344 static void | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4882
diff
changeset
|
345 XLIKE_ring_bell (struct device *d, int volume, int pitch, int duration) |
428 | 346 { |
347 Display *display = DEVICE_X_DISPLAY (d); | |
348 | |
349 if (volume < 0) volume = 0; | |
350 else if (volume > 100) volume = 100; | |
351 if (pitch < 0 && duration < 0) | |
352 { | |
353 XBell (display, (volume * 2) - 100); | |
354 XFlush (display); | |
355 } | |
356 else | |
357 { | |
358 XKeyboardState state; | |
359 XKeyboardControl ctl; | |
360 XSync (display, 0); | |
361 /* #### grab server? */ | |
362 XGetKeyboardControl (display, &state); | |
363 | |
664 | 364 ctl.bell_pitch = (pitch >= 0 ? pitch : (int) state.bell_pitch); |
365 ctl.bell_duration = (duration >= 0 ? duration : (int) state.bell_duration); | |
428 | 366 XChangeKeyboardControl (display, KBBellPitch|KBBellDuration, &ctl); |
367 | |
368 XBell (display, (volume * 2) - 100); | |
369 | |
370 ctl.bell_pitch = state.bell_pitch; | |
371 ctl.bell_duration = state.bell_duration; | |
372 XChangeKeyboardControl (display, KBBellPitch|KBBellDuration, &ctl); | |
373 | |
374 /* #### ungrab server? */ | |
375 XSync (display, 0); | |
376 } | |
377 } |