Mercurial > hg > xemacs-beta
annotate src/frame-x.c @ 5124:623d57b7fbe8 ben-lisp-object
separate regular and disksave finalization, print method fixes.
Create separate disksave method and make the finalize method only be for
actual object finalization, not disksave finalization.
Fix places where 0 was given in place of a printer -- print methods are
mandatory, and internal objects formerly without a print method now must
explicitly specify internal_object_printer().
Change the defn of CONSOLE_LIVE_P to avoid problems in some weird situations.
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-01-20 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (very_old_free_lcrecord):
* alloc.c (disksave_object_finalization_1):
* alloc.c (make_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* buffer.c:
* bytecode.c:
* bytecode.c (Fcompiled_function_p):
* chartab.c:
* console-impl.h:
* console-impl.h (CONSOLE_TYPE_P):
* console.c:
* console.c (set_quit_events):
* data.c:
* data.c (Fmake_ephemeron):
* database.c:
* database.c (finalize_database):
* database.c (Fclose_database):
* device-msw.c:
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device.c:
* elhash.c:
* elhash.c (finalize_hash_table):
* eval.c:
* eval.c (bind_multiple_value_limits):
* event-stream.c:
* event-stream.c (finalize_command_builder):
* events.c:
* events.c (mark_event):
* extents.c:
* extents.c (finalize_extent_info):
* extents.c (uninit_buffer_extents):
* faces.c:
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.h:
* file-coding.h (struct coding_system_methods):
* file-coding.h (struct detector):
* floatfns.c:
* floatfns.c (extract_float):
* fns.c:
* fns.c (Fidentity):
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (finalize_fc_config):
* frame.c:
* glyphs.c:
* glyphs.c (finalize_image_instance):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* gui.c:
* gui.c (gui_error):
* keymap.c:
* lisp.h (struct Lisp_Symbol):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE):
* lrecord.h (DEFINE_DUMPABLE_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_SIZABLE_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_FROB_BLOCK_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_INTERNAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT):
* lrecord.h (MAKE_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_MODULE_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_MODULE_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT):
* lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_MODULE_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_MODULE_GENERAL_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT):
* lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_GENERAL_LISP_OBJECT):
* lrecord.h (MAKE_MODULE_LISP_OBJECT):
* lstream.c:
* lstream.c (finalize_lstream):
* lstream.c (disksave_lstream):
* marker.c:
* marker.c (finalize_marker):
* mule-charset.c (make_charset):
* number.c:
* objects.c:
* objects.c (finalize_color_instance):
* objects.c (finalize_font_instance):
* opaque.c:
* opaque.c (make_opaque_ptr):
* process-nt.c:
* process-nt.c (nt_finalize_process_data):
* process-nt.c (nt_deactivate_process):
* process.c:
* process.c (finalize_process):
* procimpl.h (struct process_methods):
* scrollbar.c:
* scrollbar.c (free_scrollbar_instance):
* specifier.c (finalize_specifier):
* symbols.c:
* toolbar.c:
* toolbar.c (Ftoolbar_button_p):
* tooltalk.c:
* ui-gtk.c:
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* window.c:
* window.c (finalize_window):
* window.c (mark_window_as_deleted):
Separate out regular and disksave finalization. Instead of a
FOR_DISKSAVE argument to the finalizer, create a separate object
method `disksaver'. Make `finalizer' have only one argument.
Go through and separate out all finalize methods into finalize
and disksave. Delete lots of thereby redundant disksave checking.
Delete places that signal an error if we attempt to disksave --
all of these objects are non-dumpable and we will get an error
from pdump anyway if we attempt to dump them. After this is done,
only one object remains that has a disksave method -- lstream.
Change DEFINE_*_LISP_OBJECT_WITH_PROPS to DEFINE_*_GENERAL_LISP_OBJECT,
which is used for specifying either property methods or disksave
methods (or in the future, any other less-used methods).
Remove the for_disksave argument to finalize_process_data. Don't
provide a disksaver for processes because no one currently needs
it.
Clean up various places where objects didn't provide a print method.
It was made mandatory in previous changes, and all methods now
either provide their own print method or use internal_object_printer
or external_object_printer.
Change the definition of CONSOLE_LIVE_P to use the contype enum
rather than looking into the conmeths structure -- in some weird
situations with dead objects, the conmeths structure is NULL,
and printing such objects from debug_print() will crash if we try
to look into the conmeths structure.
| author | Ben Wing <ben@xemacs.org> |
|---|---|
| date | Wed, 20 Jan 2010 07:05:57 -0600 |
| parents | d1247f3cc363 |
| children | b5df3737028a |
| rev | line source |
|---|---|
| 428 | 1 /* Functions for the X window system. |
| 2 Copyright (C) 1989, 1992-5, 1997 Free Software Foundation, Inc. | |
| 2367 | 3 Copyright (C) 1995, 1996, 2001, 2002, 2004 Ben Wing. |
| 428 | 4 |
| 5 This file is part of XEmacs. | |
| 6 | |
| 7 XEmacs is free software; you can redistribute it and/or modify it | |
| 8 under the terms of the GNU General Public License as published by the | |
| 9 Free Software Foundation; either version 2, or (at your option) any | |
| 10 later version. | |
| 11 | |
| 12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
| 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 15 for more details. | |
| 16 | |
| 17 You should have received a copy of the GNU General Public License | |
| 18 along with XEmacs; see the file COPYING. If not, write to | |
| 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
| 20 Boston, MA 02111-1307, USA. */ | |
| 21 | |
| 22 /* Synched up with: Not synched with FSF. */ | |
| 23 | |
| 2367 | 24 /* This file has been Mule-ized, Ben Wing, 10-14-04. */ |
| 25 | |
| 428 | 26 /* Substantially rewritten for XEmacs. */ |
| 27 | |
| 28 #include <config.h> | |
| 29 #include "lisp.h" | |
| 30 | |
| 800 | 31 #include "buffer.h" |
| 872 | 32 #include "device-impl.h" |
| 800 | 33 #include "events.h" |
| 34 #include "extents.h" | |
| 35 #include "faces.h" | |
| 872 | 36 #include "frame-impl.h" |
| 800 | 37 #include "gutter.h" |
| 872 | 38 #include "window.h" |
| 39 | |
| 40 #include "console-x-impl.h" | |
| 800 | 41 #include "glyphs-x.h" |
| 872 | 42 #include "objects-x-impl.h" |
| 800 | 43 #include "scrollbar-x.h" |
| 44 | |
| 428 | 45 #include "xintrinsicp.h" /* CoreP.h needs this */ |
| 46 #include <X11/CoreP.h> /* Numerous places access the fields of | |
| 47 a core widget directly. We could | |
| 48 use XtGetValues(), but ... */ | |
| 49 #include <X11/Shell.h> | |
| 50 #include <X11/ShellP.h> | |
|
4769
5460287a3327
Remove support for pre-X11R5 systems, including systems without Xmu. See
Jerry James <james@xemacs.org>
parents:
4706
diff
changeset
|
51 #include <X11/Xmu/Editres.h> |
| 428 | 52 #include "EmacsManager.h" |
| 53 #include "EmacsFrameP.h" | |
| 54 #include "EmacsShell.h" | |
| 55 #ifdef EXTERNAL_WIDGET | |
| 56 #include "ExternalShell.h" | |
| 57 #endif | |
| 58 | |
| 59 #ifdef HAVE_DRAGNDROP | |
| 60 #include "dragdrop.h" | |
| 61 #endif | |
| 62 | |
| 63 /* Default properties to use when creating frames. */ | |
| 64 Lisp_Object Vdefault_x_frame_plist; | |
| 65 | |
| 2747 | 66 Lisp_Object Qoverride_redirect; |
| 428 | 67 Lisp_Object Qx_resource_name; |
| 68 | |
| 1204 | 69 static const struct memory_description x_frame_data_description_1 [] = { |
| 1346 | 70 { XD_LISP_OBJECT, offsetof (struct x_frame, last_menubar_buffer) }, |
| 1204 | 71 { XD_LISP_OBJECT, offsetof (struct x_frame, icon_pixmap) }, |
| 72 { XD_LISP_OBJECT, offsetof (struct x_frame, icon_pixmap_mask) }, | |
| 73 { XD_END } | |
| 74 }; | |
| 75 | |
| 3092 | 76 #ifdef NEW_GC |
|
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4790
diff
changeset
|
77 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("x-frame", x_frame, |
|
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4790
diff
changeset
|
78 0, x_frame_data_description_1, |
|
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4790
diff
changeset
|
79 Lisp_X_Frame); |
| 3092 | 80 #else /* not NEW_GC */ |
| 1204 | 81 extern const struct sized_memory_description x_frame_data_description; |
| 82 | |
| 83 const struct sized_memory_description x_frame_data_description = { | |
| 84 sizeof (struct x_frame), x_frame_data_description_1 | |
| 85 }; | |
| 3092 | 86 #endif /* not NEW_GC */ |
| 1204 | 87 |
| 428 | 88 EXFUN (Fx_window_id, 1); |
| 89 | |
| 90 | |
| 91 /************************************************************************/ | |
| 92 /* helper functions */ | |
| 93 /************************************************************************/ | |
| 94 | |
| 95 /* Return the Emacs frame-object corresponding to an X window */ | |
| 96 struct frame * | |
| 97 x_window_to_frame (struct device *d, Window wdesc) | |
| 98 { | |
| 99 Lisp_Object tail, frame; | |
| 100 struct frame *f; | |
| 101 | |
| 102 /* This function was previously written to accept only a window argument | |
| 103 (and to loop over all devices looking for a matching window), but | |
| 104 that is incorrect because window ID's are not unique across displays. */ | |
| 105 | |
| 106 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail)) | |
| 107 { | |
| 108 frame = XCAR (tail); | |
| 109 if (!FRAMEP (frame)) | |
| 110 continue; | |
| 111 f = XFRAME (frame); | |
| 112 if (FRAME_X_P (f) && XtWindow (FRAME_X_TEXT_WIDGET (f)) == wdesc) | |
| 113 return f; | |
| 114 } | |
| 115 return 0; | |
| 116 } | |
| 117 | |
| 118 /* Like x_window_to_frame but also compares the window with the widget's | |
| 119 windows */ | |
| 120 struct frame * | |
| 121 x_any_window_to_frame (struct device *d, Window wdesc) | |
| 122 { | |
| 123 Widget w; | |
| 124 assert (DEVICE_X_P (d)); | |
| 125 | |
| 126 w = XtWindowToWidget (DEVICE_X_DISPLAY (d), wdesc); | |
| 127 | |
| 128 if (!w) | |
| 129 return 0; | |
| 130 | |
| 131 /* We used to map over all frames here and then map over all widgets | |
| 132 belonging to that frame. However it turns out that this was very fragile | |
| 442 | 133 as it requires our display structures to be in sync _and_ that the |
| 428 | 134 loop is told about every new widget somebody adds. Therefore we |
| 135 now let Xt find it for us (which does a bottom-up search which | |
| 136 could even be faster) */ | |
| 137 return x_any_widget_or_parent_to_frame (d, w); | |
| 138 } | |
| 139 | |
| 140 static struct frame * | |
| 141 x_find_frame_for_window (struct device *d, Window wdesc) | |
| 142 { | |
| 143 Lisp_Object tail, frame; | |
| 144 struct frame *f; | |
| 145 /* This function was previously written to accept only a window argument | |
| 146 (and to loop over all devices looking for a matching window), but | |
| 147 that is incorrect because window ID's are not unique across displays. */ | |
| 148 | |
| 149 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail)) | |
| 150 { | |
| 151 frame = XCAR (tail); | |
| 152 f = XFRAME (frame); | |
| 153 /* This frame matches if the window is any of its widgets. */ | |
| 154 if (wdesc == XtWindow (FRAME_X_SHELL_WIDGET (f)) || | |
| 155 wdesc == XtWindow (FRAME_X_CONTAINER_WIDGET (f)) || | |
| 156 wdesc == XtWindow (FRAME_X_TEXT_WIDGET (f))) | |
| 157 return f; | |
| 158 | |
| 159 /* Match if the window is one of the widgets at the top of the frame | |
| 160 (menubar, Energize psheets). */ | |
| 161 | |
| 162 /* Note: Jamie once said | |
| 163 | |
| 164 "Do *not* match if the window is this frame's psheet." | |
| 165 | |
| 166 But this is wrong and will screw up some functions that expect | |
| 167 x_any_window_to_frame() to work as advertised. I think the reason | |
| 168 for this statement is that, in the old (broken) event loop, where | |
| 169 not all events went through XtDispatchEvent(), psheet events | |
| 170 would incorrectly get sucked away by Emacs if this function matched | |
| 171 on psheet widgets. */ | |
| 172 | |
| 173 /* Note: that this called only from | |
| 174 x_any_widget_or_parent_to_frame it is unnecessary to iterate | |
| 175 over the top level widgets. */ | |
| 176 | |
| 177 /* Note: we use to special case scrollbars but this turns out to be a bad idea | |
| 178 because | |
| 179 1. We sometimes get events for _unmapped_ scrollbars and our | |
| 180 callers don't want us to fail. | |
| 181 2. Starting with the 21.2 widget stuff there are now loads of | |
| 182 widgets to check and it is easy to forget adding them in a loop here. | |
| 183 See x_any_window_to_frame | |
| 184 3. We pick up all widgets now anyway. */ | |
| 185 } | |
| 186 | |
| 187 return 0; | |
| 188 } | |
| 189 | |
| 190 struct frame * | |
| 191 x_any_widget_or_parent_to_frame (struct device *d, Widget widget) | |
| 192 { | |
| 193 while (widget) | |
| 194 { | |
| 195 struct frame *f = x_find_frame_for_window (d, XtWindow (widget)); | |
| 196 if (f) | |
| 197 return f; | |
| 198 widget = XtParent (widget); | |
| 199 } | |
| 200 | |
| 201 return 0; | |
| 202 } | |
| 203 | |
| 204 struct frame * | |
| 205 decode_x_frame (Lisp_Object frame) | |
| 206 { | |
| 207 if (NILP (frame)) | |
| 793 | 208 frame = wrap_frame (selected_frame ()); |
| 428 | 209 CHECK_LIVE_FRAME (frame); |
| 210 /* this will also catch dead frames, but putting in the above check | |
| 211 results in a more useful error */ | |
| 212 CHECK_X_FRAME (frame); | |
| 213 return XFRAME (frame); | |
| 214 } | |
| 215 | |
| 216 | |
| 217 /************************************************************************/ | |
| 218 /* window-manager interactions */ | |
| 219 /************************************************************************/ | |
| 220 | |
| 221 #if 0 | |
| 222 /* Not currently used. */ | |
| 223 | |
| 224 void | |
| 225 x_wm_mark_shell_size_user_specified (Widget wmshell) | |
| 226 { | |
| 2500 | 227 if (! XtIsWMShell (wmshell)) ABORT (); |
| 428 | 228 EmacsShellSetSizeUserSpecified (wmshell); |
| 229 } | |
| 230 | |
| 231 void | |
| 232 x_wm_mark_shell_position_user_specified (Widget wmshell) | |
| 233 { | |
| 2500 | 234 if (! XtIsWMShell (wmshell)) ABORT (); |
| 428 | 235 EmacsShellSetPositionUserSpecified (wmshell); |
| 236 } | |
| 237 | |
| 238 #endif | |
| 239 | |
| 240 void | |
| 241 x_wm_set_shell_iconic_p (Widget shell, int iconic_p) | |
| 242 { | |
| 2500 | 243 if (! XtIsWMShell (shell)) ABORT (); |
| 428 | 244 |
| 245 /* Because of questionable logic in Shell.c, this sequence can't work: | |
| 246 | |
| 247 w = XtCreatePopupShell (...); | |
| 248 Xt_SET_VALUE (w, XtNiconic, True); | |
| 249 XtRealizeWidget (w); | |
| 250 | |
| 251 The iconic resource is only consulted at initialization time (when | |
| 252 XtCreatePopupShell is called) instead of at realization time (just | |
| 253 before the window gets created, which would be more sensible) or | |
| 254 at management-time (just before the window gets mapped, which would | |
| 255 be most sensible of all). | |
| 256 | |
| 257 The bug is that Shell's SetValues method doesn't do anything to | |
| 258 w->wm.wm_hints.initial_state until after the widget has been realized. | |
| 259 Calls to XtSetValues are ignored in the window between creation and | |
| 260 realization. This is true of MIT X11R5 patch level 25, at least. | |
| 261 (Apparently some other versions of Xt don't have this bug?) | |
| 262 */ | |
| 263 Xt_SET_VALUE (shell, XtNiconic, iconic_p); | |
| 264 EmacsShellSmashIconicHint (shell, iconic_p); | |
| 265 } | |
| 266 | |
| 267 void | |
| 268 x_wm_set_cell_size (Widget wmshell, int cw, int ch) | |
| 269 { | |
| 270 Arg al [2]; | |
| 271 | |
| 272 if (!XtIsWMShell (wmshell)) | |
| 2500 | 273 ABORT (); |
| 428 | 274 if (cw <= 0 || ch <= 0) |
| 2500 | 275 ABORT (); |
| 428 | 276 |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
277 Xt_SET_ARG (al[0], XtNwidthInc, cw); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
278 Xt_SET_ARG (al[1], XtNheightInc, ch); |
| 428 | 279 XtSetValues (wmshell, al, 2); |
| 280 } | |
| 281 | |
| 282 void | |
| 283 x_wm_set_variable_size (Widget wmshell, int width, int height) | |
| 284 { | |
| 285 Arg al [2]; | |
| 286 | |
| 287 if (!XtIsWMShell (wmshell)) | |
| 2500 | 288 ABORT (); |
| 428 | 289 #ifdef DEBUG_GEOMETRY_MANAGEMENT |
| 290 /* See comment in EmacsShell.c */ | |
| 291 printf ("x_wm_set_variable_size: %d %d\n", width, height); | |
| 292 fflush (stdout); | |
| 293 #endif | |
| 294 | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
295 Xt_SET_ARG (al[0], XtNwidthCells, width); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
296 Xt_SET_ARG (al[1], XtNheightCells, height); |
| 428 | 297 XtSetValues (wmshell, al, 2); |
| 298 } | |
| 299 | |
| 300 /* If the WM_PROTOCOLS property does not already contain WM_TAKE_FOCUS | |
| 301 and WM_DELETE_WINDOW, then add them. (They may already be present | |
| 302 because of the toolkit (Motif adds them, for example, but Xt doesn't). | |
| 303 */ | |
| 304 static void | |
| 305 x_wm_hack_wm_protocols (Widget widget) | |
| 306 { | |
| 307 Display *dpy = XtDisplay (widget); | |
| 308 struct device *d = get_device_from_display (dpy); | |
| 309 Window w = XtWindow (widget); | |
| 310 int need_delete = 1; | |
| 311 int need_focus = 1; | |
| 312 | |
| 313 assert (XtIsWMShell (widget)); | |
| 314 | |
| 315 { | |
| 1885 | 316 Atom type; |
| 428 | 317 int format = 0; |
| 318 unsigned long nitems = 0; | |
| 319 unsigned long bytes_after; | |
| 2367 | 320 Rawbyte *prop_return = 0; /* semantically a void* */ |
| 428 | 321 |
| 322 if (Success == XGetWindowProperty (dpy, w, DEVICE_XATOM_WM_PROTOCOLS (d), | |
| 323 0, 100, False, XA_ATOM, | |
| 324 &type, &format, &nitems, &bytes_after, | |
| 1885 | 325 &prop_return) |
| 428 | 326 && format == 32 && type == XA_ATOM) |
| 327 while (nitems > 0) | |
| 328 { | |
| 1885 | 329 Atom *atoms = (Atom *) prop_return; |
| 428 | 330 nitems--; |
| 1885 | 331 if (atoms[nitems] == DEVICE_XATOM_WM_DELETE_WINDOW (d)) |
| 428 | 332 need_delete = 0; |
| 1885 | 333 else if (atoms[nitems] == DEVICE_XATOM_WM_TAKE_FOCUS (d)) |
| 428 | 334 need_focus = 0; |
| 335 } | |
| 2367 | 336 if (prop_return) XFree ((CRawbyte *) prop_return); |
| 428 | 337 } |
| 338 { | |
| 339 Atom props [10]; | |
| 340 int count = 0; | |
| 341 if (need_delete) props[count++] = DEVICE_XATOM_WM_DELETE_WINDOW (d); | |
| 342 if (need_focus) props[count++] = DEVICE_XATOM_WM_TAKE_FOCUS (d); | |
| 343 if (count) | |
| 344 XChangeProperty (dpy, w, DEVICE_XATOM_WM_PROTOCOLS (d), XA_ATOM, 32, | |
| 2367 | 345 PropModeAppend, (Rawbyte *) props, count); |
| 428 | 346 } |
| 347 } | |
| 348 | |
| 349 static void | |
| 2367 | 350 x_wm_store_class_hints (Widget shell, Extbyte *frame_name) |
| 428 | 351 { |
| 352 Display *dpy = XtDisplay (shell); | |
| 2367 | 353 Extbyte *app_name, *app_class; |
| 428 | 354 XClassHint classhint; |
| 355 | |
| 356 if (!XtIsWMShell (shell)) | |
| 2500 | 357 ABORT (); |
| 428 | 358 |
| 359 XtGetApplicationNameAndClass (dpy, &app_name, &app_class); | |
| 360 classhint.res_name = frame_name; | |
| 361 classhint.res_class = app_class; | |
| 362 XSetClassHint (dpy, XtWindow (shell), &classhint); | |
| 363 } | |
| 364 | |
| 365 #ifndef HAVE_WMCOMMAND | |
| 2367 | 366 |
| 428 | 367 static void |
| 368 x_wm_maybe_store_wm_command (struct frame *f) | |
| 369 { | |
| 370 Widget w = FRAME_X_SHELL_WIDGET (f); | |
| 371 struct device *d = XDEVICE (FRAME_DEVICE (f)); | |
| 372 | |
| 373 if (!XtIsWMShell (w)) | |
| 2500 | 374 ABORT (); |
| 428 | 375 |
| 376 if (NILP (DEVICE_X_WM_COMMAND_FRAME (d))) | |
| 377 { | |
| 378 int argc; | |
| 2367 | 379 Wexttext **argv; |
| 428 | 380 make_argc_argv (Vcommand_line_args, &argc, &argv); |
| 381 XSetCommand (XtDisplay (w), XtWindow (w), argv, argc); | |
| 382 free_argc_argv (argv); | |
| 793 | 383 DEVICE_X_WM_COMMAND_FRAME (d) = wrap_frame (f); |
| 428 | 384 } |
| 385 } | |
| 386 | |
| 387 /* If we're deleting the frame on which the WM_COMMAND property has been | |
| 388 set, then move that property to another frame so that there is exactly | |
| 389 one frame that has that property set. | |
| 390 */ | |
| 391 static void | |
| 392 x_wm_maybe_move_wm_command (struct frame *f) | |
| 393 { | |
| 394 struct device *d = XDEVICE (FRAME_DEVICE (f)); | |
| 395 | |
| 396 /* There may not be a frame in DEVICE_X_WM_COMMAND_FRAME() | |
| 397 if we C-c'ed at startup at the right time. */ | |
| 398 if (FRAMEP (DEVICE_X_WM_COMMAND_FRAME (d)) | |
| 399 && f == XFRAME (DEVICE_X_WM_COMMAND_FRAME (d))) | |
| 400 { | |
| 401 Lisp_Object rest = DEVICE_FRAME_LIST (d); | |
| 402 DEVICE_X_WM_COMMAND_FRAME (d) = Qnil; | |
| 403 /* find some random other X frame that is not this one, or give up */ | |
| 404 /* skip non-top-level (ExternalClient) frames */ | |
| 405 while (!NILP (rest) && | |
| 406 (f == XFRAME (XCAR (rest)) || | |
| 407 !FRAME_X_TOP_LEVEL_FRAME_P (XFRAME (XCAR (rest))))) | |
| 408 rest = XCDR (rest); | |
| 409 if (NILP (rest)) | |
| 410 return; | |
| 411 f = XFRAME (XCAR (rest)); | |
| 412 | |
| 413 x_wm_maybe_store_wm_command (f); | |
| 414 | |
| 415 } | |
| 416 } | |
| 2367 | 417 |
| 428 | 418 #endif /* !HAVE_WMCOMMAND */ |
| 419 | |
| 593 | 420 int |
| 421 x_frame_window_state (struct frame *f) | |
| 428 | 422 { |
| 423 Atom actual_type; | |
| 424 int actual_format; | |
| 425 unsigned long nitems, bytesafter; | |
| 2367 | 426 Rawbyte *datap = 0; |
| 428 | 427 Widget widget; |
| 593 | 428 int result = -1; |
| 428 | 429 struct device *d = XDEVICE (FRAME_DEVICE (f)); |
| 430 | |
| 431 widget = FRAME_X_SHELL_WIDGET (f); | |
| 432 if (Success == XGetWindowProperty (XtDisplay (widget), XtWindow (widget), | |
| 433 DEVICE_XATOM_WM_STATE (d), 0, 2, False, | |
| 434 DEVICE_XATOM_WM_STATE (d), &actual_type, | |
| 435 &actual_format, &nitems, &bytesafter, | |
| 1885 | 436 &datap) |
| 428 | 437 && datap) |
| 438 { | |
| 1885 | 439 unsigned long *ul_result_ptr = (unsigned long *) datap; |
| 593 | 440 if (nitems <= 2) /* "suggested" by ICCCM version 1 */ |
| 1885 | 441 result = (int) ul_result_ptr[0]; |
| 2367 | 442 XFree ((CRawbyte *) datap); |
| 428 | 443 } |
| 593 | 444 |
| 428 | 445 return result; |
| 446 } | |
| 447 | |
| 593 | 448 static int |
| 449 x_frame_iconified_p (struct frame *f) | |
| 450 { | |
| 451 return x_frame_window_state (f) == IconicState; | |
| 452 } | |
| 453 | |
| 428 | 454 |
| 455 /************************************************************************/ | |
| 456 /* frame properties */ | |
| 457 /************************************************************************/ | |
| 458 | |
| 459 /* Connect the frame-property names (symbols) to the corresponding | |
| 460 X Resource Manager names. The name of a property, as a Lisp symbol, | |
| 793 | 461 has an `x-resource-name' property which is a Lisp string. */ |
| 428 | 462 |
| 463 static void | |
| 464 init_x_prop_symbols (void) | |
| 465 { | |
| 466 #define def(sym, rsrc) \ | |
| 467 Fput (sym, Qx_resource_name, build_string (rsrc)) | |
| 468 #define defi(sym,rsrc) \ | |
| 469 def (sym, rsrc); Fput (sym, Qintegerp, Qt) | |
| 470 | |
| 471 #if 0 /* this interferes with things. #### fix this right */ | |
| 472 def (Qminibuffer, XtNminibuffer); | |
| 473 def (Qunsplittable, XtNunsplittable); | |
| 474 #endif | |
| 475 defi(Qinternal_border_width, XtNinternalBorderWidth); | |
| 476 def (Qscrollbar_placement, XtNscrollBarPlacement); | |
| 477 defi(Qinter_line_space, XtNinterline); | |
| 478 /* font, foreground */ | |
| 479 def (Qiconic, XtNiconic); | |
| 480 def (Qbar_cursor, XtNbarCursor); | |
| 481 def (Qvisual_bell, XtNvisualBell); | |
| 482 defi(Qbell_volume, XtNbellVolume); | |
| 483 def (Qpointer_background, XtNpointerBackground); | |
| 484 def (Qpointer_color, XtNpointerColor); | |
| 485 def (Qtext_pointer, XtNtextPointer); | |
| 486 def (Qspace_pointer, XtNspacePointer); | |
| 487 def (Qmodeline_pointer, XtNmodeLinePointer); | |
| 488 def (Qgc_pointer, XtNgcPointer); | |
| 489 /* geometry, initial_geometry */ | |
| 490 def (Qinitially_unmapped, XtNinitiallyUnmapped); | |
| 491 /* preferred_width, preferred_height */ | |
| 492 def (Quse_backing_store, XtNuseBackingStore); | |
| 493 | |
| 494 /* inherited: */ | |
| 495 | |
| 496 def (Qborder_color, XtNborderColor); | |
| 497 defi(Qborder_width, XtNborderWidth); | |
| 498 defi(Qwidth, XtNwidth); | |
| 499 defi(Qheight, XtNheight); | |
| 500 defi(Qleft, XtNx); | |
| 501 defi(Qtop, XtNy); | |
| 502 | |
| 503 #undef def | |
| 3381 | 504 #undef defi |
| 428 | 505 } |
| 506 | |
| 507 static Lisp_Object | |
| 508 color_to_string (Widget w, unsigned long pixel) | |
| 509 { | |
| 867 | 510 Ibyte buf[255]; |
| 428 | 511 |
| 512 XColor color; | |
| 513 color.pixel = pixel; | |
| 514 XQueryColor (XtDisplay (w), w->core.colormap, &color); | |
| 771 | 515 qxesprintf (buf, "#%04x%04x%04x", color.red, color.green, color.blue); |
| 516 return build_intstring (buf); | |
| 428 | 517 } |
| 518 | |
| 519 static void | |
| 520 x_get_top_level_position (Display *d, Window w, Position *x, Position *y) | |
| 521 { | |
| 522 Window root, parent = w, *children; | |
| 523 unsigned int nchildren; | |
| 524 XWindowAttributes xwa; | |
| 525 | |
| 526 do | |
| 527 { | |
| 528 w = parent; | |
| 529 if (!XQueryTree (d, w, &root, &parent, &children, &nchildren)) | |
| 530 { | |
| 531 *x = 0; | |
| 532 *y = 0; | |
| 533 return; | |
| 534 } | |
| 535 XFree (children); | |
| 536 } | |
| 537 while (root != parent); | |
| 538 XGetWindowAttributes (d, w, &xwa); | |
| 539 *x = xwa.x; | |
| 540 *y = xwa.y; | |
| 541 } | |
| 542 | |
| 543 #if 0 | |
| 544 static void | |
| 545 x_smash_bastardly_shell_position (Widget shell) | |
| 546 { | |
| 547 /* Naturally those bastards who wrote Xt couldn't be bothered | |
| 548 to learn about race conditions and such. We can't trust | |
| 549 the X and Y values to have any semblance of correctness, | |
| 550 so we smash the right values in place. */ | |
| 551 | |
| 552 /* We might be called before we've actually realized the window (if | |
| 553 we're checking for the minibuffer resource). This will bomb in | |
| 554 that case so we don't bother calling it. */ | |
| 555 if (XtWindow (shell)) | |
| 556 x_get_top_level_position (XtDisplay (shell), XtWindow (shell), | |
| 557 &shell->core.x, &shell->core.y); | |
| 558 } | |
| 559 #endif /* 0 */ | |
| 560 | |
| 561 static Lisp_Object | |
| 562 x_frame_property (struct frame *f, Lisp_Object property) | |
| 563 { | |
| 564 Widget shell = FRAME_X_SHELL_WIDGET (f); | |
| 565 EmacsFrame w = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | |
| 566 Widget gw = (Widget) w; | |
| 567 | |
| 568 if (EQ (Qleft, property) || EQ (Qtop, property)) | |
| 569 { | |
| 570 Position x, y; | |
| 571 if (!XtWindow(shell)) | |
| 572 return Qzero; | |
| 573 x_get_top_level_position (XtDisplay (shell), XtWindow (shell), &x, &y); | |
| 574 if (EQ (Qleft, property)) return make_int (x); | |
| 575 if (EQ (Qtop, property)) return make_int (y); | |
| 576 } | |
| 577 if (EQ (Qborder_width, property)) | |
| 578 return make_int (w->core.border_width); | |
| 579 if (EQ (Qinternal_border_width, property)) | |
| 580 return make_int (w->emacs_frame.internal_border_width); | |
| 581 if (EQ (Qborder_color, property)) | |
| 582 return color_to_string (gw, w->core.border_pixel); | |
| 583 if (EQ (Qinter_line_space, property)) | |
| 584 return make_int (w->emacs_frame.interline); | |
| 585 if (EQ (Qwindow_id, property)) | |
| 771 | 586 return Fx_window_id (wrap_frame (f)); |
| 428 | 587 |
| 588 return Qunbound; | |
| 589 } | |
| 590 | |
| 591 static int | |
| 2286 | 592 x_internal_frame_property_p (struct frame *UNUSED (f), Lisp_Object property) |
| 428 | 593 { |
| 594 return EQ (property, Qleft) | |
| 595 || EQ (property, Qtop) | |
| 596 || EQ (property, Qborder_width) | |
| 597 || EQ (property, Qinternal_border_width) | |
| 598 || EQ (property, Qborder_color) | |
| 599 || EQ (property, Qinter_line_space) | |
| 600 || EQ (property, Qwindow_id) | |
| 601 || STRINGP (property); | |
| 602 } | |
| 603 | |
| 604 static Lisp_Object | |
| 605 x_frame_properties (struct frame *f) | |
| 606 { | |
| 607 Lisp_Object props = Qnil; | |
| 608 Widget shell = FRAME_X_SHELL_WIDGET (f); | |
| 609 EmacsFrame w = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | |
| 610 Widget gw = (Widget) w; | |
| 611 Position x, y; | |
| 612 | |
| 771 | 613 props = cons3 (Qwindow_id, Fx_window_id (wrap_frame (f)), props); |
| 428 | 614 props = cons3 (Qinter_line_space, make_int (w->emacs_frame.interline), props); |
| 615 | |
| 616 props = cons3 (Qborder_color, | |
| 617 color_to_string (gw, w->core.border_pixel), props); | |
| 618 props = cons3 (Qinternal_border_width, | |
| 619 make_int (w->emacs_frame.internal_border_width), props); | |
| 620 props = cons3 (Qborder_width, make_int (w->core.border_width), props); | |
| 621 | |
| 622 if (!XtWindow(shell)) | |
| 623 x = y = 0; | |
| 624 else | |
| 625 x_get_top_level_position (XtDisplay (shell), XtWindow (shell), &x, &y); | |
| 626 | |
| 627 props = cons3 (Qtop, make_int (y), props); | |
| 628 props = cons3 (Qleft, make_int (x), props); | |
| 629 | |
| 630 return props; | |
| 631 } | |
| 632 | |
| 633 | |
| 634 /* Functions called only from `x_set_frame_properties' to set | |
| 635 individual properties. */ | |
| 636 | |
| 637 static void | |
| 867 | 638 x_set_frame_text_value (struct frame *f, Ibyte *value, |
| 428 | 639 String Xt_resource_name, |
| 640 String Xt_resource_encoding_name) | |
| 641 { | |
| 642 Atom encoding = XA_STRING; | |
| 643 String new_XtValue = (String) value; | |
| 644 String old_XtValue = NULL; | |
| 645 | |
| 646 #ifdef MULE | |
| 867 | 647 Ibyte *ptr; |
| 428 | 648 /* Optimize for common ASCII case */ |
| 649 for (ptr = value; *ptr; ptr++) | |
| 826 | 650 if (!byte_ascii_p (*ptr)) |
| 428 | 651 { |
| 2367 | 652 const Extbyte *tmp; |
| 428 | 653 encoding = DEVICE_XATOM_COMPOUND_TEXT (XDEVICE (FRAME_DEVICE (f))); |
| 442 | 654 C_STRING_TO_EXTERNAL (value, tmp, Qctext); |
| 428 | 655 new_XtValue = (String) tmp; |
| 656 break; | |
| 657 } | |
| 658 #endif /* MULE */ | |
| 659 | |
| 440 | 660 /* #### Caching is device-independent - belongs in update_frame_title. */ |
| 428 | 661 Xt_GET_VALUE (FRAME_X_SHELL_WIDGET (f), Xt_resource_name, &old_XtValue); |
| 662 if (!old_XtValue || strcmp (new_XtValue, old_XtValue)) | |
| 663 { | |
| 664 Arg al[2]; | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
665 Xt_SET_ARG (al[0], Xt_resource_name, new_XtValue); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
666 Xt_SET_ARG (al[1], Xt_resource_encoding_name, encoding); |
| 428 | 667 XtSetValues (FRAME_X_SHELL_WIDGET (f), al, 2); |
| 668 } | |
| 669 } | |
| 670 | |
| 671 static void | |
| 867 | 672 x_set_title_from_ibyte (struct frame *f, Ibyte *name) |
| 428 | 673 { |
| 674 x_set_frame_text_value (f, name, XtNtitle, XtNtitleEncoding); | |
| 675 } | |
| 676 | |
| 677 static void | |
| 867 | 678 x_set_icon_name_from_ibyte (struct frame *f, Ibyte *name) |
| 428 | 679 { |
| 680 x_set_frame_text_value (f, name, XtNiconName, XtNiconNameEncoding); | |
| 681 } | |
| 682 | |
| 683 /* Set the initial frame size as specified. This function is used | |
| 684 when the frame's widgets have not yet been realized. In this | |
| 685 case, it is not sufficient just to set the width and height of | |
| 686 the EmacsFrame widget, because they will be ignored when the | |
| 687 widget is realized (instead, the shell's geometry resource is | |
| 688 used). */ | |
| 689 | |
| 690 static void | |
| 691 x_set_initial_frame_size (struct frame *f, int flags, int x, int y, | |
| 647 | 692 int w, int h) |
| 428 | 693 { |
| 2367 | 694 Ascbyte shell_geom[255]; |
| 428 | 695 int xval, yval; |
| 2367 | 696 Ascbyte xsign, ysign; |
| 697 Boolbyte uspos = !!(flags & (XValue | YValue)); | |
| 698 Boolbyte ussize = !!(flags & (WidthValue | HeightValue)); | |
| 699 Ascbyte *temp; | |
| 428 | 700 |
| 701 /* assign the correct size to the EmacsFrame widget ... */ | |
| 702 EmacsFrameSetCharSize (FRAME_X_TEXT_WIDGET (f), w, h); | |
| 703 | |
| 704 /* and also set the WMShell's geometry */ | |
| 705 (flags & XNegative) ? (xval = -x, xsign = '-') : (xval = x, xsign = '+'); | |
| 706 (flags & YNegative) ? (yval = -y, ysign = '-') : (yval = y, ysign = '+'); | |
| 707 | |
| 708 if (uspos && ussize) | |
| 709 sprintf (shell_geom, "=%dx%d%c%d%c%d", w, h, xsign, xval, ysign, yval); | |
| 710 else if (uspos) | |
| 711 sprintf (shell_geom, "=%c%d%c%d", xsign, xval, ysign, yval); | |
| 712 else if (ussize) | |
| 713 sprintf (shell_geom, "=%dx%d", w, h); | |
| 714 | |
| 715 if (uspos || ussize) | |
| 716 { | |
| 2367 | 717 temp = xnew_ascbytes (1 + strlen (shell_geom)); |
| 428 | 718 strcpy (temp, shell_geom); |
| 719 FRAME_X_GEOM_FREE_ME_PLEASE (f) = temp; | |
| 720 } | |
| 721 else | |
| 722 temp = NULL; | |
| 723 | |
| 724 Xt_SET_VALUE (FRAME_X_SHELL_WIDGET (f), XtNgeometry, temp); | |
| 725 } | |
| 726 | |
| 727 /* Report to X that a frame property of frame S is being set or changed. | |
| 728 If the property is not specially recognized, do nothing. | |
| 729 */ | |
| 730 | |
| 731 static void | |
| 732 x_set_frame_properties (struct frame *f, Lisp_Object plist) | |
| 733 { | |
| 734 Position x, y; | |
| 735 Dimension width = 0, height = 0; | |
| 736 Bool width_specified_p = False; | |
| 737 Bool height_specified_p = False; | |
| 738 Bool x_position_specified_p = False; | |
| 739 Bool y_position_specified_p = False; | |
| 740 Bool internal_border_width_specified = False; | |
| 741 Lisp_Object tail; | |
| 3415 | 742 Widget w; |
| 743 | |
| 744 /* We can be called after the X IO error handler has seen a broken pipe on | |
| 745 the relevant display. Don't do anything in that case. */ | |
| 746 if (!FRAME_LIVE_P (f) || DEVICE_X_BEING_DELETED (XDEVICE (FRAME_DEVICE (f)))) | |
| 747 return; | |
| 748 | |
| 749 w = FRAME_X_TEXT_WIDGET (f); | |
| 428 | 750 |
| 751 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | |
| 752 { | |
| 753 Lisp_Object prop = Fcar (tail); | |
| 754 Lisp_Object val = Fcar (Fcdr (tail)); | |
| 755 | |
| 756 if (STRINGP (prop)) | |
| 757 { | |
| 2367 | 758 const Extbyte *extprop; |
| 428 | 759 |
| 760 if (XSTRING_LENGTH (prop) == 0) | |
| 761 continue; | |
| 762 | |
| 2367 | 763 LISP_STRING_TO_EXTERNAL (prop, extprop, Qxt_widget_arg_encoding); |
| 428 | 764 if (STRINGP (val)) |
| 765 { | |
| 442 | 766 const Extbyte *extval; |
| 665 | 767 Bytecount extvallen; |
| 428 | 768 |
| 2367 | 769 /* !!#### I seriously doubt there is a single external format |
| 770 for the value of a widget argument; it depends on the | |
| 771 semantics of the argument. So use of | |
| 772 Qxt_widget_arg_encoding is totally bogus. --ben */ | |
| 440 | 773 TO_EXTERNAL_FORMAT (LISP_STRING, val, |
| 774 ALLOCA, (extval, extvallen), | |
| 2367 | 775 Qxt_widget_arg_encoding); |
| 428 | 776 XtVaSetValues (w, XtVaTypedArg, extprop, |
| 2367 | 777 /* !!#### Verify this + 1 and document |
| 778 as zero-termination */ | |
| 428 | 779 XtRString, extval, extvallen + 1, |
| 3463 | 780 NULL); |
| 428 | 781 } |
| 782 else | |
| 783 XtVaSetValues (w, XtVaTypedArg, extprop, XtRInt, | |
| 784 XINT (val), sizeof (int), | |
| 3463 | 785 NULL); |
| 428 | 786 } |
| 787 else if (SYMBOLP (prop)) | |
| 788 { | |
| 789 Lisp_Object str = Fget (prop, Qx_resource_name, Qnil); | |
| 790 int int_p = !NILP (Fget (prop, Qintegerp, Qnil)); | |
| 2367 | 791 Extbyte *strext; |
| 428 | 792 |
| 793 if (NILP (prop) || NILP (str)) | |
| 794 { | |
| 795 /* Kludge to handle the font property. */ | |
| 796 if (EQ (prop, Qfont)) | |
| 797 { | |
| 798 /* If the value is not a string we silently ignore it. */ | |
| 799 if (STRINGP (val)) | |
| 800 { | |
| 801 Lisp_Object frm, font_spec; | |
| 802 | |
| 793 | 803 frm = wrap_frame (f); |
| 428 | 804 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil); |
| 805 | |
| 806 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil); | |
| 807 update_frame_face_values (f); | |
| 808 } | |
| 809 | |
| 810 continue; | |
| 811 } | |
| 812 else | |
| 813 continue; | |
| 814 } | |
| 815 CHECK_STRING (str); | |
| 816 | |
| 817 /* Kludge the width/height so that we interpret them in characters | |
| 818 instead of pixels. Yuck yuck yuck. */ | |
| 2367 | 819 if (!qxestrcmp_ascii (XSTRING_DATA (str), "width")) |
| 428 | 820 { |
| 821 CHECK_INT (val); | |
| 822 width = XINT (val); | |
| 823 width_specified_p = True; | |
| 824 continue; | |
| 825 } | |
| 2367 | 826 if (!qxestrcmp_ascii (XSTRING_DATA (str), "height")) |
| 428 | 827 { |
| 828 CHECK_INT (val); | |
| 829 height = XINT (val); | |
| 830 height_specified_p = True; | |
| 831 continue; | |
| 832 } | |
| 833 /* Further kludge the x/y. */ | |
| 2367 | 834 if (!qxestrcmp_ascii (XSTRING_DATA (str), "x")) |
| 428 | 835 { |
| 836 CHECK_INT (val); | |
| 837 x = (Position) XINT (val); | |
| 838 x_position_specified_p = True; | |
| 839 continue; | |
| 840 } | |
| 2367 | 841 if (!qxestrcmp_ascii (XSTRING_DATA (str), "y")) |
| 428 | 842 { |
| 843 CHECK_INT (val); | |
| 844 y = (Position) XINT (val); | |
| 845 y_position_specified_p = True; | |
| 846 continue; | |
| 847 } | |
| 848 /* Have you figured out by now that this entire function is | |
| 849 one gigantic kludge? */ | |
| 2367 | 850 if (!qxestrcmp_ascii (XSTRING_DATA (str), "internalBorderWidth")) |
| 428 | 851 { |
| 852 internal_border_width_specified = True; | |
| 853 } | |
| 854 | |
| 2367 | 855 LISP_STRING_TO_EXTERNAL (str, strext, Qxt_widget_arg_encoding); |
| 428 | 856 if (int_p) |
| 857 { | |
| 858 CHECK_INT (val); | |
| 2367 | 859 Xt_SET_VALUE (w, strext, XINT (val)); |
| 428 | 860 } |
| 861 else if (EQ (val, Qt)) | |
| 862 { | |
| 2367 | 863 Xt_SET_VALUE (w, strext, True); /* XtN...*/ |
| 428 | 864 } |
| 865 else if (EQ (val, Qnil)) | |
| 866 { | |
| 2367 | 867 Xt_SET_VALUE (w, strext, False); /* XtN...*/ |
| 428 | 868 } |
| 869 else | |
| 870 { | |
| 2367 | 871 const Extbyte *extval; |
| 872 Bytecount extvallen; | |
| 2372 | 873 CHECK_STRING (val); |
| 2367 | 874 |
| 875 TO_EXTERNAL_FORMAT (LISP_STRING, val, | |
| 876 ALLOCA, (extval, extvallen), | |
| 877 Qxt_widget_arg_encoding); | |
| 428 | 878 XtVaSetValues (w, XtVaTypedArg, |
| 879 /* XtN... */ | |
| 2367 | 880 strext, |
| 881 /* !!#### Verify this + 1 and document | |
| 882 as zero-termination */ | |
| 883 XtRString, extval, extvallen + 1, | |
| 3463 | 884 NULL); |
| 428 | 885 } |
| 886 | |
| 887 #ifdef HAVE_SCROLLBARS | |
| 2367 | 888 if (!qxestrcmp_ascii (XSTRING_DATA (str), "scrollBarWidth") |
| 889 || !qxestrcmp_ascii (XSTRING_DATA (str), "scrollBarHeight")) | |
| 428 | 890 { |
| 891 x_update_frame_scrollbars (f); | |
| 892 } | |
| 893 #endif /* HAVE_SCROLLBARS */ | |
| 894 } | |
| 895 } | |
| 896 | |
| 897 /* Kludge kludge kludge. We need to deal with the size and position | |
| 898 specially. */ | |
| 899 { | |
| 900 int size_specified_p = width_specified_p || height_specified_p; | |
| 901 int position_specified_p = x_position_specified_p || | |
| 902 y_position_specified_p; | |
| 903 | |
| 904 if (!width_specified_p) | |
| 905 width = FRAME_WIDTH (f); | |
| 906 if (!height_specified_p) | |
| 907 height = FRAME_HEIGHT (f); | |
| 908 | |
| 909 /* Kludge kludge kludge kludge. */ | |
| 910 if (position_specified_p && | |
| 911 (!x_position_specified_p || !y_position_specified_p)) | |
| 912 { | |
| 913 Position dummy; | |
| 914 Widget shell = FRAME_X_SHELL_WIDGET (f); | |
| 915 x_get_top_level_position (XtDisplay (shell), XtWindow (shell), | |
| 916 (x_position_specified_p ? &dummy : &x), | |
| 917 (y_position_specified_p ? &dummy : &y)); | |
| 918 #if 0 | |
| 919 x = (int) (FRAME_X_SHELL_WIDGET (f)->core.x); | |
| 920 y = (int) (FRAME_X_SHELL_WIDGET (f)->core.y); | |
| 921 #endif | |
| 922 } | |
| 923 | |
| 924 if (!f->init_finished) | |
| 925 { | |
| 926 int flags = (size_specified_p ? WidthValue | HeightValue : 0) | | |
| 927 (position_specified_p ? | |
| 928 XValue | YValue | (x < 0 ? XNegative : 0) | (y < 0 ? YNegative : 0) | |
| 929 : 0); | |
| 930 if (size_specified_p | |
| 931 || position_specified_p | |
| 932 || internal_border_width_specified) | |
| 933 x_set_initial_frame_size (f, flags, x, y, width, height); | |
| 934 } | |
| 935 else | |
| 936 { | |
| 937 if (size_specified_p || internal_border_width_specified) | |
| 938 { | |
| 793 | 939 Lisp_Object frame = wrap_frame (f); |
| 940 | |
| 428 | 941 Fset_frame_size (frame, make_int (width), |
| 942 make_int (height), Qnil); | |
| 943 } | |
| 944 if (position_specified_p) | |
| 945 { | |
| 793 | 946 Lisp_Object frame = wrap_frame (f); |
| 947 | |
| 428 | 948 Fset_frame_position (frame, make_int (x), make_int (y)); |
| 949 } | |
| 950 } | |
| 951 } | |
| 952 } | |
| 953 | |
| 954 static int frame_title_format_already_set; | |
| 955 | |
| 956 static void | |
| 957 maybe_set_frame_title_format (Widget shell) | |
| 958 { | |
| 959 | |
| 960 /* Only do this if this is the first X frame we're creating. | |
| 961 | |
| 962 If the *title resource (or -title option) was specified, then | |
| 963 set frame-title-format to its value. | |
| 964 */ | |
| 965 | |
| 966 if (!frame_title_format_already_set) | |
| 967 { | |
| 968 /* No doubt there's a less stupid way to do this. */ | |
| 2367 | 969 Extbyte *results[2]; |
| 970 XtResource resources[2]; | |
| 971 results[0] = results[1] = 0; | |
| 972 resources[0].resource_name = XtNtitle; | |
| 973 resources[0].resource_class = XtCTitle; | |
| 974 resources[0].resource_type = XtRString; | |
| 975 resources[0].resource_size = sizeof (String); | |
| 976 resources[0].resource_offset = 0; | |
| 977 resources[0].default_type = XtRString; | |
| 978 resources[0].default_addr = 0; | |
| 979 resources[1].resource_name = XtNiconName; | |
| 980 resources[1].resource_class = XtCIconName; | |
| 981 resources[1].resource_type = XtRString; | |
| 982 resources[1].resource_size = sizeof (String); | |
| 983 resources[1].resource_offset = sizeof (Extbyte *); | |
| 984 resources[1].default_type = XtRString; | |
| 985 resources[1].default_addr = 0; | |
| 428 | 986 XtGetSubresources (XtParent (shell), (XtPointer) results, |
| 987 shell->core.name, | |
| 988 shell->core.widget_class->core_class.class_name, | |
| 989 resources, XtNumber (resources), 0, 0); | |
| 990 if (results[0]) | |
| 2367 | 991 Vframe_title_format = build_ext_string (results[0], Qctext); |
| 428 | 992 if (results[1]) |
| 2367 | 993 Vframe_icon_title_format = build_ext_string (results[1], Qctext); |
| 428 | 994 } |
| 995 | |
| 996 frame_title_format_already_set = 1; | |
| 997 } | |
| 998 | |
|
4790
bc4f2511bbea
Remove support for the OffiX drag-and-drop protocol. See xemacs-patches
Jerry James <james@xemacs.org>
parents:
4769
diff
changeset
|
999 #if defined (HAVE_CDE) |
| 2367 | 1000 |
| 1001 static Extbyte * | |
| 1002 start_drag_internal_1 (Lisp_Object event, Lisp_Object data, | |
| 1003 Lisp_Object encoding, XEvent *x_event, int listp, | |
| 1004 Widget *wid_out, Bytecount *len_out, | |
| 1005 int *num_items_out) | |
| 1006 { | |
| 1007 struct frame *f; | |
| 1008 Widget wid; | |
| 1009 struct device *d; | |
| 1010 struct x_device *xd; | |
| 1011 XWindowAttributes win_attrib; | |
| 1012 int modifier = 0, state = 0; | |
| 1013 Extbyte *dnd_data; | |
| 1014 Lisp_Event *lisp_event; | |
| 1015 | |
| 1016 CHECK_EVENT (event); | |
| 1017 lisp_event = XEVENT (event); | |
| 1018 if (EVENT_TYPE (lisp_event) != button_press_event) | |
| 1019 invalid_argument ("Need button-press event for drag", event); | |
| 1020 f = decode_x_frame (FW_FRAME (EVENT_CHANNEL (lisp_event))); | |
| 1021 wid = FRAME_X_TEXT_WIDGET (f); | |
| 1022 d = XDEVICE (FRAME_DEVICE (f)); | |
| 1023 xd = DEVICE_X_DATA (d); | |
| 1024 *num_items_out = 0; | |
| 1025 | |
| 1026 if (listp) | |
| 1027 { | |
| 1028 DECLARE_EISTRING (ei); | |
| 1029 | |
| 1030 EXTERNAL_LIST_LOOP_2 (elt, data) | |
| 1031 { | |
| 1032 CHECK_STRING (elt); | |
| 1033 eicat_lstr (ei, elt); | |
| 1034 eicat_ch (ei, '\0'); | |
| 1035 (*num_items_out)++; | |
| 1036 } | |
| 1037 eicat_ch (ei, '\0'); | |
| 1038 SIZED_C_STRING_TO_SIZED_EXTERNAL_MALLOC (eidata (ei), eilen (ei), | |
| 1039 dnd_data, *len_out, | |
| 1040 encoding); | |
| 1041 } | |
| 1042 else | |
| 1043 { | |
| 1044 CHECK_STRING (data); | |
| 1045 LISP_STRING_TO_SIZED_EXTERNAL_MALLOC (data, dnd_data, *len_out, | |
| 1046 encoding); | |
| 1047 *len_out += EXTTEXT_ZTERM_SIZE; | |
| 1048 (*num_items_out)++; | |
| 1049 } | |
| 1050 | |
| 1051 /* not so gross hack that converts an emacs event back to a XEvent */ | |
| 1052 | |
| 1053 x_event->xbutton.type = ButtonPress; | |
| 1054 x_event->xbutton.send_event = False; | |
| 1055 x_event->xbutton.display = XtDisplayOfObject (wid); | |
| 1056 x_event->xbutton.window = XtWindowOfObject (wid); | |
| 1057 x_event->xbutton.root = XRootWindow (x_event->xbutton.display, 0); | |
| 1058 x_event->xbutton.subwindow = 0; | |
| 1059 x_event->xbutton.time = lisp_event->timestamp; | |
| 1060 x_event->xbutton.x = EVENT_BUTTON_X (lisp_event); | |
| 1061 x_event->xbutton.y = EVENT_BUTTON_Y (lisp_event); | |
| 1062 if (Success == XGetWindowAttributes (x_event->xbutton.display, | |
| 1063 x_event->xbutton.window, | |
| 1064 &win_attrib)) | |
| 1065 { | |
| 1066 x_event->xbutton.x_root = win_attrib.x + EVENT_BUTTON_X (lisp_event); | |
| 1067 x_event->xbutton.y_root = win_attrib.y + EVENT_BUTTON_Y (lisp_event); | |
| 1068 } | |
| 1069 else | |
| 1070 { | |
| 1071 x_event->xbutton.x_root = EVENT_BUTTON_X (lisp_event); /* this is wrong */ | |
| 1072 x_event->xbutton.y_root = EVENT_BUTTON_Y (lisp_event); | |
| 1073 } | |
| 1074 | |
| 1075 modifier = EVENT_BUTTON_MODIFIERS (lisp_event); | |
| 1076 if (modifier & XEMACS_MOD_SHIFT) state |= ShiftMask; | |
| 1077 if (modifier & XEMACS_MOD_CONTROL) state |= ControlMask; | |
| 1078 if (modifier & XEMACS_MOD_META) state |= xd->MetaMask; | |
| 1079 if (modifier & XEMACS_MOD_SUPER) state |= xd->SuperMask; | |
| 1080 if (modifier & XEMACS_MOD_HYPER) state |= xd->HyperMask; | |
| 1081 if (modifier & XEMACS_MOD_ALT) state |= xd->AltMask; | |
| 1082 state |= Button1Mask << (EVENT_BUTTON_BUTTON (lisp_event) - 1); | |
| 1083 | |
| 1084 x_event->xbutton.state = state; | |
| 1085 x_event->xbutton.button = EVENT_BUTTON_BUTTON (lisp_event); | |
| 1086 x_event->xbutton.same_screen = True; | |
| 1087 | |
| 1088 *wid_out = wid; | |
| 1089 return dnd_data; | |
| 1090 } | |
| 1091 | |
|
4790
bc4f2511bbea
Remove support for the OffiX drag-and-drop protocol. See xemacs-patches
Jerry James <james@xemacs.org>
parents:
4769
diff
changeset
|
1092 #endif /* defined (HAVE_CDE) */ |
| 2367 | 1093 |
| 428 | 1094 #ifdef HAVE_CDE |
| 1095 #include <Dt/Dt.h> | |
| 1096 #include <Dt/Dnd.h> | |
| 1097 | |
| 1098 static Widget CurrentDragWidget = NULL; | |
| 1099 static XtCallbackRec dnd_convert_cb_rec[2]; | |
| 1100 static XtCallbackRec dnd_destroy_cb_rec[2]; | |
| 1101 static int drag_not_done = 0; | |
| 1102 | |
| 1103 static void | |
| 1104 x_cde_destroy_callback (Widget widget, XtPointer clientData, | |
| 1105 XtPointer callData) | |
| 1106 { | |
| 1107 DtDndDragFinishCallbackStruct *dragFinishInfo = | |
| 2367 | 1108 (DtDndDragFinishCallbackStruct *) callData; |
| 428 | 1109 DtDndContext *dragData = dragFinishInfo->dragData; |
| 1110 int i; | |
| 1111 | |
| 1112 /* free the items */ | |
| 1113 if (callData != NULL && dragData != NULL) | |
| 1114 { | |
| 1115 if (dragData->protocol == DtDND_BUFFER_TRANSFER) | |
| 1116 { | |
| 1117 for (i = 0; i < dragData->numItems; i++) | |
| 1118 { | |
| 2367 | 1119 XtFree ((CRawbyte *) dragData->data.buffers[i].bp); |
| 428 | 1120 if (dragData->data.buffers[i].name) |
| 1121 XtFree(dragData->data.buffers[i].name); | |
| 1122 } | |
| 1123 } | |
| 1124 else | |
| 1125 { | |
| 1126 for (i = 0; i < dragData->numItems; i++) | |
| 1127 XtFree(dragData->data.files[i]); | |
| 1128 } | |
| 1129 } | |
| 1130 | |
| 1131 /* free the data string */ | |
| 1726 | 1132 xfree (clientData, XtPointer); |
| 428 | 1133 |
| 1134 CurrentDragWidget = NULL; | |
| 1135 } | |
| 1136 | |
| 1137 static void | |
| 1138 x_cde_convert_callback (Widget widget, XtPointer clientData, | |
| 1139 XtPointer callData) | |
| 1140 { | |
| 1141 DtDndConvertCallbackStruct *convertInfo = | |
| 1142 (DtDndConvertCallbackStruct *) callData; | |
| 2367 | 1143 Extbyte *textdata = (Extbyte *) clientData; |
| 1144 Extbyte *textptr = NULL; | |
| 428 | 1145 int i; |
| 1146 | |
| 1147 if (convertInfo == NULL) | |
| 1148 { | |
| 1149 return; | |
| 1150 } | |
| 1151 | |
| 1152 if ((convertInfo->dragData->protocol != DtDND_BUFFER_TRANSFER | |
| 1153 && convertInfo->dragData->protocol != DtDND_FILENAME_TRANSFER) || | |
| 1154 (convertInfo->reason != DtCR_DND_CONVERT_DATA)) | |
| 1155 { | |
| 1156 return; | |
| 1157 } | |
| 1158 | |
| 2367 | 1159 for (textptr = textdata, i = 0; |
| 1160 i < convertInfo->dragData->numItems; | |
| 1161 textptr += strlen (textptr) + 1, i++) | |
| 428 | 1162 { |
| 1163 if (convertInfo->dragData->protocol == DtDND_BUFFER_TRANSFER) | |
| 1164 { | |
| 2367 | 1165 convertInfo->dragData->data.buffers[i].bp = XtNewString (textptr); |
| 1166 convertInfo->dragData->data.buffers[i].size = strlen (textptr); | |
| 428 | 1167 convertInfo->dragData->data.buffers[i].name = NULL; |
| 1168 } | |
| 1169 else | |
| 1170 { | |
| 2367 | 1171 convertInfo->dragData->data.files[i] = XtNewString (textptr); |
| 428 | 1172 } |
| 1173 } | |
| 1174 | |
| 1175 convertInfo->status = DtDND_SUCCESS; | |
| 1176 } | |
| 1177 | |
| 1178 static Lisp_Object | |
| 2367 | 1179 abort_current_drag (Lisp_Object arg) |
| 428 | 1180 { |
| 1181 if (CurrentDragWidget && drag_not_done) | |
| 1182 { | |
| 1183 XmDragCancel(CurrentDragWidget); | |
| 1184 CurrentDragWidget = NULL; | |
| 1185 } | |
| 1186 return arg; | |
| 1187 } | |
| 1188 | |
| 1189 DEFUN ("cde-start-drag-internal", Fcde_start_drag_internal, 3, 3, 0, /* | |
| 1190 Start a CDE drag from a buffer. | |
| 1191 First argument is the event that started the drag (must be a | |
| 1192 button-press-event), | |
| 1193 second arg defines if the data should be treated as a buffer or | |
| 1194 a filename transfer (set to nil for buffer transfer), | |
| 1195 and the third argument is a list of data strings. | |
| 1196 WARNING: can only handle plain/text and file: transfers! | |
| 1197 */ | |
| 1198 (event, dragtype, dragdata)) | |
| 1199 { | |
| 2367 | 1200 Extbyte *dnd_data; |
| 1201 XEvent x_event; | |
| 1202 Bytecount dnd_len; | |
| 1203 Widget wid; | |
| 1204 int num_items; | |
| 1205 | |
| 1206 dnd_data = start_drag_internal_1 (event, dragdata, Qdt_dnd_encoding, | |
| 1207 &x_event, 1, | |
| 1208 &wid, &dnd_len, &num_items); | |
| 1209 | |
| 1210 dnd_convert_cb_rec[0].callback = x_cde_convert_callback; | |
| 1211 dnd_convert_cb_rec[0].closure = (XtPointer) dnd_data; | |
| 1212 dnd_convert_cb_rec[1].callback = NULL; | |
| 1213 dnd_convert_cb_rec[1].closure = NULL; | |
| 1214 | |
| 1215 dnd_destroy_cb_rec[0].callback = x_cde_destroy_callback; | |
| 1216 dnd_destroy_cb_rec[0].closure = (XtPointer) dnd_data; | |
| 1217 dnd_destroy_cb_rec[1].callback = NULL; | |
| 1218 dnd_destroy_cb_rec[1].closure = NULL; | |
| 1219 | |
| 1220 CurrentDragWidget = | |
| 1221 DtDndDragStart (wid, &x_event, | |
| 1222 (NILP (dragtype) ? DtDND_BUFFER_TRANSFER : | |
| 1223 DtDND_FILENAME_TRANSFER), | |
| 1224 num_items, | |
| 1225 XmDROP_COPY, | |
| 1226 dnd_convert_cb_rec, | |
| 1227 dnd_destroy_cb_rec, | |
| 1228 NULL, 0); | |
| 1229 | |
| 1230 xfree (dnd_data, Extbyte *); | |
| 1231 | |
| 1232 return num_items ? Qt : Qnil; | |
| 428 | 1233 } |
| 1234 | |
| 1235 static void | |
| 1236 x_cde_transfer_callback (Widget widget, XtPointer clientData, | |
| 1237 XtPointer callData) | |
| 1238 { | |
| 2367 | 1239 int ii, enqueue = 1; |
| 428 | 1240 Lisp_Object frame = Qnil; |
| 1241 Lisp_Object l_type = Qnil; | |
| 1242 Lisp_Object l_data = Qnil; | |
| 1243 DtDndTransferCallbackStruct *transferInfo = NULL; | |
| 1244 struct gcpro gcpro1, gcpro2, gcpro3; | |
| 1245 | |
| 1246 /* | |
| 1247 this needs to be changed to the new protocol: | |
| 1248 - we need the button, modifier and pointer states to create a | |
| 1249 correct misc_user_event | |
| 1250 - the data must be converted to the new format (URL/MIME) | |
| 1251 */ | |
| 1252 /* return; */ | |
| 1253 | |
| 1254 transferInfo = (DtDndTransferCallbackStruct *) callData; | |
| 1255 if (transferInfo == NULL) | |
| 1256 return; | |
| 1257 | |
| 1258 GCPRO3 (frame, l_type, l_data); | |
| 1259 | |
| 771 | 1260 frame = wrap_frame ((struct frame *) clientData); |
| 428 | 1261 |
| 1262 if (transferInfo->dropData->protocol == DtDND_FILENAME_TRANSFER) | |
| 1263 { | |
| 1264 l_type = Qdragdrop_URL; | |
| 1265 | |
| 1266 for (ii = 0; ii < transferInfo->dropData->numItems; ii++) | |
| 1267 { | |
| 2367 | 1268 Ibyte *fileint; |
| 1269 Ibyte *hurl; | |
| 1270 | |
| 1271 EXTERNAL_TO_C_STRING (transferInfo->dropData->data.files[ii], | |
| 1272 fileint, Qfile_name); | |
| 1273 | |
| 1274 hurl = dnd_url_hexify_string (fileint, "file:"); | |
| 1275 l_data = Fcons (build_intstring (hurl), l_data); | |
| 1276 xfree (hurl, Ibyte *); | |
| 428 | 1277 } |
| 1278 } | |
| 1279 else if (transferInfo->dropData->protocol == DtDND_BUFFER_TRANSFER) | |
| 1280 { | |
| 2367 | 1281 int speccount = specpdl_depth (); |
| 1282 | |
| 1283 /* !!#### Problem: all buffers a treated as text/plain!!! | |
| 1284 Not appropriate for intl text. Note that there is a function | |
| 1285 DtDtsBufferToDataType(), but I don't know what the possible | |
| 1286 return values are. | |
| 1287 Solution (?): Also support DtDND_TEXT_TRANSFER (compound text) | |
| 428 | 1288 perhaps implementation of the Motif protocol |
| 1289 (which is the base of CDE) will clear this */ | |
| 1290 l_type = Qdragdrop_MIME; | |
| 2367 | 1291 record_unwind_protect (abort_current_drag, Qnil); |
| 428 | 1292 drag_not_done = 1; |
| 1293 for (ii = 0; ii < transferInfo->dropData->numItems; ii++) | |
| 1294 { | |
| 1295 /* let us forget this name thing for now... */ | |
| 1296 /* filePath = transferInfo->dropData->data.buffers[ii].name; | |
| 1297 path = (filePath == NULL) ? Qnil | |
| 2367 | 1298 : build_ext_string (filePath, Q???); */ |
| 428 | 1299 /* what, if the data is no text, and how can I tell it? */ |
| 2367 | 1300 l_data = |
| 1301 Fcons (list3 (list1 (build_string ("text/plain")), | |
| 1302 build_string ("8bit"), | |
| 1303 make_ext_string | |
| 1304 (transferInfo->dropData->data.buffers[ii].bp, | |
| 1305 transferInfo->dropData->data.buffers[ii].size, | |
| 1306 /* !!#### what goes here? */ | |
| 1307 Qdt_dnd_encoding)), | |
| 1308 l_data); | |
| 428 | 1309 } |
| 1310 drag_not_done = 0; | |
| 771 | 1311 unbind_to (speccount); |
| 428 | 1312 } |
| 1313 else /* the other cases: NOOP_TRANSFER */ | |
| 2367 | 1314 enqueue = 0; |
| 428 | 1315 |
| 1316 /* The Problem: no button and mods from CDE... */ | |
| 1317 if (enqueue) | |
| 2367 | 1318 enqueue_misc_user_event_pos (frame, Qdragdrop_drop_dispatch, |
| 1319 Fcons (l_type, l_data), | |
| 1320 0 /* this is the button */, | |
| 1321 0 /* these are the mods */, | |
| 1322 transferInfo->x, | |
| 1323 transferInfo->y); | |
| 428 | 1324 |
| 1325 UNGCPRO; | |
| 1326 return; | |
| 1327 } | |
| 1328 #endif /* HAVE_CDE */ | |
| 1329 | |
| 1330 | |
| 1331 /************************************************************************/ | |
| 1332 /* widget creation */ | |
| 1333 /************************************************************************/ | |
| 1334 | |
| 1335 /* The widget hierarchy is | |
| 1336 | |
| 1337 argv[0] shell container FRAME-NAME | |
| 1338 ApplicationShell EmacsShell EmacsManager EmacsFrame | |
| 1339 | |
| 1340 We accept geometry specs in this order: | |
| 1341 | |
| 1342 *FRAME-NAME.geometry | |
| 1343 *EmacsFrame.geometry | |
| 1344 Emacs.geometry | |
| 1345 | |
| 1346 Other possibilities for widget hierarchies might be | |
| 1347 | |
| 1348 argv[0] frame container FRAME-NAME | |
| 1349 ApplicationShell EmacsShell EmacsManager EmacsFrame | |
| 1350 or | |
| 1351 argv[0] FRAME-NAME container FRAME-NAME | |
| 1352 ApplicationShell EmacsShell EmacsManager EmacsFrame | |
| 1353 or | |
| 1354 argv[0] FRAME-NAME container emacsTextPane | |
| 1355 ApplicationShell EmacsShell EmacsManager EmacsFrame | |
| 1356 | |
| 1357 #ifdef EXTERNAL_WIDGET | |
| 1358 The ExternalShell widget is simply a replacement for the Shell widget | |
| 1359 which is able to deal with using an externally-supplied window instead | |
| 1360 of always creating its own. | |
| 1361 #endif | |
| 1362 | |
| 1363 */ | |
| 1364 | |
| 1365 #ifdef EXTERNAL_WIDGET | |
| 1366 | |
| 1367 static int | |
| 1368 is_valid_window (Window w, struct device *d) | |
| 1369 { | |
| 1370 XWindowAttributes xwa; | |
| 1371 Display *dpy = DEVICE_X_DISPLAY (d); | |
| 1372 | |
| 1373 expect_x_error (dpy); | |
| 1374 XGetWindowAttributes (dpy, w, &xwa); | |
| 1375 return !x_error_occurred_p (dpy); | |
| 1376 } | |
| 1377 | |
| 1378 #endif /* EXTERNAL_WIDGET */ | |
| 1379 | |
| 1380 /* This sends a synthetic mouse-motion event to the frame, if the mouse | |
| 1381 is over the frame. This ensures that the cursor gets set properly | |
| 1382 before the user moves the mouse for the first time. */ | |
| 1383 | |
| 1384 static void | |
| 2286 | 1385 x_send_synthetic_mouse_event (struct frame *UNUSED (f)) |
| 428 | 1386 { |
| 1387 /* #### write this function. */ | |
| 1388 } | |
| 1389 | |
| 1390 static int | |
| 1391 first_x_frame_p (struct frame *f) | |
| 1392 { | |
| 1393 Lisp_Object rest = DEVICE_FRAME_LIST (XDEVICE (f->device)); | |
| 1394 while (!NILP (rest) && | |
| 1395 (f == XFRAME (XCAR (rest)) || | |
| 1396 !FRAME_X_P (XFRAME (XCAR (rest))))) | |
| 1397 rest = XCDR (rest); | |
| 1398 return NILP (rest); | |
| 1399 } | |
| 1400 | |
| 1401 /* Figure out what size the EmacsFrame widget should initially be, | |
| 1402 and set it. Should be called after the default font has been | |
| 1403 determined but before the widget has been realized. */ | |
| 1404 | |
| 1405 static void | |
| 1406 x_initialize_frame_size (struct frame *f) | |
| 1407 { | |
| 1408 /* Geometry of the AppShell */ | |
| 1409 int app_flags = 0; | |
| 1410 int app_x = 0; | |
| 1411 int app_y = 0; | |
| 1412 unsigned int app_w = 0; | |
| 1413 unsigned int app_h = 0; | |
| 1414 | |
| 1415 /* Geometry of the EmacsFrame */ | |
| 1416 int frame_flags = 0; | |
| 1417 int frame_x = 0; | |
| 1418 int frame_y = 0; | |
| 1419 unsigned int frame_w = 0; | |
| 1420 unsigned int frame_h = 0; | |
| 1421 | |
| 1422 /* Hairily merged geometry */ | |
| 1423 int x = 0; | |
| 1424 int y = 0; | |
| 1425 unsigned int w = 80; | |
| 1426 unsigned int h = 40; | |
| 1427 int flags = 0; | |
| 1428 | |
| 2367 | 1429 Ascbyte *geom = 0, *ew_geom = 0; |
| 428 | 1430 Boolean iconic_p = False, ew_iconic_p = False; |
| 1431 | |
| 1432 Widget wmshell = FRAME_X_SHELL_WIDGET (f); | |
| 1433 /* #### This may not be an ApplicationShell any more, with the 'popup | |
| 1434 frame property. */ | |
| 1435 Widget app_shell = XtParent (wmshell); | |
| 1436 Widget ew = FRAME_X_TEXT_WIDGET (f); | |
| 1437 | |
| 2747 | 1438 /* set the position of the frame's root window now. When the |
| 1439 frame was created, the position was initialized to (0,0). */ | |
| 428 | 1440 { |
| 1441 struct window *win = XWINDOW (f->root_window); | |
| 1442 | |
| 442 | 1443 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f) |
| 1444 + FRAME_LEFT_GUTTER_BOUNDS (f); | |
| 1445 WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f) | |
| 1446 + FRAME_TOP_GUTTER_BOUNDS (f); | |
| 428 | 1447 |
| 1448 if (!NILP (f->minibuffer_window)) | |
| 1449 { | |
| 1450 win = XWINDOW (f->minibuffer_window); | |
| 442 | 1451 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f) |
| 1452 + FRAME_LEFT_GUTTER_BOUNDS (f); | |
| 428 | 1453 } |
| 1454 } | |
| 1455 | |
| 1456 #ifdef EXTERNAL_WIDGET | |
| 1457 /* If we're an external widget, then the size of the frame is predetermined | |
| 1458 (by the client) and is not our decision to make. */ | |
| 1459 if (FRAME_X_EXTERNAL_WINDOW_P (f)) | |
| 1460 return; | |
| 1461 #endif | |
| 1462 | |
| 1463 #if 0 | |
| 1464 /* #### this junk has not been tested; therefore it's | |
| 1465 probably wrong. Doesn't really matter at this point because | |
| 1466 currently all frames are either top-level or external widgets. */ | |
| 1467 | |
| 1468 /* If we're not our own top-level window, then we shouldn't go messing around | |
| 1469 with top-level shells or "Emacs.geometry" or any such stuff. Therefore, | |
| 1470 we do as follows to determine the size of the frame: | |
| 1471 | |
| 1472 1) If a value for the frame's "geometry" resource was specified, then | |
| 1473 use it. (This specifies a size in characters.) | |
| 1474 2) Else, if the "width" and "height" resources were specified, then | |
| 1475 leave them alone. (This is a value in pixels. Sorry, we can't break | |
| 1476 Xt conventions here.) | |
| 1477 3) Else, assume a size of 64x12. (This is somewhat arbitrary, but | |
| 1478 it's unlikely that a size of 80x40 is desirable because we're probably | |
| 1479 inside of a dialog box.) | |
| 1480 | |
| 1481 Set the widget's x, y, height, and width as determined. Don't set the | |
| 1482 top-level container widget, because we don't necessarily know what it | |
| 1483 is. (Assume it is smart and pays attention to our values.) | |
| 1484 */ | |
| 1485 | |
| 1486 if (!FRAME_X_TOP_LEVEL_FRAME_P (f)) | |
| 1487 { | |
| 1488 Xt_GET_VALUE (ew, XtNgeometry, &ew_geom); | |
| 1489 if (ew_geom) | |
| 1490 frame_flags = XParseGeometry (ew_geom, | |
| 1491 &frame_x, &frame_y, | |
| 1492 &frame_w, &frame_h); | |
| 1493 if (! (frame_flags & (WidthValue | HeightValue))) | |
| 1494 { | |
| 1495 Arg al[2]; | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1496 Xt_SET_ARG (al [0], XtNwidth, &frame_w); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1497 Xt_SET_ARG (al [1], XtNheight, &frame_h); |
| 428 | 1498 XtGetValues (ew, al, 2); |
| 1499 if (!frame_w && !frame_h) | |
| 1500 { | |
| 1501 frame_w = 64; | |
| 1502 frame_h = 12; | |
| 1503 frame_flags |= WidthValue | HeightValue; | |
| 1504 } | |
| 1505 } | |
| 1506 if (frame_flags & (WidthValue | HeightValue)) | |
| 1507 EmacsFrameSetCharSize (ew, frame_w, frame_h); | |
| 1508 if (frame_flags & (XValue | YValue)) | |
| 1509 { | |
| 1510 Arg al[2]; | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1511 Xt_SET_ARG (al [0], XtNwidth, &frame_w); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1512 Xt_SET_ARG (al [1], XtNheight, &frame_h); |
| 428 | 1513 XtGetValues (ew, al, 2); |
| 1514 | |
| 1515 if (frame_flags & XNegative) | |
| 1516 frame_x += frame_w; | |
| 1517 if (frame_flags & YNegative) | |
| 1518 frame_y += frame_h; | |
| 1519 | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1520 Xt_SET_ARG (al [0], XtNx, frame_x); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1521 Xt_SET_ARG (al [1], XtNy, frame_y); |
| 428 | 1522 XtSetValues (ew, al, 2); |
| 1523 } | |
| 1524 return; | |
| 1525 } | |
| 1526 #endif | |
| 1527 | |
| 1528 /* OK, we're a top-level shell. */ | |
| 1529 | |
| 1530 if (!XtIsWMShell (wmshell)) | |
| 2500 | 1531 ABORT (); |
| 428 | 1532 |
| 1533 /* If the EmacsFrame doesn't have a geometry but the shell does, | |
| 1534 treat that as the geometry of the frame. | |
| 1535 (Is this bogus? I'm not sure.) */ | |
| 1536 | |
| 1537 Xt_GET_VALUE (ew, XtNgeometry, &ew_geom); | |
| 1538 if (!ew_geom) | |
| 1539 { | |
| 1540 Xt_GET_VALUE (wmshell, XtNgeometry, &geom); | |
| 1541 if (geom) | |
| 1542 { | |
| 1543 ew_geom = geom; | |
| 1544 Xt_SET_VALUE (ew, XtNgeometry, ew_geom); | |
| 1545 } | |
| 1546 } | |
| 1547 | |
| 1548 /* If the Shell is iconic, then the EmacsFrame is iconic. | |
| 1549 (Is this bogus? I'm not sure.) */ | |
| 1550 Xt_GET_VALUE (ew, XtNiconic, &ew_iconic_p); | |
| 1551 if (!ew_iconic_p) | |
| 1552 { | |
| 1553 Xt_GET_VALUE (wmshell, XtNiconic, &iconic_p); | |
| 1554 if (iconic_p) | |
| 1555 { | |
| 1556 ew_iconic_p = iconic_p; | |
| 1557 Xt_SET_VALUE (ew, XtNiconic, iconic_p); | |
| 1558 } | |
| 1559 } | |
| 1560 | |
| 1561 Xt_GET_VALUE (app_shell, XtNgeometry, &geom); | |
| 1562 if (geom) | |
| 1563 app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h); | |
| 1564 | |
| 1565 if (ew_geom) | |
| 1566 frame_flags = XParseGeometry (ew_geom, | |
| 1567 &frame_x, &frame_y, | |
| 1568 &frame_w, &frame_h); | |
| 1569 | |
| 1570 if (first_x_frame_p (f)) | |
| 1571 { | |
| 1572 /* If this is the first frame created: | |
| 1573 ==================================== | |
| 1574 | |
| 1575 - Use the ApplicationShell's size/position, if specified. | |
| 1576 (This is "Emacs.geometry", or the "-geometry" command line arg.) | |
| 1577 - Else use the EmacsFrame's size/position. | |
| 1578 (This is "*FRAME-NAME.geometry") | |
| 1579 | |
| 1580 - If the AppShell is iconic, the frame should be iconic. | |
| 1581 | |
| 1582 AppShell comes first so that -geometry always applies to the first | |
| 1583 frame created, even if there is an "every frame" entry in the | |
| 1584 resource database. | |
| 1585 */ | |
| 1586 if (app_flags & (XValue | YValue)) | |
| 1587 { | |
| 1588 x = app_x; y = app_y; | |
| 1589 flags |= (app_flags & (XValue | YValue | XNegative | YNegative)); | |
| 1590 } | |
| 1591 else if (frame_flags & (XValue | YValue)) | |
| 1592 { | |
| 1593 x = frame_x; y = frame_y; | |
| 1594 flags |= (frame_flags & (XValue | YValue | XNegative | YNegative)); | |
| 1595 } | |
| 1596 | |
| 1597 if (app_flags & (WidthValue | HeightValue)) | |
| 1598 { | |
| 1599 w = app_w; h = app_h; | |
| 1600 flags |= (app_flags & (WidthValue | HeightValue)); | |
| 1601 } | |
| 1602 else if (frame_flags & (WidthValue | HeightValue)) | |
| 1603 { | |
| 1604 w = frame_w; h = frame_h; | |
| 1605 flags |= (frame_flags & (WidthValue | HeightValue)); | |
| 1606 } | |
| 1607 | |
| 1608 /* If the AppShell is iconic, then the EmacsFrame is iconic. */ | |
| 1609 if (!ew_iconic_p) | |
| 1610 { | |
| 1611 Xt_GET_VALUE (app_shell, XtNiconic, &iconic_p); | |
| 1612 if (iconic_p) | |
| 1613 { | |
| 1614 ew_iconic_p = iconic_p; | |
| 1615 Xt_SET_VALUE (ew, XtNiconic, iconic_p); | |
| 1616 } | |
| 1617 } | |
| 1618 } | |
| 1619 else | |
| 1620 { | |
| 1621 /* If this is not the first frame created: | |
| 1622 ======================================== | |
| 1623 | |
| 1624 - use the EmacsFrame's size/position if specified | |
| 1625 - Otherwise, use the ApplicationShell's size, but not position. | |
| 1626 | |
| 1627 So that means that one can specify the position of the first frame | |
| 1628 with "Emacs.geometry" or `-geometry'; but can only specify the | |
| 1629 position of subsequent frames with "*FRAME-NAME.geometry". | |
| 1630 | |
| 1631 AppShell comes second so that -geometry does not apply to subsequent | |
| 1632 frames when there is an "every frame" entry in the resource db, | |
| 1633 but does apply to the first frame. | |
| 1634 */ | |
| 1635 if (frame_flags & (XValue | YValue)) | |
| 1636 { | |
| 1637 x = frame_x; y = frame_y; | |
| 1638 flags |= (frame_flags & (XValue | YValue | XNegative | YNegative)); | |
| 1639 } | |
| 1640 | |
| 1641 if (frame_flags & (WidthValue | HeightValue)) | |
| 1642 { | |
| 1643 w = frame_w; h = frame_h; | |
| 1644 flags |= (frame_flags & (WidthValue | HeightValue)); | |
| 1645 } | |
| 1646 else if (app_flags & (WidthValue | HeightValue)) | |
| 1647 { | |
| 1648 w = app_w; | |
| 1649 h = app_h; | |
| 1650 flags |= (app_flags & (WidthValue | HeightValue)); | |
| 1651 } | |
| 1652 } | |
| 1653 | |
| 1654 x_set_initial_frame_size (f, flags, x, y, w, h); | |
| 1655 } | |
| 1656 | |
| 1657 static void | |
| 1658 x_get_layout_sizes (struct frame *f, Dimension *topbreadth) | |
| 1659 { | |
| 1660 int i; | |
| 1661 | |
| 1662 /* compute height of all top-area widgets */ | |
| 1663 for (i=0, *topbreadth = 0; i<FRAME_X_NUM_TOP_WIDGETS (f); i++) | |
| 1664 { | |
| 1665 Widget wid = FRAME_X_TOP_WIDGETS (f)[i]; | |
| 1666 if (wid && XtIsManaged (wid)) | |
| 1667 *topbreadth += wid->core.height + 2*wid->core.border_width; | |
| 1668 } | |
| 1669 } | |
| 1670 | |
| 1671 static void | |
| 2286 | 1672 x_layout_widgets (Widget UNUSED (w), XtPointer client_data, |
| 1673 XtPointer call_data) | |
| 428 | 1674 { |
| 1675 struct frame *f = (struct frame *) client_data; | |
| 1676 EmacsManagerResizeStruct *emst = (EmacsManagerResizeStruct *) call_data; | |
| 1677 Dimension width = emst->width; | |
| 1678 Dimension height = emst->height; | |
| 1679 Widget text = FRAME_X_TEXT_WIDGET (f); | |
| 1680 Dimension textbord = text->core.border_width; | |
| 1681 Dimension topbreadth; | |
| 1682 Position text_x = 0, text_y = 0; | |
| 1683 int i; | |
| 1684 | |
| 1685 x_get_layout_sizes (f, &topbreadth); | |
| 1686 | |
| 1687 /* first the menubar and psheets ... */ | |
| 1688 for (i=0; i<FRAME_X_NUM_TOP_WIDGETS (f); i++) | |
| 1689 { | |
| 1690 Widget wid = FRAME_X_TOP_WIDGETS (f)[i]; | |
| 1691 if (wid && XtIsManaged (wid)) | |
| 1692 { | |
| 1693 Dimension bord = wid->core.border_width; | |
| 1694 XtConfigureWidget (wid, 0, text_y, | |
| 1695 width - 2*bord, wid->core.height, | |
| 1696 bord); | |
| 1697 text_y += wid->core.height + 2*bord; | |
| 1698 } | |
| 1699 } | |
| 1700 | |
| 1701 #ifdef HAVE_SCROLLBARS | |
| 1702 f->scrollbar_y_offset = topbreadth + textbord; | |
| 1703 #endif | |
| 1704 | |
| 1705 /* finally the text area */ | |
| 1706 XtConfigureWidget (text, text_x, text_y, | |
| 1707 width - 2*textbord, | |
| 1708 height - text_y - 2*textbord, | |
| 1709 textbord); | |
| 1710 } | |
| 1711 | |
| 1712 static void | |
| 2286 | 1713 x_do_query_geometry (Widget UNUSED (w), XtPointer client_data, |
| 1714 XtPointer call_data) | |
| 428 | 1715 { |
| 1716 struct frame *f = (struct frame *) client_data; | |
| 1717 EmacsManagerQueryGeometryStruct *emst = | |
| 1718 (EmacsManagerQueryGeometryStruct *) call_data; | |
| 1719 Widget text = FRAME_X_TEXT_WIDGET (f); | |
| 1720 Dimension textbord = text->core.border_width; | |
| 1721 Dimension topbreadth; | |
| 1722 XtWidgetGeometry req, repl; | |
| 1723 int mask = emst->request_mode & (CWWidth | CWHeight); | |
| 1724 | |
| 1725 x_get_layout_sizes (f, &topbreadth); | |
| 1726 | |
| 1727 /* Strip away menubar from suggested size, and ask the text widget | |
| 1728 what size it wants to be. */ | |
| 1729 req.request_mode = mask; | |
| 1730 if (mask & CWWidth) | |
| 1731 req.width = emst->proposed_width - 2*textbord; | |
| 1732 if (mask & CWHeight) | |
| 1733 req.height = emst->proposed_height - topbreadth - 2*textbord; | |
| 1734 XtQueryGeometry (text, &req, &repl); | |
| 1735 | |
| 1736 /* Now add the menubar back again */ | |
| 1737 emst->proposed_width = repl.width + 2*textbord; | |
| 1738 emst->proposed_height = repl.height + topbreadth + 2*textbord; | |
| 1739 } | |
| 1740 | |
| 1741 /* Creates the widgets for a frame. | |
| 1742 lisp_window_id is a Lisp description of an X window or Xt | |
| 1743 widget to parse. | |
| 2747 | 1744 parent is a frame to use as the parent. |
| 1745 overridep if non-nil says to set the override-redirect setting. | |
| 428 | 1746 |
| 1747 This function does not create or map the windows. (That is | |
| 1748 done by x_popup_frame().) | |
| 1749 */ | |
| 1750 static void | |
| 1751 x_create_widgets (struct frame *f, Lisp_Object lisp_window_id, | |
| 2747 | 1752 Lisp_Object parent, Lisp_Object overridep) |
| 428 | 1753 { |
| 1754 struct device *d = XDEVICE (f->device); | |
| 1755 Visual *visual = DEVICE_X_VISUAL (d); | |
| 1756 int depth = DEVICE_X_DEPTH (d); | |
| 1757 Colormap cmap = DEVICE_X_COLORMAP (d); | |
| 1758 #ifdef EXTERNAL_WIDGET | |
| 1759 Window window_id = 0; | |
| 1760 #endif | |
| 2367 | 1761 const Extbyte *name; |
| 1762 Arg al[25]; | |
| 428 | 1763 int ac = 0; |
| 1764 Widget text, container, shell; | |
| 1765 Widget parentwid = 0; | |
| 1766 #ifdef HAVE_MENUBARS | |
| 1767 int menubar_visible; | |
| 1768 Widget menubar; | |
| 1769 #endif | |
| 1770 | |
| 1771 if (STRINGP (f->name)) | |
| 442 | 1772 LISP_STRING_TO_EXTERNAL (f->name, name, Qctext); |
| 428 | 1773 else |
| 1774 name = "emacs"; | |
| 1775 | |
| 1776 /* The widget hierarchy is | |
| 1777 | |
| 1778 argv[0] shell pane FRAME-NAME | |
| 1779 ApplicationShell EmacsShell EmacsManager EmacsFrame | |
| 1780 | |
| 1781 (the type of the shell is ExternalShell if this frame is running | |
| 1782 in another client's window) | |
| 1783 | |
| 1784 However the EmacsShell widget has WM_CLASS of FRAME-NAME/Emacs. | |
| 1785 Normally such shells have name/class shellname/appclass, which in this | |
| 1786 case would be "shell/Emacs" instead of "frame-name/Emacs". We could | |
| 1787 also get around this by naming the shell "frame-name", but that would | |
| 1788 be confusing because the text area (the EmacsFrame widget inferior of | |
| 1789 the shell) is also called that. So we just set the WM_CLASS property. | |
| 1790 */ | |
| 1791 | |
| 1792 #ifndef EXTERNAL_WIDGET | |
| 1793 if (!NILP (lisp_window_id)) | |
| 2367 | 1794 signal_error |
| 1795 (Qunimplemented, | |
| 1796 "support for external widgets was not enabled at compile-time", | |
| 1797 Qunbound); | |
| 428 | 1798 #else |
| 1799 if (!NILP (lisp_window_id)) | |
| 1800 { | |
| 2367 | 1801 Ibyte *string; |
| 428 | 1802 |
| 1803 CHECK_STRING (lisp_window_id); | |
| 2367 | 1804 string = XSTRING_DATA (lisp_window_id); |
| 428 | 1805 if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X')) |
| 2367 | 1806 qxesscanf_ascii_1 (string + 2, "%lxu", &window_id); |
| 428 | 1807 #if 0 |
| 1808 else if (string[0] == 'w') | |
| 1809 { | |
| 2367 | 1810 qxesscanf_ascii (string + 1, "%x", &parent_widget); |
| 428 | 1811 if (parent_widget) |
| 1812 window_id = XtWindow (parent_widget); | |
| 1813 } | |
| 1814 #endif | |
| 1815 else | |
| 2367 | 1816 qxesscanf_ascii_1 (string, "%lu", &window_id); |
| 428 | 1817 if (!is_valid_window (window_id, d)) |
| 563 | 1818 signal_ferror (Qinvalid_argument, "Invalid window %lu", |
| 1819 (unsigned long) window_id); | |
| 428 | 1820 FRAME_X_EXTERNAL_WINDOW_P (f) = 1; |
| 1821 } else | |
| 1822 #endif /* EXTERNAL_WIDGET */ | |
| 1823 FRAME_X_TOP_LEVEL_FRAME_P (f) = 1; | |
| 1824 | |
| 1825 ac = 0; | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1826 Xt_SET_ARG (al[ac], XtNallowShellResize, True); ac++; |
| 428 | 1827 #ifdef LWLIB_USES_MOTIF |
| 1828 /* Motif sucks beans. Without this in here, it will delete the window | |
| 1829 out from under us when it receives a WM_DESTROY_WINDOW message | |
| 1830 from the WM. */ | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1831 Xt_SET_ARG (al[ac], XmNdeleteResponse, XmDO_NOTHING); ac++; |
| 428 | 1832 #endif |
| 1833 | |
| 1834 #ifdef EXTERNAL_WIDGET | |
| 1835 if (window_id) | |
| 1836 { | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1837 Xt_SET_ARG (al[ac], XtNwindow, window_id); ac++; |
| 428 | 1838 } |
| 1839 else | |
| 1840 #endif /* EXTERNAL_WIDGET */ | |
| 1841 { | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1842 Xt_SET_ARG (al[ac], XtNinput, True); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1843 Xt_SET_ARG (al[ac], XtNminWidthCells, 10); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1844 Xt_SET_ARG (al[ac], XtNminHeightCells, 1); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1845 Xt_SET_ARG (al[ac], XtNvisual, visual); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1846 Xt_SET_ARG (al[ac], XtNdepth, depth); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1847 Xt_SET_ARG (al[ac], XtNcolormap, cmap); ac++; |
| 428 | 1848 } |
| 1849 | |
| 2747 | 1850 if (!NILP (overridep)) |
| 1851 { | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1852 Xt_SET_ARG (al[ac], XtNoverrideRedirect, True); ac++; |
| 2747 | 1853 } |
| 1854 | |
| 1855 /* #### maybe we should check for FRAMEP instead? */ | |
| 428 | 1856 if (!NILP (parent)) |
| 1857 { | |
| 1858 parentwid = FRAME_X_SHELL_WIDGET (XFRAME (parent)); | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1859 Xt_SET_ARG (al[ac], XtNtransientFor, parentwid); ac++; |
| 428 | 1860 } |
| 1861 | |
| 1862 shell = XtCreatePopupShell ("shell", | |
| 1863 ( | |
| 1864 #ifdef EXTERNAL_WIDGET | |
| 1865 window_id ? externalShellWidgetClass : | |
| 1866 #endif | |
| 1867 parentwid ? transientEmacsShellWidgetClass : | |
| 1868 topLevelEmacsShellWidgetClass | |
| 1869 ), | |
| 1870 parentwid ? parentwid : | |
| 1871 DEVICE_XT_APP_SHELL (d), | |
| 1872 al, ac); | |
| 1873 FRAME_X_SHELL_WIDGET (f) = shell; | |
| 1874 maybe_set_frame_title_format (shell); | |
| 1875 | |
| 1876 /* Create the manager widget */ | |
| 1877 ac = 0; | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1878 Xt_SET_ARG (al[ac], XtNvisual, visual); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1879 Xt_SET_ARG (al[ac], XtNdepth, depth); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1880 Xt_SET_ARG (al[ac], XtNcolormap, cmap); ac++; |
| 428 | 1881 |
| 1882 container = XtCreateWidget ("container", | |
| 1883 emacsManagerWidgetClass, shell, al, ac); | |
| 1884 FRAME_X_CONTAINER_WIDGET (f) = container; | |
| 1885 XtAddCallback (container, XtNresizeCallback, x_layout_widgets, | |
| 1886 (XtPointer) f); | |
| 1887 XtAddCallback (container, XtNqueryGeometryCallback, x_do_query_geometry, | |
| 1888 (XtPointer) f); | |
| 1889 | |
| 1890 /* Create the text area */ | |
| 1891 ac = 0; | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1892 Xt_SET_ARG (al[ac], XtNvisual, visual); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1893 Xt_SET_ARG (al[ac], XtNdepth, depth); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1894 Xt_SET_ARG (al[ac], XtNcolormap, cmap); ac++; |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1895 Xt_SET_ARG (al[ac], XtNborderWidth, 0); ac++; /* should this be settable? */ |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
1896 Xt_SET_ARG (al[ac], XtNemacsFrame, f); ac++; |
| 428 | 1897 text = XtCreateWidget (name, emacsFrameClass, container, al, ac); |
| 1898 FRAME_X_TEXT_WIDGET (f) = text; | |
| 1899 | |
| 1900 #ifdef HAVE_MENUBARS | |
| 1901 /* Create the initial menubar widget. */ | |
| 1902 menubar_visible = x_initialize_frame_menubar (f); | |
| 1903 FRAME_X_TOP_WIDGETS (f)[0] = menubar = FRAME_X_MENUBAR_WIDGET (f); | |
| 1904 FRAME_X_NUM_TOP_WIDGETS (f) = 1; | |
| 1905 | |
| 1906 if (menubar_visible) | |
| 1907 XtManageChild (menubar); | |
| 1908 #endif /* HAVE_MENUBARS */ | |
| 1909 XtManageChild (text); | |
| 1910 XtManageChild (container); | |
| 1911 } | |
| 1912 | |
| 1913 /* We used to call XtPopup() in x_popup_frame, but that doesn't give | |
| 1914 you control over whether the widget is initially mapped or not | |
| 1915 because XtPopup() makes an unconditional call to XMapRaised(). | |
| 1916 Boy, those Xt designers were clever. | |
| 1917 | |
| 1918 When we first removed it we only kept the XtRealizeWidget call in | |
| 1919 XtPopup. For everything except HP's that was enough. For HP's, | |
| 1920 though, the failure to call the popup callbacks resulted in XEmacs | |
| 1921 not accepting any input. Bizarre but true. Stupid but true. | |
| 1922 | |
| 1923 So, in case there are any other gotchas floating out there along | |
| 1924 the same lines I've duplicated the majority of XtPopup here. It | |
| 1925 assumes no grabs and that the widget is not already popped up, both | |
| 1926 valid assumptions for the one place this is called from. */ | |
| 1927 static void | |
| 1928 xemacs_XtPopup (Widget widget) | |
| 1929 { | |
| 1930 ShellWidget shell_widget = (ShellWidget) widget; | |
| 1931 XtGrabKind call_data = XtGrabNone; | |
| 1932 | |
| 2367 | 1933 XtCallCallbacks (widget, XtNpopupCallback, (XtPointer) &call_data); |
| 428 | 1934 |
| 1935 shell_widget->shell.popped_up = TRUE; | |
| 1936 shell_widget->shell.grab_kind = XtGrabNone; | |
| 1937 shell_widget->shell.spring_loaded = False; | |
| 1938 | |
| 1939 if (shell_widget->shell.create_popup_child_proc != NULL) | |
| 2367 | 1940 (*(shell_widget->shell.create_popup_child_proc)) (widget); |
| 428 | 1941 |
| 1942 /* The XtSetValues below are not in XtPopup menu. We just want to | |
| 1943 make absolutely sure... */ | |
| 1944 Xt_SET_VALUE (widget, XtNmappedWhenManaged, False); | |
| 1945 XtRealizeWidget (widget); | |
| 1946 Xt_SET_VALUE (widget, XtNmappedWhenManaged, True); | |
| 1947 } | |
| 1948 | |
| 1949 /* create the windows for the specified frame and display them. | |
| 1950 Note that the widgets have already been created, and any | |
| 1951 necessary geometry calculations have already been done. */ | |
| 1952 static void | |
| 1953 x_popup_frame (struct frame *f) | |
| 1954 { | |
| 1955 Widget shell_widget = FRAME_X_SHELL_WIDGET (f); | |
| 1956 Widget frame_widget = FRAME_X_TEXT_WIDGET (f); | |
| 1957 struct device *d = XDEVICE (FRAME_DEVICE (f)); | |
| 1958 | |
| 1959 /* Before mapping the window, make sure that the WMShell's notion of | |
| 1960 whether it should be iconified is synchronized with the EmacsFrame's | |
| 1961 notion. | |
| 1962 */ | |
| 1963 if (FRAME_X_TOP_LEVEL_FRAME_P (f)) | |
| 1964 x_wm_set_shell_iconic_p (shell_widget, | |
| 1965 ((EmacsFrame) frame_widget) | |
| 1966 ->emacs_frame.iconic); | |
| 1967 | |
| 1968 xemacs_XtPopup (shell_widget); | |
| 1969 | |
| 1970 if (!((EmacsFrame) frame_widget)->emacs_frame.initially_unmapped) | |
| 1971 XtMapWidget (shell_widget); | |
| 1972 else | |
| 1973 { | |
| 1974 /* We may have set f->visible to 1 in x_init_frame(), so undo | |
| 1975 that now. */ | |
| 1976 FRAME_X_TOTALLY_VISIBLE_P (f) = 0; | |
| 1977 f->visible = 0; | |
| 1978 } | |
| 1979 | |
| 1980 #ifdef EXTERNAL_WIDGET | |
| 1981 if (FRAME_X_EXTERNAL_WINDOW_P (f)) | |
| 1982 ExternalShellReady (shell_widget, XtWindow (frame_widget), KeyPressMask); | |
| 1983 else | |
| 1984 #endif | |
| 1985 if (FRAME_X_TOP_LEVEL_FRAME_P (f)) | |
| 1986 { | |
| 1987 /* tell the window manager about us. */ | |
| 1988 x_wm_store_class_hints (shell_widget, XtName (frame_widget)); | |
| 1989 | |
| 1990 #ifndef HAVE_WMCOMMAND | |
| 1991 x_wm_maybe_store_wm_command (f); | |
| 1992 #endif /* HAVE_WMCOMMAND */ | |
| 1993 | |
| 1994 x_wm_hack_wm_protocols (shell_widget); | |
| 1995 } | |
| 1996 | |
| 1997 #ifdef HAVE_XIM | |
| 1998 XIM_init_frame (f); | |
| 1999 #endif /* HAVE_XIM */ | |
| 2000 | |
| 2001 /* Allow XEmacs to respond to EditRes requests. See the O'Reilly Xt */ | |
| 2002 /* Intrinsics Programming Manual, Motif Edition, Aug 1993, Sect 14.14, */ | |
| 2003 /* pp. 483-493. */ | |
| 2004 XtAddEventHandler (shell_widget, /* the shell widget in question */ | |
| 2005 (EventMask) NoEventMask,/* OR with existing mask */ | |
| 2006 True, /* called on non-maskable events? */ | |
| 2007 (XtEventHandler) _XEditResCheckMessages, /* the handler */ | |
| 2008 NULL); | |
| 2009 | |
| 2010 #ifdef HAVE_CDE | |
| 2011 { | |
| 2012 XtCallbackRec dnd_transfer_cb_rec[2]; | |
| 2013 | |
| 2014 dnd_transfer_cb_rec[0].callback = x_cde_transfer_callback; | |
| 2015 dnd_transfer_cb_rec[0].closure = (XtPointer) f; | |
| 2016 dnd_transfer_cb_rec[1].callback = NULL; | |
| 2017 dnd_transfer_cb_rec[1].closure = NULL; | |
| 2018 | |
| 2019 DtDndVaDropRegister (FRAME_X_TEXT_WIDGET (f), | |
| 2020 DtDND_FILENAME_TRANSFER | DtDND_BUFFER_TRANSFER, | |
| 2021 XmDROP_COPY, dnd_transfer_cb_rec, | |
| 2022 DtNtextIsBuffer, True, | |
| 2023 DtNregisterChildren, True, | |
| 2024 DtNpreserveRegistration, False, | |
| 2025 NULL); | |
| 2026 } | |
| 2027 #endif /* HAVE_CDE */ | |
| 2028 | |
| 2029 /* Do a stupid property change to force the server to generate a | |
| 2030 propertyNotify event so that the event_stream server timestamp will | |
| 2031 be initialized to something relevant to the time we created the window. | |
| 2032 */ | |
| 2033 XChangeProperty (XtDisplay (frame_widget), XtWindow (frame_widget), | |
| 2034 DEVICE_XATOM_WM_PROTOCOLS (d), XA_ATOM, 32, PropModeAppend, | |
| 2367 | 2035 (Rawbyte *) NULL, 0); |
| 428 | 2036 |
| 2037 x_send_synthetic_mouse_event (f); | |
| 2038 } | |
| 2039 | |
| 2040 static void | |
| 2041 allocate_x_frame_struct (struct frame *f) | |
| 2042 { | |
| 2043 /* zero out all slots. */ | |
| 3092 | 2044 #ifdef NEW_GC |
|
5120
d1247f3cc363
latest work on lisp-object workspace;
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
2045 f->frame_data = XX_FRAME (ALLOC_LISP_OBJECT (x_frame)); |
| 3092 | 2046 #else /* not NEW_GC */ |
| 428 | 2047 f->frame_data = xnew_and_zero (struct x_frame); |
| 3092 | 2048 #endif /* not NEW_GC */ |
| 428 | 2049 |
| 2050 /* yeah, except the lisp ones */ | |
| 1346 | 2051 FRAME_X_LAST_MENUBAR_BUFFER (f) = Qnil; |
| 428 | 2052 FRAME_X_ICON_PIXMAP (f) = Qnil; |
| 2053 FRAME_X_ICON_PIXMAP_MASK (f) = Qnil; | |
| 2054 } | |
| 2055 | |
| 2056 | |
| 2057 /************************************************************************/ | |
| 2058 /* Lisp functions */ | |
| 2059 /************************************************************************/ | |
| 2060 | |
| 2061 static void | |
| 771 | 2062 x_init_frame_1 (struct frame *f, Lisp_Object props, |
| 2286 | 2063 int UNUSED (frame_name_is_defaulted)) |
| 428 | 2064 { |
| 2065 /* This function can GC */ | |
| 2066 Lisp_Object device = FRAME_DEVICE (f); | |
| 2067 Lisp_Object lisp_window_id = Fplist_get (props, Qwindow_id, Qnil); | |
| 2068 Lisp_Object popup = Fplist_get (props, Qpopup, Qnil); | |
| 2747 | 2069 Lisp_Object overridep = Fplist_get (props, Qoverride_redirect, Qnil); |
| 428 | 2070 |
| 2071 if (!NILP (popup)) | |
| 2072 { | |
| 2073 if (EQ (popup, Qt)) | |
| 2074 popup = Fselected_frame (device); | |
| 2075 CHECK_LIVE_FRAME (popup); | |
| 2076 if (!EQ (device, FRAME_DEVICE (XFRAME (popup)))) | |
| 563 | 2077 invalid_argument_2 ("Parent must be on same device as frame", |
| 2078 device, popup); | |
| 428 | 2079 } |
| 2080 | |
| 2081 /* | |
| 2082 * Previously we set this only if NILP (DEVICE_SELECTED_FRAME (d)) | |
| 2083 * to make sure that messages were displayed as soon as possible | |
| 2084 * if we're creating the first frame on a device. But it is | |
| 2085 * better to just set this all the time, so that when a new frame | |
| 2086 * is created that covers the selected frame, echo area status | |
| 2087 * messages can still be seen. f->visible is reset later if the | |
| 2088 * initially-unmapped property is found to be non-nil in the | |
| 2089 * frame properties. | |
| 2090 */ | |
| 2091 f->visible = 1; | |
| 2092 | |
| 2093 allocate_x_frame_struct (f); | |
| 2747 | 2094 x_create_widgets (f, lisp_window_id, popup, overridep); |
| 428 | 2095 } |
| 2096 | |
| 2097 static void | |
| 2286 | 2098 x_init_frame_2 (struct frame *f, Lisp_Object UNUSED (props)) |
| 428 | 2099 { |
| 2100 /* Set up the values of the widget/frame. A case could be made for putting | |
| 2101 this inside of the widget's initialize method. */ | |
| 2102 | |
| 2103 update_frame_face_values (f); | |
| 2104 x_initialize_frame_size (f); | |
| 2105 /* Kyle: | |
| 2106 * update_frame_title() can't be done here, because some of the | |
| 2107 * modeline specs depend on the frame's device having a selected | |
| 2108 * frame, and that may not have been set up yet. The redisplay | |
| 2109 * will update the frame title anyway, so nothing is lost. | |
| 2110 * JV: | |
| 2111 * It turns out it gives problems with FVWMs name based mapping. | |
| 2112 * We'll just need to be careful in the modeline specs. | |
| 2113 */ | |
| 2114 update_frame_title (f); | |
|
4593
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2115 /* Henry S. Thompson: |
|
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2116 * Must set icon resource before mapping frame, or some WMs may |
|
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2117 * lose the icon (openbox). See <f5bhc3efb17@hildegard.inf.ed.ac.uk>. |
|
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2118 * SJT: |
|
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2119 * This probably means that the frame-icon library won't work with |
| 4594 | 2120 * that WM. Late breaking news: it *does* work, so possibly the |
| 2121 * problem at initialization is due to a race condition. | |
|
4593
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2122 */ |
|
3623446b34bc
Set icon resource on frame early enough for openbox to find it.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4528
diff
changeset
|
2123 update_frame_icon (f); |
| 428 | 2124 } |
| 2125 | |
| 2126 static void | |
| 2127 x_init_frame_3 (struct frame *f) | |
| 2128 { | |
| 2129 /* Pop up the frame. */ | |
| 2130 | |
| 2131 x_popup_frame (f); | |
| 2132 } | |
| 2133 | |
| 2134 static void | |
| 2135 x_mark_frame (struct frame *f) | |
| 2136 { | |
| 1346 | 2137 mark_object (FRAME_X_LAST_MENUBAR_BUFFER (f)); |
| 428 | 2138 mark_object (FRAME_X_ICON_PIXMAP (f)); |
| 2139 mark_object (FRAME_X_ICON_PIXMAP_MASK (f)); | |
| 2140 } | |
| 2141 | |
| 2142 static void | |
| 2143 x_set_frame_icon (struct frame *f) | |
| 2144 { | |
| 2145 Pixmap x_pixmap, x_mask; | |
| 2146 | |
| 2147 if (IMAGE_INSTANCEP (f->icon) | |
| 2148 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon))) | |
| 2149 { | |
| 2150 x_pixmap = XIMAGE_INSTANCE_X_PIXMAP (f->icon); | |
| 2151 x_mask = XIMAGE_INSTANCE_X_MASK (f->icon); | |
| 2152 } | |
| 2153 else | |
| 2154 { | |
| 2155 x_pixmap = 0; | |
| 2156 x_mask = 0; | |
| 2157 } | |
| 2158 | |
| 2159 /* Store the X data into the widget. */ | |
| 2160 { | |
| 2367 | 2161 Arg al[2]; |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2162 Xt_SET_ARG (al[0], XtNiconPixmap, x_pixmap); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2163 Xt_SET_ARG (al[1], XtNiconMask, x_mask); |
| 428 | 2164 XtSetValues (FRAME_X_SHELL_WIDGET (f), al, 2); |
| 2165 } | |
| 2166 } | |
| 2167 | |
| 2168 static void | |
| 2169 x_set_frame_pointer (struct frame *f) | |
| 2170 { | |
| 2171 XDefineCursor (XtDisplay (FRAME_X_TEXT_WIDGET (f)), | |
| 2172 XtWindow (FRAME_X_TEXT_WIDGET (f)), | |
| 2173 XIMAGE_INSTANCE_X_CURSOR (f->pointer)); | |
| 2174 XSync (XtDisplay (FRAME_X_TEXT_WIDGET (f)), 0); | |
| 2175 } | |
| 2176 | |
| 2177 static Lisp_Object | |
| 2178 x_get_frame_parent (struct frame *f) | |
| 2179 { | |
| 2180 Widget parentwid = 0; | |
| 2181 | |
| 2182 Xt_GET_VALUE (FRAME_X_SHELL_WIDGET (f), XtNtransientFor, &parentwid); | |
| 2183 /* find the frame whose wid is parentwid */ | |
| 2184 if (parentwid) | |
| 2185 { | |
| 2186 Lisp_Object frmcons; | |
| 2187 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f))) | |
| 2188 { | |
| 2189 Lisp_Object frame = XCAR (frmcons); | |
| 2190 if (FRAME_X_SHELL_WIDGET (XFRAME (frame)) == parentwid) | |
| 2191 return frame; | |
| 2192 } | |
| 2193 } | |
| 2194 return Qnil; | |
| 2195 } | |
| 2196 | |
| 2197 DEFUN ("x-window-id", Fx_window_id, 0, 1, 0, /* | |
| 2198 Get the ID of the X11 window. | |
| 2199 This gives us a chance to manipulate the Emacs window from within a | |
| 2200 different program. Since the ID is an unsigned long, we return it as | |
| 2201 a string. | |
| 2202 */ | |
| 2203 (frame)) | |
| 2204 { | |
| 867 | 2205 Ibyte str[255]; |
| 428 | 2206 struct frame *f = decode_x_frame (frame); |
| 2207 | |
| 771 | 2208 qxesprintf (str, "%lu", XtWindow (FRAME_X_TEXT_WIDGET (f))); |
| 2209 return build_intstring (str); | |
| 428 | 2210 } |
| 2211 | |
| 2212 | |
| 2213 /************************************************************************/ | |
| 2214 /* manipulating the X window */ | |
| 2215 /************************************************************************/ | |
| 2216 | |
| 2217 static void | |
| 2218 x_set_frame_position (struct frame *f, int xoff, int yoff) | |
| 2219 { | |
| 2220 Widget w = FRAME_X_SHELL_WIDGET (f); | |
| 2221 Display *dpy = XtDisplay (w); | |
| 2222 Dimension frame_w = DisplayWidth (dpy, DefaultScreen (dpy)); | |
| 2223 Dimension frame_h = DisplayHeight (dpy, DefaultScreen (dpy)); | |
| 2224 Dimension shell_w, shell_h, shell_bord; | |
| 2225 int win_gravity; | |
| 2367 | 2226 Arg al[3]; |
| 2227 | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2228 Xt_SET_ARG (al[0], XtNwidth, &shell_w); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2229 Xt_SET_ARG (al[1], XtNheight, &shell_h); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2230 Xt_SET_ARG (al[2], XtNborderWidth, &shell_bord); |
| 428 | 2231 XtGetValues (w, al, 3); |
| 2232 | |
| 2233 win_gravity = | |
| 2234 xoff >= 0 && yoff >= 0 ? NorthWestGravity : | |
| 2235 xoff >= 0 ? SouthWestGravity : | |
| 2236 yoff >= 0 ? NorthEastGravity : | |
| 2237 SouthEastGravity; | |
| 2238 if (xoff < 0) | |
| 2239 xoff += frame_w - shell_w - 2*shell_bord; | |
| 2240 if (yoff < 0) | |
| 2241 yoff += frame_h - shell_h - 2*shell_bord; | |
| 2242 | |
| 2243 /* Update the hints so that, if this window is currently iconified, it will | |
| 2244 come back at the right place. We can't look at s->visible to determine | |
| 2245 whether it is iconified because it might not be up-to-date yet (the queue | |
| 2246 might not be processed). */ | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2247 Xt_SET_ARG (al[0], XtNwinGravity, win_gravity); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2248 Xt_SET_ARG (al[1], XtNx, xoff); |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2249 Xt_SET_ARG (al[2], XtNy, yoff); |
| 428 | 2250 XtSetValues (w, al, 3); |
| 2251 | |
| 2252 /* Sometimes you will find that | |
| 2253 | |
| 2254 (set-frame-position (selected-frame) -50 -50) | |
| 2255 | |
| 2256 doesn't put the frame where you expect it to: i.e. it's closer to | |
| 2257 the lower-right corner than it should be, and it appears that the | |
| 2258 size of the WM decorations was not taken into account. This is | |
| 2259 *not* a problem with this function. Both mwm and twm have bugs | |
| 2260 in handling this situation. (mwm ignores the window gravity and | |
| 2261 always assumes NorthWest, except the first time you map the | |
| 2262 window; twm gets things almost right, but forgets to account for | |
| 2263 the border width of the top-level window.) This function does | |
| 2264 what it's supposed to according to the ICCCM, and I'm not about | |
| 2265 to hack around window-manager bugs. */ | |
| 2266 | |
| 2267 #if 0 | |
| 2268 /* This is not necessary under either mwm or twm */ | |
| 2269 x_wm_mark_shell_position_user_specified (w); | |
| 2270 #endif | |
| 2271 } | |
| 2272 | |
| 2273 /* Call this to change the size of frame S's x-window. */ | |
| 2274 | |
| 2275 static void | |
| 2276 x_set_frame_size (struct frame *f, int cols, int rows) | |
| 2277 { | |
| 2278 EmacsFrameSetCharSize (FRAME_X_TEXT_WIDGET (f), cols, rows); | |
| 3381 | 2279 |
| 2280 if (!wedge_metacity) /* cf. EmacsFrameResize */ | |
| 2281 { | |
| 2282 /* Kick the manager so that it knows we've changed size. */ | |
| 2283 XtWidgetGeometry req, repl; | |
| 2284 req.request_mode = 0; | |
| 2285 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl); | |
| 2286 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), | |
| 2287 repl.width, repl.height); | |
| 2288 } | |
| 2289 | |
| 428 | 2290 #if 0 |
| 2291 /* this is not correct. x_set_frame_size() is called from | |
| 2292 Fset_frame_size(), which may or may not have been called | |
| 2293 by the user (e.g. update_EmacsFrame() calls it when the font | |
| 2294 changes). For now, don't bother with getting this right. */ | |
| 2295 x_wm_mark_shell_size_user_specified (FRAME_X_SHELL_WIDGET (f)); | |
| 2296 #endif | |
| 2297 } | |
| 2298 | |
| 2299 static void | |
| 2300 x_set_mouse_position (struct window *w, int x, int y) | |
| 2301 { | |
| 2302 struct frame *f = XFRAME (w->frame); | |
| 2303 | |
| 2304 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); | |
| 2305 XWarpPointer (display, None, XtWindow (FRAME_X_TEXT_WIDGET (f)), | |
| 2306 0, 0, 0, 0, w->pixel_left + x, w->pixel_top + y); | |
| 2307 } | |
| 2308 | |
| 2309 static int | |
| 2310 x_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y) | |
| 2311 { | |
| 2312 Display *display = DEVICE_X_DISPLAY (d); | |
| 2313 Window child_window; | |
| 2314 Window root_window; | |
| 2315 Window win; | |
| 2316 int root_x, root_y; | |
| 2317 int win_x, win_y; | |
| 2318 unsigned int keys_and_buttons; | |
| 2319 struct frame *f; | |
| 2320 | |
| 2321 if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), | |
| 2322 &root_window, &child_window, &root_x, &root_y, | |
| 2323 &win_x, &win_y, &keys_and_buttons) == False) | |
| 2324 return 0; | |
| 2325 | |
| 2326 if (child_window == None) | |
| 2327 return 0; /* not over any window. */ | |
| 2328 | |
| 2329 while (1) | |
| 2330 { | |
| 2331 win = child_window; | |
| 2332 if (XTranslateCoordinates (display, root_window, win, root_x, root_y, | |
| 2333 &win_x, &win_y, &child_window) == False) | |
| 2334 /* Huh? */ | |
| 2335 return 0; | |
| 2336 | |
| 2337 if (child_window == None) | |
| 2338 break; | |
| 2339 } | |
| 2340 | |
| 2341 /* At this point, win is the innermost window containing the pointer | |
| 2342 and win_x and win_y are the coordinates of that window. */ | |
| 2343 f = x_any_window_to_frame (d, win); | |
| 2344 if (!f) | |
| 2345 return 0; | |
| 793 | 2346 *frame = wrap_frame (f); |
| 428 | 2347 |
| 2348 if (XTranslateCoordinates (display, win, | |
| 2349 XtWindow (FRAME_X_TEXT_WIDGET (f)), | |
| 2350 win_x, win_y, x, y, &child_window) == False) | |
| 2351 /* Huh? */ | |
| 2352 return 0; | |
| 2353 | |
| 2354 return 1; | |
| 2355 } | |
| 2356 | |
| 2268 | 2357 static DECLARE_DOESNT_RETURN (x_cant_notify_wm_error (void)); |
| 2358 | |
| 2359 static DOESNT_RETURN | |
| 2360 x_cant_notify_wm_error () | |
| 428 | 2361 { |
| 563 | 2362 signal_error (Qgui_error, "Can't notify window manager of iconification", Qunbound); |
| 428 | 2363 } |
| 2364 | |
| 2365 /* Raise frame F. */ | |
| 2366 static void | |
| 2367 x_raise_frame_1 (struct frame *f, int force) | |
| 2368 { | |
| 2369 if (FRAME_VISIBLE_P (f) || force) | |
| 2370 { | |
| 2371 Widget bottom_dialog; | |
| 2372 XWindowChanges xwc; | |
| 2373 unsigned int flags; | |
| 2374 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); | |
| 2375 Window emacs_window = XtWindow (FRAME_X_SHELL_WIDGET (f)); | |
| 2376 | |
| 2377 /* first raises all the dialog boxes, then put emacs just below the | |
| 2378 * bottom most dialog box */ | |
| 2379 bottom_dialog = lw_raise_all_pop_up_widgets (); | |
| 2380 if (bottom_dialog && XtWindow (bottom_dialog)) | |
| 2381 { | |
| 2382 xwc.sibling = XtWindow (bottom_dialog); | |
| 2383 xwc.stack_mode = Below; | |
| 2384 flags = CWSibling | CWStackMode; | |
| 2385 } | |
| 2386 else | |
| 2387 { | |
| 2388 xwc.stack_mode = Above; | |
| 2389 flags = CWStackMode; | |
| 2390 } | |
| 2391 | |
| 2392 if (!XReconfigureWMWindow (display, emacs_window, | |
| 2393 DefaultScreen (display), | |
| 2394 flags, &xwc)) | |
| 2395 x_cant_notify_wm_error (); | |
| 2396 } | |
| 2397 } | |
| 2398 | |
| 2399 static void | |
| 2400 x_raise_frame (struct frame *f) | |
| 2401 { | |
| 2402 x_raise_frame_1 (f, 1); | |
| 2403 } | |
| 2404 | |
| 2405 /* Lower frame F. */ | |
| 2406 static void | |
| 2407 x_lower_frame (struct frame *f) | |
| 2408 { | |
| 2409 if (FRAME_VISIBLE_P (f)) | |
| 2410 { | |
| 2411 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); | |
| 2412 XWindowChanges xwc; | |
| 2413 unsigned int flags = CWStackMode; | |
| 2414 | |
| 2415 xwc.stack_mode = Below; | |
| 2416 if (!XReconfigureWMWindow (display, XtWindow (FRAME_X_SHELL_WIDGET (f)), | |
| 2417 DefaultScreen (display), flags, &xwc)) | |
| 2418 x_cant_notify_wm_error (); | |
| 2419 } | |
| 2420 } | |
| 2421 | |
| 442 | 2422 static void |
| 2423 x_enable_frame (struct frame *f) | |
| 2424 { | |
| 2425 XtSetSensitive (FRAME_X_SHELL_WIDGET (f), True); | |
| 2426 } | |
| 2427 | |
| 2428 static void | |
| 2429 x_disable_frame (struct frame *f) | |
| 2430 { | |
| 2431 XtSetSensitive (FRAME_X_SHELL_WIDGET (f), False); | |
| 2432 } | |
| 2433 | |
| 428 | 2434 /* Change from withdrawn state to mapped state. */ |
| 2435 static void | |
| 2436 x_make_frame_visible (struct frame *f) | |
| 2437 { | |
| 2438 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); | |
| 2439 | |
| 2440 if (!FRAME_VISIBLE_P(f)) | |
| 2441 XMapRaised (display, XtWindow (FRAME_X_SHELL_WIDGET (f))); | |
| 2442 else | |
| 2443 x_raise_frame_1 (f, 0); | |
| 2444 } | |
| 2445 | |
| 2446 /* Change from mapped state to withdrawn state. */ | |
| 2447 static void | |
| 2448 x_make_frame_invisible (struct frame *f) | |
| 2449 { | |
| 2450 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); | |
| 2451 | |
| 2452 if (!FRAME_VISIBLE_P(f)) | |
| 2453 return; | |
| 2454 | |
| 2455 if (!XWithdrawWindow (display, | |
| 2456 XtWindow (FRAME_X_SHELL_WIDGET (f)), | |
| 2457 DefaultScreen (display))) | |
| 2458 x_cant_notify_wm_error (); | |
| 2459 } | |
| 2460 | |
| 2461 static int | |
| 2462 x_frame_visible_p (struct frame *f) | |
| 2463 { | |
| 2464 #if 0 | |
| 593 | 2465 |
| 2466 /* #### Ben suggests using x_frame_window_state (f) == NormalState. */ | |
| 2467 | |
| 428 | 2468 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); |
| 2469 XWindowAttributes xwa; | |
| 2470 int result; | |
| 2471 | |
| 2472 /* JV: | |
| 2473 This is bad, very bad :-( | |
| 2474 It is not compatible with our tristate visible and | |
| 2475 it should never ever change the visibility for us, this leads to | |
| 2476 the frame-freeze problem under fvwm because with the pager | |
| 2477 | |
| 2478 Mappedness != Viewability != Visibility != Emacs f->visible | |
| 2479 | |
| 2480 This first unequalness is the reason for the frame freezing problem | |
| 2481 under fvwm (it happens when the frame is another fvwm-page) | |
| 2482 | |
| 2483 The second unequalness happen when it is on the same fvwm-page | |
| 2484 but in an invisible part of the visible screen. | |
| 2485 | |
| 2486 For now we just return the XEmacs internal value --- which might not be up | |
| 2487 to date. Is that a problem? ---. Otherwise we should | |
| 2488 use async visibility like in standard Emacs. | |
| 2489 */ | |
| 2490 | |
| 2491 if (!XGetWindowAttributes (display, | |
| 2492 XtWindow (FRAME_X_SHELL_WIDGET (f)), | |
| 2493 &xwa)) | |
| 2494 result = 0; | |
| 2495 else | |
| 2496 result = xwa.map_state == IsViewable; | |
| 2497 /* In this implementation it should at least be != IsUnmapped | |
| 2498 JV */ | |
| 2499 | |
| 2500 f->visible = result; | |
| 2501 return result; | |
| 2502 #endif /* 0 */ | |
| 2503 | |
| 2504 return f->visible; | |
| 2505 } | |
| 2506 | |
| 2507 static int | |
| 2508 x_frame_totally_visible_p (struct frame *f) | |
| 2509 { | |
| 2510 return FRAME_X_TOTALLY_VISIBLE_P (f); | |
| 2511 } | |
| 2512 | |
| 2513 /* Change window state from mapped to iconified. */ | |
| 2514 static void | |
| 2515 x_iconify_frame (struct frame *f) | |
| 2516 { | |
| 2517 Display *display = DEVICE_X_DISPLAY (XDEVICE (f->device)); | |
| 2518 | |
| 2519 if (!XIconifyWindow (display, | |
| 2520 XtWindow (FRAME_X_SHELL_WIDGET (f)), | |
| 2521 DefaultScreen (display))) | |
| 2522 x_cant_notify_wm_error (); | |
| 2523 | |
| 2524 f->iconified = 1; | |
| 2525 } | |
| 2526 | |
| 2527 /* Sets the X focus to frame f. */ | |
| 2528 static void | |
| 2529 x_focus_on_frame (struct frame *f) | |
| 2530 { | |
| 2531 XWindowAttributes xwa; | |
| 2532 Widget shell_widget; | |
| 2533 int viewable = 0; | |
| 2534 | |
| 2535 assert (FRAME_X_P (f)); | |
| 2536 | |
| 2537 shell_widget = FRAME_X_SHELL_WIDGET (f); | |
| 2538 if (!XtWindow (shell_widget)) | |
| 2539 return; | |
| 2540 | |
| 2541 #ifdef EXTERNAL_WIDGET | |
| 2542 if (FRAME_X_EXTERNAL_WINDOW_P (f)) | |
| 2543 ExternalShellSetFocus (shell_widget); | |
| 2544 #endif /* EXTERNAL_WIDGET */ | |
| 2545 | |
| 2546 /* Do the ICCCM focus change if the window is still visible. | |
| 2547 The s->visible flag might not be up-to-date, because we might | |
| 2548 not have processed magic events recently. So make a server | |
| 2549 round-trip to find out whether it's really mapped right now. | |
| 2550 We grab the server to do this, because that's the only way to | |
| 2551 eliminate the race condition. | |
| 2552 */ | |
| 2553 XGrabServer (XtDisplay (shell_widget)); | |
| 2554 if (XGetWindowAttributes (XtDisplay (shell_widget), | |
| 2555 XtWindow (shell_widget), | |
| 2556 &xwa)) | |
| 2557 /* JV: it is bad to change the visibility like this, so we don't for the | |
| 2558 moment, at least change_frame_visibility should be called | |
| 2559 Note also that under fvwm a frame can be Viewable (and thus Mapped) | |
| 2560 but still X-invisible | |
| 2561 f->visible = xwa.map_state == IsViewable; */ | |
| 2562 viewable = xwa.map_state == IsViewable; | |
| 2563 | |
| 2564 | |
| 2565 if (viewable) | |
| 2566 { | |
| 2567 Window focus; | |
| 2568 int revert_to; | |
| 2569 XGetInputFocus (XtDisplay (shell_widget), &focus, &revert_to); | |
| 2570 /* Don't explicitly set the focus on this window unless the focus | |
| 2571 was on some other window (not PointerRoot). Note that, even when | |
| 2572 running a point-to-type window manager like *twm, there is always | |
| 2573 a focus window; the window manager maintains that based on the | |
| 2574 mouse position. If you set the "NoTitleFocus" option in these | |
| 2575 window managers, then the server itself maintains the focus via | |
| 2576 PointerRoot, and changing that to focus on the window would make | |
| 2577 the window grab the focus. Very bad. | |
| 2578 */ | |
| 2579 if (focus != PointerRoot) | |
| 2580 { | |
| 2581 XSetInputFocus (XtDisplay (shell_widget), | |
| 2582 XtWindow (shell_widget), | |
| 2583 RevertToParent, | |
| 4706 | 2584 CurrentTime); |
| 428 | 2585 XFlush (XtDisplay (shell_widget)); |
| 2586 } | |
| 2587 } | |
| 2588 XUngrabServer (XtDisplay (shell_widget)); | |
| 2589 XFlush (XtDisplay (shell_widget)); /* hey, I'd like to DEBUG this... */ | |
| 2590 } | |
| 2591 | |
| 450 | 2592 /* Destroy the X window of frame F. */ |
| 428 | 2593 static void |
| 2594 x_delete_frame (struct frame *f) | |
| 2595 { | |
| 2596 Display *dpy; | |
| 2597 | |
| 2598 #ifndef HAVE_WMCOMMAND | |
| 2599 if (FRAME_X_TOP_LEVEL_FRAME_P (f)) | |
| 2600 x_wm_maybe_move_wm_command (f); | |
| 2601 #endif /* HAVE_WMCOMMAND */ | |
| 2602 | |
| 2603 #ifdef HAVE_CDE | |
| 2604 DtDndDropUnregister (FRAME_X_TEXT_WIDGET (f)); | |
| 2605 #endif /* HAVE_CDE */ | |
| 2606 | |
| 3094 | 2607 #ifdef USE_XFT |
| 2608 /* If we have an XftDraw structure, we need to free it here. | |
| 2609 We can't ever have an XftDraw without a Display, so we are safe | |
| 2610 to free it in here, and we avoid too much playing around with the | |
| 2611 malloc checking hooks this way. */ | |
| 2612 if (FRAME_X_XFTDRAW (f)) | |
| 2613 { | |
| 2614 XftDrawDestroy (FRAME_X_XFTDRAW (f)); | |
| 2615 FRAME_X_XFTDRAW (f) = NULL; | |
| 2616 } | |
| 2617 #endif | |
| 2618 | |
| 2619 | |
| 428 | 2620 assert (FRAME_X_SHELL_WIDGET (f) != 0); |
| 2621 dpy = XtDisplay (FRAME_X_SHELL_WIDGET (f)); | |
| 2622 | |
| 2623 #ifdef EXTERNAL_WIDGET | |
| 1024 | 2624 expect_x_error (dpy); |
| 428 | 2625 /* for obscure reasons having (I think) to do with the internal |
| 2626 window-to-widget hierarchy maintained by Xt, we have to call | |
| 2627 XtUnrealizeWidget() here. Xt can really suck. */ | |
| 2628 if (f->being_deleted) | |
| 2629 XtUnrealizeWidget (FRAME_X_SHELL_WIDGET (f)); | |
| 2630 XtDestroyWidget (FRAME_X_SHELL_WIDGET (f)); | |
| 1024 | 2631 x_error_occurred_p (dpy); |
| 428 | 2632 #else |
| 2633 XtDestroyWidget (FRAME_X_SHELL_WIDGET (f)); | |
| 2634 /* make sure the windows are really gone! */ | |
| 440 | 2635 /* #### Is this REALLY necessary? */ |
| 428 | 2636 XFlush (dpy); |
| 2637 #endif /* EXTERNAL_WIDGET */ | |
| 2638 | |
| 2639 FRAME_X_SHELL_WIDGET (f) = 0; | |
| 2640 | |
| 2641 if (FRAME_X_GEOM_FREE_ME_PLEASE (f)) | |
| 2642 { | |
| 2367 | 2643 xfree (FRAME_X_GEOM_FREE_ME_PLEASE (f), Ascbyte *); |
| 428 | 2644 FRAME_X_GEOM_FREE_ME_PLEASE (f) = 0; |
| 2645 } | |
| 2646 | |
| 2647 if (f->frame_data) | |
| 2648 { | |
| 4117 | 2649 #ifndef NEW_GC |
| 1726 | 2650 xfree (f->frame_data, void *); |
| 3092 | 2651 #endif /* not NEW_GC */ |
| 428 | 2652 f->frame_data = 0; |
| 2653 } | |
| 2654 } | |
| 2655 | |
| 2656 static void | |
| 2367 | 2657 x_update_frame_external_traits (struct frame *frm, Lisp_Object name) |
| 428 | 2658 { |
| 2659 Arg al[10]; | |
| 2660 int ac = 0; | |
| 793 | 2661 Lisp_Object frame = wrap_frame (frm); |
| 2662 | |
| 428 | 2663 |
| 2664 if (EQ (name, Qforeground)) | |
| 2665 { | |
| 2666 Lisp_Object color = FACE_FOREGROUND (Vdefault_face, frame); | |
| 2667 XColor fgc; | |
| 2668 | |
| 2669 if (!EQ (color, Vthe_null_color_instance)) | |
| 2670 { | |
| 2671 fgc = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color)); | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2672 Xt_SET_ARG (al[ac], XtNforeground, (void *) fgc.pixel); ac++; |
| 428 | 2673 } |
| 2674 } | |
| 2675 else if (EQ (name, Qbackground)) | |
| 2676 { | |
| 2677 Lisp_Object color = FACE_BACKGROUND (Vdefault_face, frame); | |
| 2678 XColor bgc; | |
| 2679 | |
| 2680 if (!EQ (color, Vthe_null_color_instance)) | |
| 2681 { | |
| 2682 bgc = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color)); | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2683 Xt_SET_ARG (al[ac], XtNbackground, (void *) bgc.pixel); ac++; |
| 428 | 2684 } |
| 2685 | |
| 2686 /* Really crappy way to force the modeline shadows to be | |
| 2687 redrawn. But effective. */ | |
| 2688 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (frm); | |
| 2689 MARK_FRAME_CHANGED (frm); | |
| 2690 } | |
| 2691 else if (EQ (name, Qfont)) | |
| 2692 { | |
| 2693 Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii); | |
| 2694 | |
| 3676 | 2695 /* It may be that instantiating the font has deleted the frame (will |
| 2696 happen if the user has specified a charset registry for ASCII that | |
| 2697 isn't available on the server, and our fallback of iso8859-1 isn't | |
| 2698 available; something vanishingly rare.) In that case, return from | |
| 2699 this function without further manipulation of the dead frame. */ | |
| 2700 | |
| 2701 if (!FRAME_LIVE_P(frm)) | |
| 2702 { | |
| 2703 return; | |
| 2704 } | |
| 2705 | |
| 3094 | 2706 /* #### what to do about Xft? I don't think the font is actually used |
| 2707 to compute cell size for computing frame pixel dimensions (see call | |
| 2708 to EmacsFrameRecomputeCellSize() below); where is it used? -- sjt | |
| 2709 What does XtSetValues() do if that resource isn't present? */ | |
| 428 | 2710 if (!EQ (font, Vthe_null_font_instance)) |
| 1746 | 2711 { |
| 3094 | 2712 if (0) |
| 2713 ; | |
| 2714 #ifdef USE_XFT | |
| 2715 else if (FONT_INSTANCE_X_XFTFONT (XFONT_INSTANCE (font))) | |
| 2716 { | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2717 Xt_SET_ARG (al[ac], XtNxftFont, |
| 3094 | 2718 (void *) FONT_INSTANCE_X_XFTFONT (XFONT_INSTANCE (font))); |
| 2719 ac++; | |
| 2720 } | |
| 2721 #endif | |
| 2722 else if (FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font))) | |
| 2723 { | |
|
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2724 Xt_SET_ARG (al[ac], XtNfont, |
|
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
2725 (void *) FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font))); |
| 3094 | 2726 ac++; |
| 2727 } | |
| 1746 | 2728 } |
| 428 | 2729 } |
| 2730 else | |
| 2500 | 2731 ABORT (); |
| 428 | 2732 |
| 2733 XtSetValues (FRAME_X_TEXT_WIDGET (frm), al, ac); | |
| 2734 | |
| 2735 #ifdef HAVE_TOOLBARS | |
| 2736 /* Setting the background clears the entire frame area | |
| 2737 including the toolbar so we force an immediate redraw of | |
| 2738 it. */ | |
| 2739 if (EQ (name, Qbackground)) | |
| 2740 MAYBE_DEVMETH (XDEVICE (frm->device), redraw_frame_toolbars, (frm)); | |
| 2741 #endif /* HAVE_TOOLBARS */ | |
| 2742 | |
| 2743 /* Set window manager resize increment hints according to | |
| 2744 the new character size */ | |
| 2745 if (EQ (name, Qfont)) | |
| 2746 EmacsFrameRecomputeCellSize (FRAME_X_TEXT_WIDGET (frm)); | |
| 2747 } | |
| 2748 | |
| 2749 | |
| 2750 /************************************************************************/ | |
| 2751 /* initialization */ | |
| 2752 /************************************************************************/ | |
| 2753 | |
| 2754 void | |
| 2755 syms_of_frame_x (void) | |
| 2756 { | |
| 3092 | 2757 #ifdef NEW_GC |
|
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4790
diff
changeset
|
2758 INIT_LISP_OBJECT (x_frame); |
| 3092 | 2759 #endif /* NEW_GC */ |
| 2760 | |
| 2747 | 2761 DEFSYMBOL (Qoverride_redirect); |
| 563 | 2762 DEFSYMBOL (Qx_resource_name); |
| 428 | 2763 |
| 2764 DEFSUBR (Fx_window_id); | |
| 2765 #ifdef HAVE_CDE | |
| 2766 DEFSUBR (Fcde_start_drag_internal); | |
| 2767 #endif | |
| 2768 } | |
| 2769 | |
| 2770 void | |
| 2771 console_type_create_frame_x (void) | |
| 2772 { | |
| 2773 /* frame methods */ | |
| 2774 CONSOLE_HAS_METHOD (x, init_frame_1); | |
| 2775 CONSOLE_HAS_METHOD (x, init_frame_2); | |
| 2776 CONSOLE_HAS_METHOD (x, init_frame_3); | |
| 2777 CONSOLE_HAS_METHOD (x, mark_frame); | |
| 2778 CONSOLE_HAS_METHOD (x, focus_on_frame); | |
| 2779 CONSOLE_HAS_METHOD (x, delete_frame); | |
| 2780 CONSOLE_HAS_METHOD (x, get_mouse_position); | |
| 2781 CONSOLE_HAS_METHOD (x, set_mouse_position); | |
| 2782 CONSOLE_HAS_METHOD (x, raise_frame); | |
| 2783 CONSOLE_HAS_METHOD (x, lower_frame); | |
| 442 | 2784 CONSOLE_HAS_METHOD (x, enable_frame); |
| 2785 CONSOLE_HAS_METHOD (x, disable_frame); | |
| 428 | 2786 CONSOLE_HAS_METHOD (x, make_frame_visible); |
| 2787 CONSOLE_HAS_METHOD (x, make_frame_invisible); | |
| 2788 CONSOLE_HAS_METHOD (x, iconify_frame); | |
| 2789 CONSOLE_HAS_METHOD (x, set_frame_size); | |
| 2790 CONSOLE_HAS_METHOD (x, set_frame_position); | |
| 2791 CONSOLE_HAS_METHOD (x, frame_property); | |
| 2792 CONSOLE_HAS_METHOD (x, internal_frame_property_p); | |
| 2793 CONSOLE_HAS_METHOD (x, frame_properties); | |
| 2794 CONSOLE_HAS_METHOD (x, set_frame_properties); | |
| 867 | 2795 CONSOLE_HAS_METHOD (x, set_title_from_ibyte); |
| 2796 CONSOLE_HAS_METHOD (x, set_icon_name_from_ibyte); | |
| 428 | 2797 CONSOLE_HAS_METHOD (x, frame_visible_p); |
| 2798 CONSOLE_HAS_METHOD (x, frame_totally_visible_p); | |
| 2799 CONSOLE_HAS_METHOD (x, frame_iconified_p); | |
| 2800 CONSOLE_HAS_METHOD (x, set_frame_pointer); | |
| 2801 CONSOLE_HAS_METHOD (x, set_frame_icon); | |
| 2802 CONSOLE_HAS_METHOD (x, get_frame_parent); | |
| 2803 CONSOLE_HAS_METHOD (x, update_frame_external_traits); | |
| 2804 } | |
| 2805 | |
| 2806 void | |
| 2807 vars_of_frame_x (void) | |
| 2808 { | |
| 2809 #ifdef EXTERNAL_WIDGET | |
| 2810 Fprovide (intern ("external-widget")); | |
| 2811 #endif | |
| 2812 | |
| 2813 /* this call uses only safe functions from emacs.c */ | |
| 2814 init_x_prop_symbols (); | |
| 2815 | |
| 2816 DEFVAR_LISP ("default-x-frame-plist", &Vdefault_x_frame_plist /* | |
| 2817 Plist of default frame-creation properties for X frames. | |
| 2818 These override what is specified in the resource database and in | |
| 2819 `default-frame-plist', but are overridden by the arguments to the | |
| 2820 particular call to `make-frame'. | |
| 2821 | |
| 2822 Note: In many cases, properties of a frame are available as specifiers | |
| 2823 instead of through the frame-properties mechanism. | |
| 2824 | |
| 2825 Here is a list of recognized frame properties, other than those | |
| 2826 documented in `set-frame-properties' (they can be queried and | |
| 2827 set at any time, except as otherwise noted): | |
| 2828 | |
| 2829 window-id The X window ID corresponding to the | |
| 2830 frame. May be set only at startup, and | |
| 2831 only if external widget support was | |
| 2832 compiled in; doing so causes the frame | |
| 2833 to be created as an "external widget" | |
| 2834 in another program that uses an existing | |
| 2835 window in the program rather than creating | |
| 2836 a new one. | |
| 2837 initially-unmapped If non-nil, the frame will not be visible | |
| 2838 when it is created. In this case, you | |
| 2839 need to call `make-frame-visible' to make | |
| 2840 the frame appear. | |
| 2841 popup If non-nil, it should be a frame, and this | |
| 2842 frame will be created as a "popup" frame | |
| 2843 whose parent is the given frame. This | |
| 2844 will make the window manager treat the | |
| 2845 frame as a dialog box, which may entail | |
| 2846 doing different things (e.g. not asking | |
| 2847 for positioning, and not iconifying | |
| 2848 separate from its parent). | |
| 2747 | 2849 override-redirect If non-nil, the frame will not be subject to |
| 2850 window-manager control. In particular, it | |
| 2851 will lack decorations, for more attractive | |
| 2852 appearance of balloon help, aka tooltips. | |
| 428 | 2853 inter-line-space Not currently implemented. |
| 2854 toolbar-shadow-thickness Thickness of toolbar shadows. | |
| 2855 background-toolbar-color Color of toolbar background. | |
| 2856 bottom-toolbar-shadow-color Color of bottom shadows on toolbars. | |
| 2857 (*Not* specific to the bottom-toolbar.) | |
| 2858 top-toolbar-shadow-color Color of top shadows on toolbars. | |
| 2859 (*Not* specific to the top-toolbar.) | |
| 2860 internal-border-width Width of internal border around text area. | |
| 2861 border-width Width of external border around text area. | |
| 2862 top Y position (in pixels) of the upper-left | |
| 2863 outermost corner of the frame (i.e. the | |
| 2864 upper-left of the window-manager | |
| 2865 decorations). | |
| 2866 left X position (in pixels) of the upper-left | |
| 2867 outermost corner of the frame (i.e. the | |
| 2868 upper-left of the window-manager | |
| 2869 decorations). | |
| 2870 border-color Color of external border around text area. | |
| 2871 cursor-color Color of text cursor. | |
| 2872 | |
| 2873 See also `default-frame-plist', which specifies properties which apply | |
| 2874 to all frames, not just X frames. | |
| 2875 */ ); | |
| 2876 Vdefault_x_frame_plist = Qnil; | |
| 2877 | |
| 2878 x_console_methods->device_specific_frame_props = &Vdefault_x_frame_plist; | |
| 2879 } |
