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