This source file includes following definitions.
- emacsFrameClass
- get_default_char_pixel_size
- pixel_to_char_size
- char_to_pixel_size
- round_size_to_char
- get_wm_shell
- mark_shell_size_user_specified
- set_frame_size
- update_wm_hints
- widget_update_wm_size_hints
- update_various_frame_slots
- update_from_various_frame_slots
- EmacsFrameInitialize
- resize_cb
- EmacsFrameRealize
- EmacsFrameDestroy
- EmacsFrameResize
- EmacsFrameQueryGeometry
- EmacsFrameSetCharSize
- EmacsFrameExpose
- widget_store_internal_border
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <config.h>
27 #include "widget.h"
28
29 #include <stdlib.h>
30
31 #include "lisp.h"
32 #include "sysstdio.h"
33 #include "xterm.h"
34 #include "frame.h"
35
36 #include <X11/StringDefs.h>
37 #include <X11/IntrinsicP.h>
38 #include <X11/cursorfont.h>
39 #include "widgetprv.h"
40 #include <X11/ObjectP.h>
41 #include <X11/Shell.h>
42 #include <X11/ShellP.h>
43 #include "../lwlib/lwlib.h"
44
45 static void EmacsFrameInitialize (Widget, Widget, ArgList, Cardinal *);
46 static void EmacsFrameDestroy (Widget);
47 static void EmacsFrameRealize (Widget, XtValueMask *, XSetWindowAttributes *);
48 static void EmacsFrameResize (Widget);
49 static void EmacsFrameExpose (Widget, XEvent *, Region);
50 static XtGeometryResult EmacsFrameQueryGeometry (Widget, XtWidgetGeometry *,
51 XtWidgetGeometry *);
52
53
54 #define offset(field) offsetof (EmacsFrameRec, emacs_frame.field)
55
56 static XtResource resources[] = {
57 {(char *) XtNgeometry, (char *) XtCGeometry, XtRString, sizeof (String),
58 offset (geometry), XtRString, (XtPointer) 0},
59 {XtNiconic, XtCIconic, XtRBoolean, sizeof (Boolean),
60 offset (iconic), XtRImmediate, (XtPointer) False},
61
62 {(char *) XtNemacsFrame, (char *) XtCEmacsFrame,
63 XtRPointer, sizeof (XtPointer),
64 offset (frame), XtRImmediate, 0},
65
66 {(char *) XtNminibuffer, (char *) XtCMinibuffer, XtRInt, sizeof (int),
67 offset (minibuffer), XtRImmediate, (XtPointer)0},
68 {(char *) XtNunsplittable, (char *) XtCUnsplittable,
69 XtRBoolean, sizeof (Boolean),
70 offset (unsplittable), XtRImmediate, (XtPointer)0},
71 {(char *) XtNinternalBorderWidth, (char *) XtCInternalBorderWidth,
72 XtRInt, sizeof (int),
73 offset (internal_border_width), XtRImmediate, (XtPointer)4},
74 {(char *) XtNinterline, (char *) XtCInterline, XtRInt, sizeof (int),
75 offset (interline), XtRImmediate, (XtPointer)0},
76 {(char *) XtNforeground, (char *) XtCForeground, XtRPixel, sizeof (Pixel),
77 offset (foreground_pixel), XtRString, (char *) "XtDefaultForeground"},
78 {(char *) XtNcursorColor, (char *) XtCForeground, XtRPixel, sizeof (Pixel),
79 offset (cursor_color), XtRString, (char *) "XtDefaultForeground"},
80 {(char *) XtNbarCursor, (char *) XtCBarCursor, XtRBoolean, sizeof (Boolean),
81 offset (bar_cursor), XtRImmediate, (XtPointer)0},
82 {(char *) XtNvisualBell, (char *) XtCVisualBell, XtRBoolean, sizeof (Boolean),
83 offset (visual_bell), XtRImmediate, (XtPointer)0},
84 {(char *) XtNbellVolume, (char *) XtCBellVolume, XtRInt, sizeof (int),
85 offset (bell_volume), XtRImmediate, (XtPointer)0},
86 };
87
88 #undef offset
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 static EmacsFrameClassRec emacsFrameClassRec = {
107 {
108 0,
109 (char *) "EmacsFrame",
110 sizeof (EmacsFrameRec),
111 0,
112 0,
113 FALSE,
114 EmacsFrameInitialize,
115 0,
116 EmacsFrameRealize,
117 0,
118 0,
119 resources,
120 XtNumber (resources),
121 NULLQUARK,
122 TRUE,
123 XtExposeNoCompress,
124 TRUE,
125 FALSE,
126 EmacsFrameDestroy,
127 EmacsFrameResize,
128 EmacsFrameExpose,
129
130
131
132 0,
133 0,
134 XtInheritSetValuesAlmost,
135 0,
136 XtInheritAcceptFocus,
137 XtVersion,
138 0,
139 0,
140 EmacsFrameQueryGeometry,
141 XtInheritDisplayAccelerator,
142 0
143 }
144 };
145
146 WidgetClass
147 emacsFrameClass (void)
148 {
149
150
151
152 emacsFrameClassRec.core_class.superclass = &widgetClassRec;
153
154 return (WidgetClass) &emacsFrameClassRec;
155 }
156
157 static void
158 get_default_char_pixel_size (EmacsFrame ew, int *pixel_width, int *pixel_height)
159 {
160 struct frame *f = ew->emacs_frame.frame;
161
162 *pixel_width = FRAME_COLUMN_WIDTH (f);
163 *pixel_height = FRAME_LINE_HEIGHT (f);
164 }
165
166 static void
167 pixel_to_char_size (EmacsFrame ew, Dimension pixel_width,
168 Dimension pixel_height, int *char_width, int *char_height)
169 {
170 struct frame *f = ew->emacs_frame.frame;
171
172 *char_width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, (int) pixel_width);
173 *char_height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (int) pixel_height);
174 }
175
176 static void
177 char_to_pixel_size (EmacsFrame ew, int char_width, int char_height,
178 Dimension *pixel_width, Dimension *pixel_height)
179 {
180 struct frame *f = ew->emacs_frame.frame;
181
182 *pixel_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, char_width);
183 *pixel_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, char_height);
184 }
185
186 static void
187 round_size_to_char (EmacsFrame ew, Dimension in_width, Dimension in_height,
188 Dimension *out_width, Dimension *out_height)
189 {
190 int char_width;
191 int char_height;
192 pixel_to_char_size (ew, in_width, in_height,
193 &char_width, &char_height);
194 char_to_pixel_size (ew, char_width, char_height,
195 out_width, out_height);
196 }
197
198 static WMShellWidget
199 get_wm_shell (Widget w)
200 {
201 Widget wmshell;
202
203 for (wmshell = XtParent (w);
204 wmshell && !XtIsWMShell (wmshell);
205 wmshell = XtParent (wmshell));
206
207 return (WMShellWidget) wmshell;
208 }
209
210 #if 0
211
212 static void
213 mark_shell_size_user_specified (Widget wmshell)
214 {
215 if (! XtIsWMShell (wmshell)) emacs_abort ();
216
217
218 ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;
219 }
220
221 #endif
222
223
224 static void
225 set_frame_size (EmacsFrame ew)
226 {
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 struct frame *f = ew->emacs_frame.frame;
263
264 ew->core.width = FRAME_PIXEL_WIDTH (f);
265 ew->core.height = FRAME_PIXEL_HEIGHT (f);
266
267 if (CONSP (frame_size_history))
268 frame_size_history_plain
269 (f, build_string ("set_frame_size"));
270 }
271
272 static bool
273 update_wm_hints (WMShellWidget wmshell, EmacsFrame ew)
274 {
275 int cw;
276 int ch;
277 Dimension rounded_width;
278 Dimension rounded_height;
279 int char_width;
280 int char_height;
281 int base_width;
282 int base_height;
283 char buffer[sizeof wmshell->wm.size_hints];
284 char *hints_ptr;
285
286
287 memcpy (buffer, &wmshell->wm.size_hints,
288 sizeof wmshell->wm.size_hints);
289
290 pixel_to_char_size (ew, ew->core.width, ew->core.height,
291 &char_width, &char_height);
292 char_to_pixel_size (ew, char_width, char_height,
293 &rounded_width, &rounded_height);
294 get_default_char_pixel_size (ew, &cw, &ch);
295
296 base_width = (wmshell->core.width - ew->core.width
297 + (rounded_width - (char_width * cw)));
298 base_height = (wmshell->core.height - ew->core.height
299 + (rounded_height - (char_height * ch)));
300
301 XtVaSetValues ((Widget) wmshell,
302 XtNbaseWidth, (XtArgVal) base_width,
303 XtNbaseHeight, (XtArgVal) base_height,
304 XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw),
305 XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch),
306 XtNminWidth, (XtArgVal) base_width,
307 XtNminHeight, (XtArgVal) base_height,
308 NULL);
309
310
311
312
313 hints_ptr = (char *) &wmshell->wm.size_hints;
314
315
316 return memcmp (hints_ptr + sizeof (long), buffer + sizeof (long),
317 sizeof wmshell->wm.wm_hints - sizeof (long));
318 }
319
320 bool
321 widget_update_wm_size_hints (Widget widget, Widget frame)
322 {
323 return update_wm_hints ((WMShellWidget) widget, (EmacsFrame) frame);
324 }
325
326 static void
327 update_various_frame_slots (EmacsFrame ew)
328 {
329 struct frame *f = ew->emacs_frame.frame;
330
331 f->internal_border_width = ew->emacs_frame.internal_border_width;
332 }
333
334 static void
335 update_from_various_frame_slots (EmacsFrame ew)
336 {
337 struct frame *f = ew->emacs_frame.frame;
338 struct x_output *x = f->output_data.x;
339
340 ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
341 ew->core.width = FRAME_PIXEL_WIDTH (f);
342 ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
343 ew->emacs_frame.internal_border_width = f->internal_border_width;
344 ew->emacs_frame.foreground_pixel = FRAME_FOREGROUND_PIXEL (f);
345 ew->emacs_frame.cursor_color = x->cursor_pixel;
346 ew->core.border_pixel = x->border_pixel;
347
348 if (CONSP (frame_size_history))
349 frame_size_history_extra
350 (f, build_string ("update_from_various_frame_slots"),
351 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
352 ew->core.width, ew->core.height,
353 f->new_width, f->new_height);
354 }
355
356 static void
357 EmacsFrameInitialize (Widget request, Widget new,
358 ArgList dum1, Cardinal *dum2)
359 {
360 EmacsFrame ew = (EmacsFrame) new;
361
362 if (!ew->emacs_frame.frame)
363 {
364 fputs ("can't create an emacs frame widget without a frame\n", stderr);
365 exit (1);
366 }
367
368 update_from_various_frame_slots (ew);
369 set_frame_size (ew);
370 }
371
372 static void
373 resize_cb (Widget widget,
374 XtPointer closure,
375 XEvent *event,
376 Boolean *continue_to_dispatch)
377 {
378 EmacsFrameResize (widget);
379 }
380
381
382 static void
383 EmacsFrameRealize (Widget widget, XtValueMask *mask,
384 XSetWindowAttributes *attrs)
385 {
386 EmacsFrame ew = (EmacsFrame) widget;
387 struct frame *f = ew->emacs_frame.frame;
388
389
390
391
392 attrs->event_mask = (STANDARD_EVENT_SET
393 | PropertyChangeMask
394 | SubstructureNotifyMask);
395 *mask |= CWEventMask;
396 XtCreateWindow (widget, InputOutput, (Visual *) CopyFromParent, *mask,
397 attrs);
398
399
400 XtAddRawEventHandler (widget, StructureNotifyMask, False, resize_cb, NULL);
401
402 if (CONSP (frame_size_history))
403 frame_size_history_plain
404 (f, build_string ("EmacsFrameRealize"));
405
406 if (get_wm_shell (widget))
407 update_wm_hints (get_wm_shell (widget), ew);
408 }
409
410 static void
411 EmacsFrameDestroy (Widget widget)
412 {
413
414 }
415
416 static void
417 EmacsFrameResize (Widget widget)
418 {
419 EmacsFrame ew = (EmacsFrame) widget;
420 struct frame *f = ew->emacs_frame.frame;
421
422 if (CONSP (frame_size_history))
423 frame_size_history_extra
424 (f, build_string ("EmacsFrameResize"),
425 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
426 ew->core.width, ew->core.height,
427 f->new_width, f->new_height);
428
429 change_frame_size (f, ew->core.width, ew->core.height,
430 false, true, false);
431
432 if (get_wm_shell (widget))
433 update_wm_hints (get_wm_shell (widget), ew);
434 update_various_frame_slots (ew);
435
436 cancel_mouse_face (f);
437 }
438
439 static XtGeometryResult
440 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
441 XtWidgetGeometry *result)
442 {
443 int mask = request->request_mode;
444
445 if (mask & (CWWidth | CWHeight) && !frame_resize_pixelwise)
446 {
447 EmacsFrame ew = (EmacsFrame) widget;
448 Dimension ok_width, ok_height;
449
450 round_size_to_char (ew,
451 mask & CWWidth ? request->width : ew->core.width,
452 mask & CWHeight ? request->height : ew->core.height,
453 &ok_width, &ok_height);
454 if ((mask & CWWidth) && (ok_width != request->width))
455 {
456 result->request_mode |= CWWidth;
457 result->width = ok_width;
458 }
459 if ((mask & CWHeight) && (ok_height != request->height))
460 {
461 result->request_mode |= CWHeight;
462 result->height = ok_height;
463 }
464 }
465 return result->request_mode ? XtGeometryAlmost : XtGeometryYes;
466 }
467
468
469 void
470 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
471 {
472 EmacsFrame ew = (EmacsFrame) widget;
473 struct frame *f = ew->emacs_frame.frame;
474
475 if (CONSP (frame_size_history))
476 frame_size_history_extra
477 (f, build_string ("EmacsFrameSetCharSize"),
478 FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
479 columns, rows,
480 f->new_width, f->new_height);
481
482 if (!frame_inhibit_resize (f, 0, Qfont)
483 && !frame_inhibit_resize (f, 1, Qfont))
484 x_set_window_size (f, 0, columns * FRAME_COLUMN_WIDTH (f),
485 rows * FRAME_LINE_HEIGHT (f));
486 }
487
488 static void
489 EmacsFrameExpose (Widget widget, XEvent *event, Region region)
490 {
491 EmacsFrame ew = (EmacsFrame) widget;
492 struct frame *f = ew->emacs_frame.frame;
493
494 expose_frame (f, event->xexpose.x, event->xexpose.y,
495 event->xexpose.width, event->xexpose.height);
496 flush_frame (f);
497 }
498
499
500 void
501 widget_store_internal_border (Widget widget)
502 {
503 EmacsFrame ew = (EmacsFrame) widget;
504 struct frame *f = ew->emacs_frame.frame;
505
506 ew->emacs_frame.internal_border_width = f->internal_border_width;
507 }