Mercurial > hg > xemacs-beta
annotate src/redisplay-x.c @ 5043:d0c14ea98592
various frame-geometry fixes
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-15 Ben Wing <ben@xemacs.org>
* EmacsFrame.c:
* EmacsFrame.c (EmacsFrameResize):
* console-msw-impl.h:
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (FRAME_MSWINDOWS_TARGET_RECT):
* device-tty.c:
* device-tty.c (tty_asynch_device_change):
* event-msw.c:
* event-msw.c (mswindows_wnd_proc):
* faces.c (Fface_list):
* faces.h:
* frame-gtk.c:
* frame-gtk.c (gtk_set_initial_frame_size):
* frame-gtk.c (gtk_set_frame_size):
* frame-msw.c:
* frame-msw.c (mswindows_init_frame_1):
* frame-msw.c (mswindows_set_frame_size):
* frame-msw.c (mswindows_size_frame_internal):
* frame-msw.c (msprinter_init_frame_3):
* frame.c:
* frame.c (enum):
* frame.c (Fmake_frame):
* frame.c (adjust_frame_size):
* frame.c (store_minibuf_frame_prop):
* frame.c (Fframe_property):
* frame.c (Fframe_properties):
* frame.c (Fframe_displayable_pixel_height):
* frame.c (Fframe_displayable_pixel_width):
* frame.c (internal_set_frame_size):
* frame.c (Fset_frame_height):
* frame.c (Fset_frame_pixel_height):
* frame.c (Fset_frame_displayable_pixel_height):
* frame.c (Fset_frame_width):
* frame.c (Fset_frame_pixel_width):
* frame.c (Fset_frame_displayable_pixel_width):
* frame.c (Fset_frame_size):
* frame.c (Fset_frame_pixel_size):
* frame.c (Fset_frame_displayable_pixel_size):
* frame.c (frame_conversion_internal_1):
* frame.c (get_frame_displayable_pixel_size):
* frame.c (change_frame_size_1):
* frame.c (change_frame_size):
* frame.c (generate_title_string):
* frame.h:
* gtk-xemacs.c:
* gtk-xemacs.c (gtk_xemacs_size_request):
* gtk-xemacs.c (gtk_xemacs_size_allocate):
* gtk-xemacs.c (gtk_xemacs_paint):
* gutter.c:
* gutter.c (update_gutter_geometry):
* redisplay.c (end_hold_frame_size_changes):
* redisplay.c (redisplay_frame):
* toolbar.c:
* toolbar.c (update_frame_toolbars_geometry):
* window.c:
* window.c (frame_pixsize_valid_p):
* window.c (check_frame_size):
Various fixes to frame geometry to make it a bit easier to understand
and fix some bugs.
1. IMPORTANT: Some renamings. Will need to be applied carefully to
the carbon repository, in the following order:
-- pixel_to_char_size -> pixel_to_frame_unit_size
-- char_to_pixel_size -> frame_unit_to_pixel_size
-- pixel_to_real_char_size -> pixel_to_char_size
-- char_to_real_pixel_size -> char_to_pixel_size
-- Reverse second and third arguments of change_frame_size() and
change_frame_size_1() to try to make functions consistent in
putting width before height.
-- Eliminate old round_size_to_char, because it didn't really
do anything differently from round_size_to_real_char()
-- round_size_to_real_char -> round_size_to_char; any places that
called the old round_size_to_char should just call the new one.
2. IMPORTANT FOR CARBON: The set_frame_size() method is now passed
sizes in "frame units", like all other frame-sizing functions,
rather than some hacked-up combination of char-cell units and
total pixel size. This only affects window systems that use
"pixelated geometry", and I'm not sure if Carbon is one of them.
MS Windows is pixelated, X and GTK are not. For pixelated-geometry
systems, the size in set_frame_size() is in displayable pixels
rather than total pixels and needs to be converted appropriately;
take a look at the changes made to mswindows_set_frame_size()
method if necessary.
3. Add a big long comment in frame.c describing how frame geometry
works.
4. Remove MS Windows-specific character height and width fields,
duplicative and unused.
5. frame-displayable-pixel-* and set-frame-displayable-pixel-*
didn't use to work on MS Windows, but they do now.
6. In general, clean up the handling of "pixelated geometry" so
that fewer functions have to worry about this. This is really
an abomination that should be removed entirely but that will
have to happen later. Fix some buggy code in
frame_conversion_internal() that happened to "work" because it
was countered by oppositely buggy code in change_frame_size().
7. Clean up some frame-size code in toolbar.c and use functions
already provided in frame.c instead of rolling its own.
8. Fix check_frame_size() in window.c, which formerly didn't take
pixelated geometry into account.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 15 Feb 2010 22:14:11 -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 } |