Mercurial > hg > xemacs-beta
annotate src/frame-gtk.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 |
---|---|
2168 | 1 /* Functions for the GTK toolkit. |
462 | 2 Copyright (C) 1989, 1992-5, 1997 Free Software Foundation, Inc. |
5043 | 3 Copyright (C) 1995, 1996, 2002, 2003, 2010 Ben Wing. |
462 | 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 | |
24 /* Substantially rewritten for XEmacs. */ | |
25 /* Revamped to use Gdk/Gtk by William Perry */ | |
26 | |
27 #include <config.h> | |
28 #include "lisp.h" | |
29 | |
872 | 30 #include "buffer.h" |
31 #include "device-impl.h" | |
32 #include "events.h" | |
33 #include "extents.h" | |
34 #include "faces.h" | |
35 #include "frame-impl.h" | |
36 #include "window.h" | |
37 | |
38 #ifdef HAVE_DRAGNDROP | |
39 #include "dragdrop.h" | |
40 #endif | |
41 | |
2168 | 42 #include "elhash.h" |
872 | 43 #include "console-gtk-impl.h" |
462 | 44 #include "glyphs-gtk.h" |
872 | 45 #include "objects-gtk-impl.h" |
462 | 46 #include "scrollbar-gtk.h" |
872 | 47 #include "ui-gtk.h" |
462 | 48 |
49 #include "gtk-xemacs.h" | |
50 | |
51 #ifdef HAVE_GNOME | |
52 #include <libgnomeui/libgnomeui.h> | |
53 #endif | |
54 | |
55 #define BORDER_WIDTH 0 | |
56 #define INTERNAL_BORDER_WIDTH 0 | |
57 | |
58 #define TRANSIENT_DATA_IDENTIFIER "xemacs::transient_for" | |
59 #define UNMAPPED_DATA_IDENTIFIER "xemacs::initially_unmapped" | |
60 | |
61 #define STUPID_X_SPECIFIC_GTK_STUFF | |
62 | |
63 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4906
diff
changeset
|
64 #include "sysgdkx.h" |
462 | 65 #endif |
66 | |
67 /* Default properties to use when creating frames. */ | |
68 Lisp_Object Vdefault_gtk_frame_plist; | |
69 | |
70 Lisp_Object Qdetachable_menubar; | |
71 Lisp_Object Qtext_widget; | |
72 Lisp_Object Qcontainer_widget; | |
73 Lisp_Object Qshell_widget; | |
74 | |
75 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
76 EXFUN (Fgtk_window_id, 1); | |
77 #endif | |
78 | |
79 #ifdef HAVE_DRAGNDROP | |
80 enum { | |
81 TARGET_TYPE_STRING, | |
82 TARGET_TYPE_URI_LIST, | |
83 }; | |
84 | |
85 static GtkTargetEntry dnd_target_table[] = { | |
86 { "STRING", 0, TARGET_TYPE_STRING }, | |
87 { "text/plain", 0, TARGET_TYPE_STRING }, | |
88 { "text/uri-list", 0, TARGET_TYPE_URI_LIST }, | |
89 { "_NETSCAPE_URL", 0, TARGET_TYPE_STRING } | |
90 }; | |
91 | |
92 static guint dnd_n_targets = sizeof(dnd_target_table) / sizeof(dnd_target_table[0]); | |
93 | |
94 #endif | |
95 | |
1204 | 96 static const struct memory_description gtk_frame_data_description_1 [] = { |
97 { XD_LISP_OBJECT, offsetof (struct gtk_frame, icon_pixmap) }, | |
98 { XD_LISP_OBJECT, offsetof (struct gtk_frame, icon_pixmap_mask) }, | |
99 { XD_LISP_OBJECT_ARRAY, offsetof (struct gtk_frame, lisp_visible_widgets), | |
100 3 }, | |
1346 | 101 { XD_LISP_OBJECT, offsetof (struct gtk_frame, menubar_data) }, |
1204 | 102 { XD_END } |
103 }; | |
104 | |
3092 | 105 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
106 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("gtk-frame", gtk_frame, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
107 0, gtk_frame_data_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
108 Lisp_Gtk_Frame); |
3092 | 109 #else /* not NEW_GC */ |
1204 | 110 extern const struct sized_memory_description gtk_frame_data_description; |
111 | |
112 const struct sized_memory_description gtk_frame_data_description = { | |
113 sizeof (struct gtk_frame), gtk_frame_data_description_1 | |
114 }; | |
3092 | 115 #endif /* not NEW_GC */ |
1204 | 116 |
462 | 117 |
118 /************************************************************************/ | |
119 /* helper functions */ | |
120 /************************************************************************/ | |
121 | |
2168 | 122 /* Return the Emacs frame-object which contains the given widget. */ |
123 struct frame * | |
124 gtk_widget_to_frame (GtkWidget *w) | |
125 { | |
126 struct frame *f = NULL; | |
127 | |
128 for (; w; w = w->parent) | |
129 { | |
130 if ((f = (struct frame *) gtk_object_get_data (GTK_OBJECT (w), | |
131 GTK_DATA_FRAME_IDENTIFIER))) | |
132 return (f); | |
133 } | |
134 | |
135 return (selected_frame()); | |
136 } | |
137 | |
138 | |
462 | 139 /* Return the Emacs frame-object corresponding to an X window */ |
140 struct frame * | |
141 gtk_window_to_frame (struct device *d, GdkWindow *wdesc) | |
142 { | |
143 Lisp_Object tail, frame; | |
144 struct frame *f; | |
145 | |
146 /* This function was previously written to accept only a window argument | |
147 (and to loop over all devices looking for a matching window), but | |
148 that is incorrect because window ID's are not unique across displays. */ | |
149 | |
150 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail)) | |
151 { | |
152 frame = XCAR (tail); | |
153 if (!FRAMEP (frame)) | |
154 continue; | |
155 f = XFRAME (frame); | |
156 if (FRAME_GTK_P (f) && GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)) == wdesc) | |
157 return f; | |
158 } | |
159 return 0; | |
160 } | |
161 | |
162 /* Like gtk_window_to_frame but also compares the window with the widget's | |
163 windows */ | |
164 struct frame * | |
165 gtk_any_window_to_frame (struct device *d, GdkWindow *w) | |
166 { | |
167 do | |
168 { | |
169 Lisp_Object frmcons; | |
170 | |
171 DEVICE_FRAME_LOOP (frmcons, d) | |
172 { | |
173 struct frame *fr = XFRAME (XCAR (frmcons)); | |
174 if ((w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (fr))) || | |
175 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_CONTAINER_WIDGET (fr))) || | |
176 #ifdef HAVE_MENUBARS | |
177 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_MENUBAR_WIDGET (fr))) || | |
178 #endif | |
179 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (fr)))) | |
180 { | |
181 return (fr); | |
182 } | |
183 } | |
184 w = gdk_window_get_parent (w); | |
185 } while (w); | |
186 | |
187 return (0); | |
188 } | |
189 | |
190 struct frame * | |
191 gtk_any_widget_or_parent_to_frame (struct device *d, GtkWidget *widget) | |
192 { | |
193 return (gtk_any_window_to_frame (d, GET_GTK_WIDGET_WINDOW (widget))); | |
194 } | |
195 | |
196 struct device * | |
197 gtk_any_window_to_device (GdkWindow *w) | |
198 { | |
199 struct device *d = NULL; | |
200 Lisp_Object devcons, concons; | |
201 | |
202 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
203 { | |
204 d = XDEVICE (XCAR (devcons)); | |
205 if (!DEVICE_GTK_P (d)) continue; | |
206 if (gtk_any_window_to_frame (d, w)) | |
207 return (d); | |
208 } | |
209 return (NULL); | |
210 } | |
211 | |
212 struct frame * | |
213 decode_gtk_frame (Lisp_Object frame) | |
214 { | |
215 if (NILP (frame)) | |
793 | 216 frame = wrap_frame (selected_frame ()); |
462 | 217 CHECK_LIVE_FRAME (frame); |
218 /* this will also catch dead frames, but putting in the above check | |
219 results in a more useful error */ | |
220 CHECK_GTK_FRAME (frame); | |
221 return XFRAME (frame); | |
222 } | |
223 | |
224 | |
225 /************************************************************************/ | |
226 /* window-manager interactions */ | |
227 /************************************************************************/ | |
228 static int | |
229 gtk_frame_iconified_p (struct frame *f) | |
230 { | |
231 return (f->iconified); | |
232 } | |
233 | |
234 | |
235 /************************************************************************/ | |
236 /* frame properties */ | |
237 /************************************************************************/ | |
238 | |
239 static Lisp_Object | |
240 gtk_frame_property (struct frame *f, Lisp_Object property) | |
241 { | |
242 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
243 | |
244 if (EQ (Qleft, property) || EQ (Qtop, property)) | |
245 { | |
246 gint x, y; | |
247 if (!GET_GTK_WIDGET_WINDOW(shell)) | |
248 return Qzero; | |
249 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), &x, &y); | |
250 if (EQ (Qleft, property)) return make_int (x); | |
251 if (EQ (Qtop, property)) return make_int (y); | |
252 } | |
253 if (EQ (Qshell_widget, property)) | |
254 { | |
255 return (FRAME_GTK_LISP_WIDGETS (f)[0]); | |
256 } | |
257 if (EQ (Qcontainer_widget, property)) | |
258 { | |
259 return (FRAME_GTK_LISP_WIDGETS (f)[1]); | |
260 } | |
261 if (EQ (Qtext_widget, property)) | |
262 { | |
263 return (FRAME_GTK_LISP_WIDGETS (f)[2]); | |
264 } | |
265 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
266 if (EQ (Qwindow_id, property)) | |
771 | 267 return Fgtk_window_id (wrap_frame (f)); |
462 | 268 #endif |
269 | |
270 return Qunbound; | |
271 } | |
272 | |
273 static int | |
3087 | 274 gtk_internal_frame_property_p (struct frame *UNUSED(f), Lisp_Object property) |
462 | 275 { |
276 return EQ (property, Qleft) | |
277 || EQ (property, Qtop) | |
278 || EQ (Qshell_widget, property) | |
279 || EQ (Qcontainer_widget, property) | |
280 || EQ (Qtext_widget, property) | |
281 || EQ (property, Qwindow_id) | |
282 || STRINGP (property); | |
283 } | |
284 | |
285 static Lisp_Object | |
286 gtk_frame_properties (struct frame *f) | |
287 { | |
288 Lisp_Object props = Qnil; | |
289 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
290 gint x, y; | |
291 | |
292 props = cons3 (Qshell_widget, FRAME_GTK_LISP_WIDGETS (f)[0], props); | |
293 props = cons3 (Qcontainer_widget, FRAME_GTK_LISP_WIDGETS (f)[1], props); | |
294 props = cons3 (Qtext_widget, FRAME_GTK_LISP_WIDGETS (f)[2], props); | |
295 | |
296 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
771 | 297 props = cons3 (Qwindow_id, Fgtk_window_id (wrap_frame (f)), props); |
462 | 298 #endif |
299 | |
300 if (!GET_GTK_WIDGET_WINDOW (shell)) | |
301 x = y = 0; | |
302 else | |
303 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), &x, &y); | |
304 | |
305 props = cons3 (Qtop, make_int (y), props); | |
306 props = cons3 (Qleft, make_int (x), props); | |
307 | |
308 return props; | |
309 } | |
310 | |
311 | |
312 /* Functions called only from `gtk_set_frame_properties' to set | |
313 individual properties. */ | |
314 | |
315 static void | |
2286 | 316 gtk_set_frame_text_value (struct frame *UNUSED (f), Ibyte *value, |
462 | 317 void (*func) (gpointer, gchar *), |
318 gpointer arg) | |
319 { | |
320 gchar *the_text = (gchar *) value; | |
321 | |
322 /* Programmer fuckup or window is not realized yet. */ | |
323 if (!func || !arg) return; | |
324 | |
325 #ifdef MULE | |
326 { | |
867 | 327 Ibyte *ptr; |
462 | 328 |
329 /* Optimize for common ASCII case */ | |
330 for (ptr = value; *ptr; ptr++) | |
826 | 331 if (!byte_ascii_p (*ptr)) |
462 | 332 { |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
333 char *tmp = ITEXT_TO_EXTERNAL (value, Qctext); |
462 | 334 the_text = tmp; |
335 break; | |
336 } | |
337 } | |
338 #endif /* MULE */ | |
339 | |
340 (*func) (arg, (gchar *) the_text); | |
341 } | |
342 | |
343 static void | |
867 | 344 gtk_set_title_from_ibyte (struct frame *f, Ibyte *name) |
462 | 345 { |
346 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (f))) | |
347 gtk_set_frame_text_value (f, name, | |
348 (void (*)(gpointer, gchar *)) | |
349 gtk_window_set_title, FRAME_GTK_SHELL_WIDGET (f)); | |
350 } | |
351 | |
352 static void | |
867 | 353 gtk_set_icon_name_from_ibyte (struct frame *f, Ibyte *name) |
462 | 354 { |
355 gtk_set_frame_text_value (f, name, | |
356 (void (*)(gpointer, gchar *)) | |
357 gdk_window_set_icon_name, FRAME_GTK_SHELL_WIDGET (f)->window); | |
358 } | |
359 | |
360 /* Set the initial frame size as specified. This function is used | |
361 when the frame's widgets have not yet been realized. | |
362 */ | |
363 static void | |
364 gtk_set_initial_frame_size (struct frame *f, int x, int y, | |
365 unsigned int w, unsigned int h) | |
366 { | |
367 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
368 GdkGeometry geometry; | |
369 | |
370 if (GTK_IS_WINDOW (shell)) | |
371 { | |
2054 | 372 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC; |
462 | 373 /* Deal with the cell size */ |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
374 default_face_width_and_height (wrap_frame (f), &geometry.width_inc, &geometry.height_inc); |
462 | 375 |
376 gtk_window_set_geometry_hints (GTK_WINDOW (shell), | |
377 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask); | |
378 gdk_window_set_hints (GET_GTK_WIDGET_WINDOW (shell), x, y, 0, 0, 0, 0, GDK_HINT_POS); | |
379 gtk_window_set_policy (GTK_WINDOW (shell), TRUE, TRUE, FALSE); | |
380 } | |
381 | |
382 FRAME_HEIGHT (f) = h; | |
383 FRAME_WIDTH (f) = w; | |
384 | |
5043 | 385 change_frame_size (f, w, h, 0); |
462 | 386 { |
387 GtkRequisition req; | |
388 | |
389 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req); | |
390 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height); | |
391 } | |
392 } | |
393 | |
394 /* Report that a frame property of frame S is being set or changed. | |
395 If the property is not specially recognized, do nothing. | |
396 */ | |
397 | |
398 static void | |
399 gtk_set_frame_properties (struct frame *f, Lisp_Object plist) | |
400 { | |
401 gint x, y; | |
402 gint width = 0, height = 0; | |
403 gboolean width_specified_p = FALSE; | |
404 gboolean height_specified_p = FALSE; | |
405 gboolean x_position_specified_p = FALSE; | |
406 gboolean y_position_specified_p = FALSE; | |
407 Lisp_Object tail; | |
408 | |
409 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | |
410 { | |
411 Lisp_Object prop = Fcar (tail); | |
412 Lisp_Object val = Fcar (Fcdr (tail)); | |
413 | |
414 if (SYMBOLP (prop)) | |
415 { | |
416 if (EQ (prop, Qfont)) | |
417 { | |
418 /* If the value is not a string we silently ignore it. */ | |
419 if (STRINGP (val)) | |
420 { | |
421 Lisp_Object frm, font_spec; | |
422 | |
793 | 423 frm = wrap_frame (f); |
462 | 424 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil); |
425 | |
426 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil); | |
427 update_frame_face_values (f); | |
428 } | |
429 continue; | |
430 } | |
431 else if (EQ (prop, Qwidth)) | |
432 { | |
433 CHECK_INT (val); | |
434 width = XINT (val); | |
435 width_specified_p = TRUE; | |
436 continue; | |
437 } | |
438 else if (EQ (prop, Qheight)) | |
439 { | |
440 CHECK_INT (val); | |
441 height = XINT (val); | |
442 height_specified_p = TRUE; | |
443 continue; | |
444 } | |
445 /* Further kludge the x/y. */ | |
446 else if (EQ (prop, Qx)) | |
447 { | |
448 CHECK_INT (val); | |
449 x = (gint) XINT (val); | |
450 x_position_specified_p = TRUE; | |
451 continue; | |
452 } | |
453 else if (EQ (prop, Qy)) | |
454 { | |
455 CHECK_INT (val); | |
456 y = (gint) XINT (val); | |
457 y_position_specified_p = TRUE; | |
458 continue; | |
459 } | |
460 } | |
461 } | |
462 | |
463 /* Kludge kludge kludge. We need to deal with the size and position | |
464 specially. */ | |
465 { | |
466 int size_specified_p = width_specified_p || height_specified_p; | |
467 int position_specified_p = x_position_specified_p || y_position_specified_p; | |
468 | |
469 if (!width_specified_p) | |
470 width = 80; | |
471 if (!height_specified_p) | |
472 height = 30; | |
473 | |
474 /* Kludge kludge kludge kludge. */ | |
475 if (position_specified_p && | |
476 (!x_position_specified_p || !y_position_specified_p)) | |
477 { | |
478 gint dummy; | |
479 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
480 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), | |
481 (x_position_specified_p ? &dummy : &x), | |
482 (y_position_specified_p ? &dummy : &y)); | |
483 } | |
484 | |
485 if (!f->init_finished) | |
486 { | |
487 if (size_specified_p || position_specified_p) | |
488 gtk_set_initial_frame_size (f, x, y, width, height); | |
489 } | |
490 else | |
491 { | |
492 if (size_specified_p) | |
493 { | |
793 | 494 Lisp_Object frame = wrap_frame (f); |
495 | |
462 | 496 Fset_frame_size (frame, make_int (width), make_int (height), Qnil); |
497 } | |
498 if (position_specified_p) | |
499 { | |
793 | 500 Lisp_Object frame = wrap_frame (f); |
501 | |
462 | 502 Fset_frame_position (frame, make_int (x), make_int (y)); |
503 } | |
504 } | |
505 } | |
506 } | |
507 | |
508 | |
509 /************************************************************************/ | |
510 /* widget creation */ | |
511 /************************************************************************/ | |
512 /* Figure out what size the shell widget should initially be, | |
513 and set it. Should be called after the default font has been | |
514 determined but before the widget has been realized. */ | |
515 | |
516 extern Lisp_Object Vgtk_initial_geometry; | |
517 | |
518 #ifndef HAVE_GNOME | |
519 static int | |
520 get_number (const char **geometry) | |
521 { | |
522 int value = 0; | |
523 int mult = 1; | |
524 | |
525 if (**geometry == '-'){ | |
526 mult = -1; | |
527 (*geometry)++; | |
528 } | |
529 while (**geometry && isdigit (**geometry)){ | |
530 value = value * 10 + (**geometry - '0'); | |
531 (*geometry)++; | |
532 } | |
533 return value * mult; | |
534 } | |
535 | |
536 /* | |
537 */ | |
538 | |
539 /** | |
540 * gnome_parse_geometry | |
541 * @geometry: geometry string to be parsed | |
542 * @xpos: X position geometry component | |
543 * @ypos: Y position geometry component | |
544 * @width: pixel width geometry component | |
545 * @height: pixel height geometry component | |
546 * | |
547 * Description: | |
548 * Parses the geometry string passed in @geometry, and fills | |
549 * @xpos, @ypos, @width, and @height with | |
550 * the corresponding values upon completion of the parse. | |
551 * If the parse fails, it should be assumed that @xpos, @ypos, @width, | |
552 * and @height contain undefined values. | |
553 * | |
554 * Returns: | |
555 * %TRUE if the geometry was successfully parsed, %FALSE otherwise. | |
556 **/ | |
557 | |
558 static gboolean | |
559 gnome_parse_geometry (const gchar *geometry, gint *xpos, | |
560 gint *ypos, gint *width, gint *height) | |
561 { | |
562 int subtract; | |
563 | |
564 g_return_val_if_fail (xpos != NULL, FALSE); | |
565 g_return_val_if_fail (ypos != NULL, FALSE); | |
566 g_return_val_if_fail (width != NULL, FALSE); | |
567 g_return_val_if_fail (height != NULL, FALSE); | |
568 | |
569 *xpos = *ypos = *width = *height = -1; | |
570 | |
571 if (!geometry) | |
572 return FALSE; | |
573 | |
574 if (*geometry == '=') | |
575 geometry++; | |
576 if (!*geometry) | |
577 return FALSE; | |
578 if (isdigit (*geometry)) | |
579 *width = get_number (&geometry); | |
580 if (!*geometry) | |
581 return TRUE; | |
582 if (*geometry == 'x' || *geometry == 'X'){ | |
583 geometry++; | |
584 *height = get_number (&geometry); | |
585 } | |
586 if (!*geometry) | |
587 return 1; | |
588 if (*geometry == '+'){ | |
589 subtract = 0; | |
590 geometry++; | |
591 } else if (*geometry == '-'){ | |
592 subtract = gdk_screen_width (); | |
593 geometry++; | |
594 } else | |
595 return FALSE; | |
596 *xpos = get_number (&geometry); | |
597 if (subtract) | |
598 *xpos = subtract - *xpos; | |
599 if (!*geometry) | |
600 return TRUE; | |
601 if (*geometry == '+'){ | |
602 subtract = 0; | |
603 geometry++; | |
604 } else if (*geometry == '-'){ | |
605 subtract = gdk_screen_height (); | |
606 geometry++; | |
607 } else | |
608 return FALSE; | |
609 *ypos = get_number (&geometry); | |
610 if (subtract) | |
611 *ypos = subtract - *ypos; | |
612 return TRUE; | |
613 } | |
614 #endif | |
615 | |
616 static void | |
617 gtk_initialize_frame_size (struct frame *f) | |
618 { | |
619 gint x = 10, y = 10, w = 80, h = 30; | |
620 | |
621 if (STRINGP (Vgtk_initial_geometry)) | |
622 { | |
2054 | 623 if (!gnome_parse_geometry ((char*) XSTRING_DATA (Vgtk_initial_geometry), &x,&y,&w,&h)) |
462 | 624 { |
625 x = y = 10; | |
626 w = 80; | |
627 h = 30; | |
628 } | |
629 } | |
630 | |
631 /* set the position of the frame's root window now. When the | |
632 frame was created, the position was initialized to (0,0). */ | |
633 { | |
634 struct window *win = XWINDOW (f->root_window); | |
635 | |
636 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f); | |
637 WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f); | |
638 | |
639 if (!NILP (f->minibuffer_window)) | |
640 { | |
641 win = XWINDOW (f->minibuffer_window); | |
642 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f); | |
643 } | |
644 } | |
645 | |
646 gtk_set_initial_frame_size (f, x, y, w, h); | |
647 } | |
648 | |
649 static gboolean | |
2286 | 650 resize_event_cb (GtkWidget *UNUSED (w), GtkAllocation *allocation, |
651 gpointer user_data) | |
462 | 652 { |
653 struct frame *f = (struct frame *) user_data; | |
654 | |
655 f->pixwidth = allocation->width; | |
656 f->pixheight = allocation->height; | |
657 | |
658 if (FRAME_GTK_TEXT_WIDGET (f)->window) | |
659 { | |
793 | 660 Lisp_Object frame = wrap_frame (f); |
661 | |
462 | 662 Fredraw_frame (frame, Qt); |
663 } | |
664 | |
665 return (FALSE); | |
666 } | |
667 | |
668 static gboolean | |
2286 | 669 delete_event_cb (GtkWidget *UNUSED (w), GdkEvent *UNUSED (ev), |
670 gpointer user_data) | |
462 | 671 { |
672 struct frame *f = (struct frame *) user_data; | |
793 | 673 Lisp_Object frame = wrap_frame (f); |
462 | 674 |
675 enqueue_misc_user_event (frame, Qeval, list3 (Qdelete_frame, frame, Qt)); | |
676 | |
677 /* See if tickling the event queue helps us with our delays when | |
678 clicking 'close' */ | |
679 signal_fake_event (); | |
680 | |
681 return (TRUE); | |
682 } | |
683 | |
684 extern gboolean emacs_shell_event_handler (GtkWidget *wid, GdkEvent *event, gpointer closure); | |
685 extern Lisp_Object build_gtk_object (GtkObject *obj); | |
686 | |
687 #ifndef GNOME_IS_APP | |
688 #define GNOME_IS_APP(x) 0 | |
689 #define gnome_app_set_contents(x,y) 0 | |
690 #endif | |
691 | |
692 static void | |
693 cleanup_deleted_frame (gpointer data) | |
694 { | |
695 struct frame *f = (struct frame *) data; | |
793 | 696 Lisp_Object frame = wrap_frame (f); |
462 | 697 |
698 Fdelete_frame (frame, Qt); | |
699 } | |
700 | |
701 #ifdef HAVE_DRAGNDROP | |
702 extern void | |
703 dragndrop_data_received (GtkWidget *widget, | |
704 GdkDragContext *context, | |
705 gint x, | |
706 gint y, | |
707 GtkSelectionData *data, | |
708 guint info, | |
709 guint time); | |
710 | |
711 extern gboolean | |
712 dragndrop_dropped (GtkWidget *widget, | |
713 GdkDragContext *drag_context, | |
714 gint x, | |
715 gint y, | |
716 guint time, | |
717 gpointer user_data); | |
718 | |
719 Lisp_Object Vcurrent_drag_object; | |
720 | |
721 #define DRAG_SELECTION_DATA_ERROR "Error converting drag data to external format" | |
722 static void | |
2286 | 723 dragndrop_get_drag (GtkWidget *UNUSED (widget), |
724 GdkDragContext *UNUSED (drag_context), | |
462 | 725 GtkSelectionData *data, |
726 guint info, | |
2286 | 727 guint UNUSED (time), |
728 gpointer UNUSED (user_data)) | |
462 | 729 { |
730 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, 8, | |
731 DRAG_SELECTION_DATA_ERROR, | |
732 strlen (DRAG_SELECTION_DATA_ERROR)); | |
733 | |
734 switch (info) | |
735 { | |
736 case TARGET_TYPE_STRING: | |
737 { | |
738 Lisp_Object string = Vcurrent_drag_object; | |
739 | |
740 if (!STRINGP (Vcurrent_drag_object)) | |
741 { | |
742 string = Fprin1_to_string (string, Qnil); | |
743 /* Convert to a string */ | |
744 } | |
745 | |
746 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, | |
747 8, XSTRING_DATA (string), XSTRING_LENGTH (string)); | |
748 } | |
749 break; | |
750 case TARGET_TYPE_URI_LIST: | |
751 break; | |
752 default: | |
753 break; | |
754 } | |
755 Vcurrent_drag_object = Qnil; | |
756 } | |
757 | |
758 DEFUN ("gtk-start-drag-internal", Fgtk_start_drag_internal, 2, 3, 0, /* | |
759 Start a GTK drag from a buffer. | |
760 First arg is the event that started the drag, | |
761 second arg should be some string, and the third | |
762 is the type of the data (this should be a MIME type as a string (ie: text/plain)). | |
763 The type defaults to text/plain. | |
764 */ | |
765 (event, data, dtyp)) | |
766 { | |
767 if (EVENTP(event)) | |
768 { | |
769 struct frame *f = decode_gtk_frame (Fselected_frame (Qnil)); | |
770 GtkWidget *wid = FRAME_GTK_TEXT_WIDGET (f); | |
771 struct Lisp_Event *lisp_event = XEVENT(event); | |
772 GdkAtom dnd_typ; | |
773 GtkTargetList *tl = gtk_target_list_new (dnd_target_table, dnd_n_targets); | |
774 | |
775 /* only drag if this is really a press */ | |
776 if (EVENT_TYPE(lisp_event) != button_press_event) | |
777 return Qnil; | |
778 | |
779 /* get the desired type */ | |
780 if (!NILP (dtyp) && STRINGP (dtyp)) | |
781 dnd_typ = gdk_atom_intern (XSTRING_DATA (dtyp), FALSE); | |
782 | |
1204 | 783 gtk_drag_begin (wid, tl, GDK_ACTION_COPY, |
784 EVENT_BUTTON_BUTTON (lisp_event), NULL); | |
462 | 785 |
786 Vcurrent_drag_object = data; | |
787 | |
788 gtk_target_list_unref (tl); | |
789 } | |
790 return Qnil; | |
791 } | |
792 #endif | |
793 | |
794 /* Creates the widgets for a frame. | |
795 lisp_window_id is a Lisp description of an X window or Xt | |
796 widget to parse. | |
797 | |
798 This function does not map the windows. (That is | |
799 done by gtk_popup_frame().) | |
800 */ | |
801 static void | |
802 gtk_create_widgets (struct frame *f, Lisp_Object lisp_window_id, Lisp_Object parent) | |
803 { | |
804 const char *name; | |
805 GtkWidget *text, *container, *shell; | |
806 gboolean embedded_p = !NILP (lisp_window_id); | |
807 #ifdef HAVE_MENUBARS | |
808 int menubar_visible; | |
809 #endif | |
810 | |
811 if (STRINGP (f->name)) | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
812 name = LISP_STRING_TO_EXTERNAL (f->name, Qctext); |
462 | 813 else |
814 name = "emacs"; | |
815 | |
816 FRAME_GTK_TOP_LEVEL_FRAME_P (f) = 1; | |
817 | |
818 if (embedded_p) | |
819 { | |
820 CHECK_GTK_OBJECT (lisp_window_id); | |
821 | |
822 if (!GTK_IS_CONTAINER (XGTK_OBJECT (lisp_window_id)->object)) | |
823 { | |
563 | 824 invalid_argument ("Window ID must be a GtkContainer subclass", lisp_window_id); |
462 | 825 } |
826 | |
827 shell = gtk_vbox_new (FALSE, 0); | |
828 | |
829 gtk_object_weakref (GTK_OBJECT (shell), cleanup_deleted_frame, f); | |
830 gtk_container_add (GTK_CONTAINER (XGTK_OBJECT (lisp_window_id)->object), shell); | |
831 } | |
832 else | |
833 { | |
834 #ifdef HAVE_GNOME | |
835 shell = GTK_WIDGET (gnome_app_new ("XEmacs", "XEmacs/GNOME")); | |
836 #else | |
837 shell = GTK_WIDGET (gtk_window_new (GTK_WINDOW_TOPLEVEL)); | |
838 #endif | |
839 } | |
840 | |
841 if (!NILP (parent)) | |
842 { | |
843 /* If this is a transient window, keep the parent info around */ | |
844 GtkWidget *parentwid = FRAME_GTK_SHELL_WIDGET (XFRAME (parent)); | |
845 gtk_object_set_data (GTK_OBJECT (shell), TRANSIENT_DATA_IDENTIFIER, parentwid); | |
846 gtk_window_set_transient_for (GTK_WINDOW (shell), GTK_WINDOW (parentwid)); | |
847 } | |
848 | |
849 gtk_container_set_border_width (GTK_CONTAINER (shell), 0); | |
850 | |
2168 | 851 /* Add a mapping from widget to frame to help widget callbacks quickly find |
852 their corresponding frame. */ | |
853 gtk_object_set_data (GTK_OBJECT (shell), GTK_DATA_FRAME_IDENTIFIER, f); | |
462 | 854 |
855 FRAME_GTK_SHELL_WIDGET (f) = shell; | |
856 | |
857 text = GTK_WIDGET (gtk_xemacs_new (f)); | |
858 | |
859 if (!GNOME_IS_APP (shell)) | |
860 container = GTK_WIDGET (gtk_vbox_new (FALSE, INTERNAL_BORDER_WIDTH)); | |
861 else | |
862 container = shell; | |
863 | |
864 FRAME_GTK_CONTAINER_WIDGET (f) = container; | |
865 FRAME_GTK_TEXT_WIDGET (f) = text; | |
866 | |
867 #ifdef HAVE_DRAGNDROP | |
868 gtk_drag_dest_set (text, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT, | |
869 dnd_target_table, dnd_n_targets, | |
870 GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK); | |
871 gtk_signal_connect (GTK_OBJECT (text), "drag_drop", | |
872 GTK_SIGNAL_FUNC (dragndrop_dropped), text); | |
873 gtk_signal_connect (GTK_OBJECT (text), "drag_data_received", | |
874 GTK_SIGNAL_FUNC (dragndrop_data_received), text); | |
875 gtk_signal_connect (GTK_OBJECT (text), "drag_data_get", | |
876 GTK_SIGNAL_FUNC (dragndrop_get_drag), NULL); | |
877 #endif | |
878 | |
879 #ifdef HAVE_MENUBARS | |
880 /* Create the initial menubar widget. */ | |
881 menubar_visible = gtk_initialize_frame_menubar (f); | |
882 | |
883 if (menubar_visible) | |
884 { | |
885 gtk_widget_show_all (FRAME_GTK_MENUBAR_WIDGET (f)); | |
886 } | |
887 #endif /* HAVE_MENUBARS */ | |
888 | |
889 if (GNOME_IS_APP (shell)) | |
890 gnome_app_set_contents (GNOME_APP (shell), text); | |
891 else | |
892 /* Now comes the drawing area, which should fill the rest of the | |
893 ** frame completely. | |
894 */ | |
895 gtk_box_pack_end (GTK_BOX (container), text, TRUE, TRUE, 0); | |
896 | |
897 /* Connect main event handler */ | |
898 gtk_signal_connect (GTK_OBJECT (shell), "delete-event", GTK_SIGNAL_FUNC (delete_event_cb), f); | |
899 | |
900 { | |
901 static char *events_to_frob[] = { "focus-in-event", | |
902 "focus-out-event", | |
903 "enter-notify-event", | |
904 "leave-notify-event", | |
905 "map-event", | |
906 "unmap-event", | |
907 "property-notify-event", | |
908 "selection-clear-event", | |
909 "selection-request-event", | |
910 "selection-notify-event", | |
911 "client-event", | |
912 /* "configure-event", */ | |
913 "visibility-notify-event", | |
914 NULL }; | |
915 int i; | |
916 | |
917 for (i = 0; events_to_frob[i]; i++) | |
918 { | |
919 gtk_signal_connect (GTK_OBJECT (shell), events_to_frob[i], | |
920 GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); | |
921 } | |
922 } | |
923 | |
924 gtk_signal_connect (GTK_OBJECT (shell), "size-allocate", GTK_SIGNAL_FUNC (resize_event_cb), f); | |
925 | |
926 /* This might be safe to call now... */ | |
927 /* gtk_signal_connect (GTK_OBJECT (shell), "event", GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); */ | |
928 | |
929 /* Let's make sure we get all the events we can */ | |
930 gtk_widget_set_events (text, GDK_ALL_EVENTS_MASK); | |
931 | |
932 if (shell != container) | |
933 gtk_container_add (GTK_CONTAINER (shell), container); | |
934 | |
935 gtk_widget_set_name (shell, "XEmacs::shell"); | |
936 gtk_widget_set_name (container, "XEmacs::container"); | |
937 gtk_widget_set_name (text, "XEmacs::text"); | |
938 | |
939 FRAME_GTK_LISP_WIDGETS(f)[0] = build_gtk_object (GTK_OBJECT (shell)); | |
940 FRAME_GTK_LISP_WIDGETS(f)[1] = build_gtk_object (GTK_OBJECT (container)); | |
941 FRAME_GTK_LISP_WIDGETS(f)[2] = build_gtk_object (GTK_OBJECT (text)); | |
942 | |
943 gtk_widget_realize (shell); | |
944 } | |
945 | |
946 /* create the windows for the specified frame and display them. | |
947 Note that the widgets have already been created, and any | |
948 necessary geometry calculations have already been done. */ | |
949 static void | |
950 gtk_popup_frame (struct frame *f) | |
951 { | |
952 /* */ | |
953 | |
954 if (gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), UNMAPPED_DATA_IDENTIFIER)) | |
955 { | |
956 FRAME_GTK_TOTALLY_VISIBLE_P (f) = 0; | |
957 f->visible = 0; | |
958 gtk_widget_realize (FRAME_GTK_SHELL_WIDGET (f)); | |
959 gtk_widget_realize (FRAME_GTK_TEXT_WIDGET (f)); | |
960 gtk_widget_hide_all (FRAME_GTK_SHELL_WIDGET (f)); | |
961 } | |
962 else | |
963 { | |
964 gtk_widget_show_all (FRAME_GTK_SHELL_WIDGET (f)); | |
965 } | |
966 } | |
967 | |
968 static void | |
969 allocate_gtk_frame_struct (struct frame *f) | |
970 { | |
1346 | 971 int i; |
972 | |
462 | 973 /* zero out all slots. */ |
3092 | 974 #ifdef NEW_GC |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5126
diff
changeset
|
975 f->frame_data = XGTK_FRAME (ALLOC_NORMAL_LISP_OBJECT (gtk_frame)); |
3092 | 976 #else /* not NEW_GC */ |
462 | 977 f->frame_data = xnew_and_zero (struct gtk_frame); |
3092 | 978 #endif /* not NEW_GC */ |
462 | 979 |
980 /* yeah, except the lisp ones */ | |
981 FRAME_GTK_ICON_PIXMAP (f) = Qnil; | |
982 FRAME_GTK_ICON_PIXMAP_MASK (f) = Qnil; | |
1346 | 983 FRAME_GTK_MENUBAR_DATA (f) = Qnil; |
984 for (i = 0; i < 3; i++) | |
985 FRAME_GTK_LISP_WIDGETS (f)[i] = Qnil; | |
2168 | 986 |
987 /* | |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
988 Hashtables of callback data for glyphs on the frame. [[ Make them EQ |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
989 because we only use ints as keys. Otherwise we run into stickiness in |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
990 redisplay because internal_equal() can QUIT. See |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
991 enter_redisplay_critical_section() ]] -- probably not true any more, |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
992 now that we have internal_equal_trapping_problems(). --ben |
2168 | 993 */ |
994 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f) = | |
995 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
996 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f) = | |
997 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
998 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f) = | |
999 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
462 | 1000 } |
1001 | |
1002 | |
1003 /************************************************************************/ | |
1004 /* Lisp functions */ | |
1005 /************************************************************************/ | |
1006 | |
1007 static void | |
771 | 1008 gtk_init_frame_1 (struct frame *f, Lisp_Object props, |
2286 | 1009 int UNUSED (frame_name_is_defaulted)) |
462 | 1010 { |
1011 /* This function can GC */ | |
1012 Lisp_Object initially_unmapped; | |
1013 Lisp_Object device = FRAME_DEVICE (f); | |
1014 Lisp_Object lisp_window_id = Fplist_get (props, Qwindow_id, Qnil); | |
1015 Lisp_Object popup = Fplist_get (props, Qpopup, Qnil); | |
1016 | |
1017 if (!NILP (popup)) | |
1018 { | |
1019 if (EQ (popup, Qt)) | |
1020 popup = Fselected_frame (device); | |
1021 CHECK_LIVE_FRAME (popup); | |
1022 if (!EQ (device, FRAME_DEVICE (XFRAME (popup)))) | |
563 | 1023 invalid_argument_2 ("Parent must be on same device as frame", |
1024 device, popup); | |
462 | 1025 } |
1026 | |
1027 initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil); | |
1028 | |
1029 /* | |
1030 * Previously we set this only if NILP (DEVICE_SELECTED_FRAME (d)) | |
1031 * to make sure that messages were displayed as soon as possible | |
1032 * if we're creating the first frame on a device. But it is | |
1033 * better to just set this all the time, so that when a new frame | |
1034 * is created that covers the selected frame, echo area status | |
1035 * messages can still be seen. f->visible is reset later if the | |
1036 * initially-unmapped property is found to be non-nil in the | |
1037 * frame properties. | |
1038 */ | |
1039 f->visible = 1; | |
1040 | |
1041 allocate_gtk_frame_struct (f); | |
1042 gtk_create_widgets (f, lisp_window_id, popup); | |
1043 | |
1044 if (!NILP (initially_unmapped)) | |
1045 { | |
1046 gtk_object_set_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), | |
1047 UNMAPPED_DATA_IDENTIFIER, (gpointer) 1); | |
1048 } | |
1049 } | |
1050 | |
1051 static void | |
2286 | 1052 gtk_init_frame_2 (struct frame *f, Lisp_Object UNUSED (props)) |
462 | 1053 { |
1054 /* Set up the values of the widget/frame. A case could be made for putting | |
1055 this inside of the widget's initialize method. */ | |
1056 | |
1057 update_frame_face_values (f); | |
1058 gtk_initialize_frame_size (f); | |
1059 /* Kyle: | |
1060 * update_frame_title() can't be done here, because some of the | |
1061 * modeline specs depend on the frame's device having a selected | |
1062 * frame, and that may not have been set up yet. The redisplay | |
1063 * will update the frame title anyway, so nothing is lost. | |
1064 * JV: | |
1065 * It turns out it gives problems with FVWMs name based mapping. | |
1066 * We'll just need to be carefull in the modeline specs. | |
1067 */ | |
1068 update_frame_title (f); | |
1069 } | |
1070 | |
1071 static void | |
1072 gtk_init_frame_3 (struct frame *f) | |
1073 { | |
1074 /* Pop up the frame. */ | |
1075 gtk_popup_frame (f); | |
1076 } | |
1077 | |
1078 static void | |
1079 gtk_mark_frame (struct frame *f) | |
1080 { | |
1081 mark_object (FRAME_GTK_ICON_PIXMAP (f)); | |
1082 mark_object (FRAME_GTK_ICON_PIXMAP_MASK (f)); | |
1346 | 1083 mark_object (FRAME_GTK_MENUBAR_DATA (f)); |
462 | 1084 mark_object (FRAME_GTK_LISP_WIDGETS (f)[0]); |
1085 mark_object (FRAME_GTK_LISP_WIDGETS (f)[1]); | |
1086 mark_object (FRAME_GTK_LISP_WIDGETS (f)[2]); | |
2168 | 1087 mark_object (FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f)); |
1088 mark_object (FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f)); | |
1089 mark_object (FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f)); | |
462 | 1090 } |
1091 | |
1092 static void | |
1093 gtk_set_frame_icon (struct frame *f) | |
1094 { | |
1095 GdkPixmap *gtk_pixmap = NULL, *gtk_mask = NULL; | |
1096 | |
1097 if (IMAGE_INSTANCEP (f->icon) | |
1098 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon))) | |
1099 { | |
1100 gtk_pixmap = XIMAGE_INSTANCE_GTK_PIXMAP (f->icon); | |
1101 gtk_mask = XIMAGE_INSTANCE_GTK_MASK (f->icon); | |
1102 } | |
1103 else | |
1104 { | |
1105 gtk_pixmap = 0; | |
1106 gtk_mask = 0; | |
1107 } | |
1108 | |
1109 gdk_window_set_icon (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)), NULL, gtk_pixmap, gtk_mask); | |
1110 } | |
1111 | |
1112 static void | |
1113 gtk_set_frame_pointer (struct frame *f) | |
1114 { | |
1115 GtkWidget *w = FRAME_GTK_TEXT_WIDGET (f); | |
1116 GdkCursor *c = XIMAGE_INSTANCE_GTK_CURSOR (f->pointer); | |
1117 | |
1118 if (POINTER_IMAGE_INSTANCEP (f->pointer)) | |
1119 { | |
1120 gdk_window_set_cursor (GET_GTK_WIDGET_WINDOW (w), c); | |
1121 gdk_flush (); | |
1122 } | |
1123 else | |
1124 { | |
2500 | 1125 /* ABORT()? */ |
462 | 1126 stderr_out ("POINTER_IMAGE_INSTANCEP (f->pointer) failed!\n"); |
1127 } | |
1128 } | |
1129 | |
1130 static Lisp_Object | |
1131 gtk_get_frame_parent (struct frame *f) | |
1132 { | |
2054 | 1133 GtkWidget *parentwid = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), |
1134 TRANSIENT_DATA_IDENTIFIER); | |
462 | 1135 |
1136 /* find the frame whose wid is parentwid */ | |
1137 if (parentwid) | |
1138 { | |
1139 Lisp_Object frmcons; | |
1140 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f))) | |
1141 { | |
1142 Lisp_Object frame = XCAR (frmcons); | |
1143 if (FRAME_GTK_SHELL_WIDGET (XFRAME (frame)) == parentwid) | |
1144 return frame; | |
1145 } | |
1146 } | |
1147 return Qnil; | |
1148 } | |
1149 | |
1150 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1151 DEFUN ("gtk-window-id", Fgtk_window_id, 0, 1, 0, /* | |
1152 Get the ID of the Gtk window. | |
1153 This gives us a chance to manipulate the Emacs window from within a | |
1154 different program. Since the ID is an unsigned long, we return it as | |
1155 a string. | |
1156 */ | |
1157 (frame)) | |
1158 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
1159 Ascbyte str[255]; |
462 | 1160 struct frame *f = decode_gtk_frame (frame); |
1161 | |
1162 /* Arrrrggghhh... this defeats the whole purpose of using Gdk... do we really need this? */ | |
1163 sprintf (str, "%lu", GDK_WINDOW_XWINDOW( GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)))); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
1164 return build_ascstring (str); |
462 | 1165 } |
1166 #endif | |
1167 | |
1168 | |
1169 /************************************************************************/ | |
1170 /* manipulating the X window */ | |
1171 /************************************************************************/ | |
1172 | |
1173 static void | |
1174 gtk_set_frame_position (struct frame *f, int xoff, int yoff) | |
1175 { | |
1176 gtk_widget_set_uposition (FRAME_GTK_SHELL_WIDGET (f), xoff, yoff); | |
1177 } | |
1178 | |
1179 /* Call this to change the size of frame S's x-window. */ | |
1180 | |
1181 static void | |
1182 gtk_set_frame_size (struct frame *f, int cols, int rows) | |
1183 { | |
1184 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
1185 GdkGeometry geometry; | |
1186 | |
1187 if (GTK_IS_WINDOW (shell)) | |
1188 { | |
2054 | 1189 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC; |
1190 | |
462 | 1191 /* Update the cell size */ |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1192 default_face_width_and_height (wrap_frame (f), &geometry.width_inc, |
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1193 &geometry.height_inc); |
462 | 1194 |
1195 gtk_window_set_geometry_hints (GTK_WINDOW (shell), | |
1196 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask); | |
1197 } | |
1198 | |
5043 | 1199 change_frame_size (f, cols, rows, 0); |
462 | 1200 |
1201 { | |
1202 GtkRequisition req; | |
1203 | |
1204 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req); | |
1205 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height); | |
1206 } | |
1207 } | |
1208 | |
1209 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1210 /* There is NO equivalent to XWarpPointer under Gtk */ | |
1211 static void | |
1212 gtk_set_mouse_position (struct window *w, int x, int y) | |
1213 { | |
1214 struct frame *f = XFRAME (w->frame); | |
1215 Display *display = GDK_DISPLAY (); | |
1216 XWarpPointer (display, None, | |
1217 GDK_WINDOW_XWINDOW (GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f))), | |
1218 0, 0, 0, 0, w->pixel_left + x, w->pixel_top + y); | |
1219 } | |
1220 #endif /* STUPID_X_SPECIFIC_GTK_STUFF */ | |
1221 | |
1222 static int | |
1223 gtk_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y) | |
1224 { | |
1225 /* Returns the pixel position within the editor text widget */ | |
1226 gint win_x, win_y; | |
1227 GdkWindow *w = gdk_window_at_pointer (&win_x, &win_y); | |
1228 struct frame *f = NULL; | |
1229 | |
1230 if (!w) return (0); | |
1231 | |
1232 /* At this point, w is the innermost GdkWindow containing the | |
1233 ** pointer and win_x and win_y are the coordinates of that window. | |
1234 */ | |
1235 f = gtk_any_window_to_frame (d, w); | |
1236 | |
1237 if (!f) return (0); | |
1238 | |
793 | 1239 *frame = wrap_frame (f); |
462 | 1240 |
1241 gdk_window_get_pointer (GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)), | |
1242 &win_x, &win_y, NULL); | |
1243 | |
1244 *x = win_x; | |
1245 *y = win_y; | |
1246 | |
1247 return (1); | |
1248 } | |
1249 | |
2268 | 1250 static DECLARE_DOESNT_RETURN (gtk_cant_notify_wm_error (void)); |
1251 | |
1252 static DOESNT_RETURN | |
1253 gtk_cant_notify_wm_error () | |
462 | 1254 { |
563 | 1255 signal_error (Qgui_error, "Can't notify window manager of iconification", Qunbound); |
462 | 1256 } |
1257 | |
1258 /* Raise frame F. */ | |
1259 static void | |
1260 gtk_raise_frame_1 (struct frame *f, int force) | |
1261 { | |
1262 if (FRAME_VISIBLE_P (f) || force) | |
1263 { | |
1264 GdkWindow *emacs_window = GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)); | |
1265 | |
1266 gdk_window_raise (emacs_window); | |
1267 } | |
1268 } | |
1269 | |
1270 static void | |
1271 gtk_raise_frame (struct frame *f) | |
1272 { | |
1273 gtk_raise_frame_1 (f, 1); | |
1274 } | |
1275 | |
1276 /* Lower frame F. */ | |
1277 static void | |
1278 gtk_lower_frame (struct frame *f) | |
1279 { | |
1280 if (FRAME_VISIBLE_P (f)) | |
1281 { | |
1282 gdk_window_lower (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f))); | |
1283 } | |
1284 } | |
1285 | |
1286 /* Change from withdrawn state to mapped state. */ | |
1287 static void | |
1288 gtk_make_frame_visible (struct frame *f) | |
1289 { | |
2195 | 1290 gtk_widget_map (FRAME_GTK_SHELL_WIDGET (f)); |
462 | 1291 gtk_raise_frame_1 (f, 0); |
1292 } | |
1293 | |
1294 /* Change from mapped state to withdrawn state. */ | |
1295 static void | |
1296 gtk_make_frame_invisible (struct frame *f) | |
1297 { | |
2195 | 1298 gtk_widget_unmap(FRAME_GTK_SHELL_WIDGET (f)); |
462 | 1299 } |
1300 | |
1301 static int | |
1302 gtk_frame_visible_p (struct frame *f) | |
1303 { | |
1304 GtkWidget *w = FRAME_GTK_SHELL_WIDGET (f); | |
1305 | |
1306 f->visible = (GTK_OBJECT_FLAGS (w) & GTK_VISIBLE); | |
1307 | |
1308 return f->visible; | |
1309 } | |
1310 | |
1311 static int | |
1312 gtk_frame_totally_visible_p (struct frame *f) | |
1313 { | |
1314 return FRAME_GTK_TOTALLY_VISIBLE_P (f); | |
1315 } | |
1316 | |
1317 /* Change window state from mapped to iconified. */ | |
1318 static void | |
1319 gtk_iconify_frame (struct frame *f) | |
1320 { | |
1321 GdkWindow *w = GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)); | |
1322 | |
1323 /* There is no equivalent to XIconifyWindow in Gtk/Gdk. */ | |
1324 if (!XIconifyWindow (GDK_WINDOW_XDISPLAY (w), | |
1325 GDK_WINDOW_XWINDOW (w), | |
1326 DefaultScreen (GDK_WINDOW_XDISPLAY (w)))) | |
1327 gtk_cant_notify_wm_error (); | |
1328 | |
1329 f->iconified = 1; | |
1330 } | |
1331 | |
1332 /* Sets the X focus to frame f. */ | |
1333 static void | |
1334 gtk_focus_on_frame (struct frame *f) | |
1335 { | |
1336 GtkWidget *shell_widget; | |
1337 | |
1338 assert (FRAME_GTK_P (f)); | |
1339 | |
1340 shell_widget = FRAME_GTK_SHELL_WIDGET (f); | |
1341 if (!GET_GTK_WIDGET_WINDOW (shell_widget)) | |
1342 return; | |
1343 | |
1344 gtk_widget_grab_focus (shell_widget); | |
1345 } | |
1346 | |
1347 /* Destroy the window of frame S. */ | |
1348 static void | |
1349 gtk_delete_frame (struct frame *f) | |
1350 { | |
1351 GtkWidget *w = FRAME_GTK_SHELL_WIDGET (f); | |
1352 | |
1353 gtk_widget_destroy (w); | |
1354 | |
1355 if (FRAME_GTK_GEOM_FREE_ME_PLEASE (f)) | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1356 xfree (FRAME_GTK_GEOM_FREE_ME_PLEASE (f)); |
4117 | 1357 #ifndef NEW_GC |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1358 xfree (f->frame_data); |
3092 | 1359 #endif /* not NEW_GC */ |
462 | 1360 f->frame_data = 0; |
1361 } | |
1362 | |
1363 static void | |
1364 gtk_recompute_cell_sizes (struct frame *frm) | |
1365 { | |
1366 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (frm))) | |
1367 { | |
1368 GtkWindow *w = GTK_WINDOW (FRAME_GTK_SHELL_WIDGET (frm)); | |
1369 GdkGeometry geometry; | |
1370 GdkWindowHints geometry_mask; | |
1371 gint width_inc = 10; | |
1372 gint height_inc = 10; | |
1373 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1374 default_face_width_and_height (wrap_frame (frm), &width_inc, &height_inc); |
462 | 1375 geometry_mask = GDK_HINT_RESIZE_INC; |
1376 geometry.width_inc = width_inc; | |
1377 geometry.height_inc = height_inc; | |
1378 | |
1379 gtk_window_set_geometry_hints (w, FRAME_GTK_TEXT_WIDGET (frm), &geometry, geometry_mask); | |
1380 } | |
1381 } | |
1382 | |
1383 static void | |
1384 gtk_update_frame_external_traits (struct frame* frm, Lisp_Object name) | |
1385 { | |
1386 Lisp_Object frame = Qnil; | |
1387 | |
793 | 1388 frame = wrap_frame (frm); |
462 | 1389 |
1390 if (EQ (name, Qforeground)) | |
1391 { | |
1392 Lisp_Object color = FACE_FOREGROUND (Vdefault_face, frame); | |
1393 GdkColor *fgc; | |
1394 | |
1395 if (!EQ (color, Vthe_null_color_instance)) | |
1396 { | |
1397 fgc = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (color)); | |
1398 /* #### BILL!!! The X code set the XtNforeground property of | |
1399 the text widget here. Why did they bother? All that type | |
1400 of thing is done down in the guts of the redisplay code, | |
1401 not in the Emacs* widgets. */ | |
1402 } | |
1403 } | |
1404 else if (EQ (name, Qbackground)) | |
1405 { | |
1406 Lisp_Object color = FACE_BACKGROUND (Vdefault_face, frame); | |
1407 GdkColor *bgc; | |
1408 | |
1409 if (!EQ (color, Vthe_null_color_instance)) | |
1410 { | |
1411 bgc = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (color)); | |
1412 if (FRAME_GTK_SHELL_WIDGET (frm)->window) | |
1413 { | |
1414 gdk_window_set_background (FRAME_GTK_SHELL_WIDGET (frm)->window, bgc); | |
1415 } | |
1416 if (FRAME_GTK_TEXT_WIDGET (frm)->window) | |
1417 { | |
1418 gdk_window_set_background (FRAME_GTK_TEXT_WIDGET (frm)->window, bgc); | |
1419 } | |
1420 } | |
1421 | |
1422 /* Really crappy way to force the modeline shadows to be | |
1423 redrawn. But effective. */ | |
1424 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (frm); | |
1425 MARK_FRAME_CHANGED (frm); | |
1426 } | |
1427 else if (EQ (name, Qfont)) | |
1428 { | |
1429 Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii); | |
1430 | |
3676 | 1431 /* It may be that instantiating the font has deleted the frame (will |
1432 happen if the user has specified a charset registry for ASCII that | |
1433 isn't available on the server, and our fallback of iso8859-1 isn't | |
1434 available; something vanishingly rare.) In that case, return from | |
1435 this function. */ | |
1436 | |
1437 if (!FRAME_LIVE_P(frm)) | |
1438 { | |
1439 return; | |
1440 } | |
1441 | |
462 | 1442 if (!EQ (font, Vthe_null_font_instance)) |
1443 { | |
1444 /* #### BILL!!! The X code set the XtNfont property of the | |
1445 text widget here. Why did they bother? All that type of | |
1446 thing is done down in the guts of the redisplay code, not | |
1447 in the Emacs* widgets. */ | |
1448 } | |
1449 } | |
1450 else | |
2500 | 1451 ABORT (); |
462 | 1452 |
1453 #ifdef HAVE_TOOLBARS | |
1454 /* Setting the background clears the entire frame area | |
1455 including the toolbar so we force an immediate redraw of | |
1456 it. */ | |
1457 if (EQ (name, Qbackground)) | |
1458 MAYBE_DEVMETH (XDEVICE (frm->device), redraw_frame_toolbars, (frm)); | |
1459 #endif /* HAVE_TOOLBARS */ | |
1460 | |
1461 /* Set window manager resize increment hints according to | |
1462 the new character size */ | |
1463 if (EQ (name, Qfont) && FRAME_GTK_TOP_LEVEL_FRAME_P (frm)) | |
1464 gtk_recompute_cell_sizes (frm); | |
1465 } | |
1466 | |
1467 | |
1468 /************************************************************************/ | |
1469 /* initialization */ | |
1470 /************************************************************************/ | |
1471 | |
1472 void | |
1473 syms_of_frame_gtk (void) | |
1474 { | |
3092 | 1475 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
1476 INIT_LISP_OBJECT (gtk_frame); |
3092 | 1477 #endif /* NEW_GC */ |
1478 | |
563 | 1479 DEFSYMBOL (Qtext_widget); |
1480 DEFSYMBOL (Qcontainer_widget); | |
1481 DEFSYMBOL (Qshell_widget); | |
1482 DEFSYMBOL (Qdetachable_menubar); | |
462 | 1483 |
1484 #ifdef HAVE_DRAGNDROP | |
1485 staticpro (&Vcurrent_drag_object); | |
1486 Vcurrent_drag_object = Qnil; | |
1487 DEFSUBR (Fgtk_start_drag_internal); | |
1488 #endif | |
1489 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1490 DEFSUBR (Fgtk_window_id); | |
1491 #endif | |
1492 } | |
1493 | |
1494 void | |
1495 console_type_create_frame_gtk (void) | |
1496 { | |
1497 /* frame methods */ | |
1498 CONSOLE_HAS_METHOD (gtk, init_frame_1); | |
1499 CONSOLE_HAS_METHOD (gtk, init_frame_2); | |
1500 CONSOLE_HAS_METHOD (gtk, init_frame_3); | |
1501 CONSOLE_HAS_METHOD (gtk, mark_frame); | |
1502 CONSOLE_HAS_METHOD (gtk, focus_on_frame); | |
1503 CONSOLE_HAS_METHOD (gtk, delete_frame); | |
1504 CONSOLE_HAS_METHOD (gtk, get_mouse_position); | |
1505 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1506 CONSOLE_HAS_METHOD (gtk, set_mouse_position); | |
1507 #endif | |
1508 CONSOLE_HAS_METHOD (gtk, raise_frame); | |
1509 CONSOLE_HAS_METHOD (gtk, lower_frame); | |
1510 CONSOLE_HAS_METHOD (gtk, make_frame_visible); | |
1511 CONSOLE_HAS_METHOD (gtk, make_frame_invisible); | |
1512 CONSOLE_HAS_METHOD (gtk, iconify_frame); | |
1513 CONSOLE_HAS_METHOD (gtk, set_frame_size); | |
1514 CONSOLE_HAS_METHOD (gtk, set_frame_position); | |
1515 CONSOLE_HAS_METHOD (gtk, frame_property); | |
1516 CONSOLE_HAS_METHOD (gtk, internal_frame_property_p); | |
1517 CONSOLE_HAS_METHOD (gtk, frame_properties); | |
1518 CONSOLE_HAS_METHOD (gtk, set_frame_properties); | |
867 | 1519 CONSOLE_HAS_METHOD (gtk, set_title_from_ibyte); |
1520 CONSOLE_HAS_METHOD (gtk, set_icon_name_from_ibyte); | |
462 | 1521 CONSOLE_HAS_METHOD (gtk, frame_visible_p); |
1522 CONSOLE_HAS_METHOD (gtk, frame_totally_visible_p); | |
1523 CONSOLE_HAS_METHOD (gtk, frame_iconified_p); | |
1524 CONSOLE_HAS_METHOD (gtk, set_frame_pointer); | |
1525 CONSOLE_HAS_METHOD (gtk, set_frame_icon); | |
1526 CONSOLE_HAS_METHOD (gtk, get_frame_parent); | |
1527 CONSOLE_HAS_METHOD (gtk, update_frame_external_traits); | |
1528 } | |
1529 | |
1530 void | |
1531 vars_of_frame_gtk (void) | |
1532 { | |
1533 DEFVAR_LISP ("default-gtk-frame-plist", &Vdefault_gtk_frame_plist /* | |
1534 Plist of default frame-creation properties for Gtk frames. | |
1535 These override what is specified in the resource database and in | |
1536 `default-frame-plist', but are overridden by the arguments to the | |
1537 particular call to `make-frame'. | |
1538 | |
1539 Note: In many cases, properties of a frame are available as specifiers | |
1540 instead of through the frame-properties mechanism. | |
1541 | |
1542 Here is a list of recognized frame properties, other than those | |
1543 documented in `set-frame-properties' (they can be queried and | |
1544 set at any time, except as otherwise noted): | |
1545 | |
1546 initially-unmapped If non-nil, the frame will not be visible | |
1547 when it is created. In this case, you | |
1548 need to call `make-frame-visible' to make | |
1549 the frame appear. | |
1550 popup If non-nil, it should be a frame, and this | |
1551 frame will be created as a "popup" frame | |
1552 whose parent is the given frame. This | |
1553 will make the window manager treat the | |
1554 frame as a dialog box, which may entail | |
1555 doing different things (e.g. not asking | |
1556 for positioning, and not iconifying | |
1557 separate from its parent). | |
1558 inter-line-space Not currently implemented. | |
1559 toolbar-shadow-thickness Thickness of toolbar shadows. | |
1560 background-toolbar-color Color of toolbar background. | |
1561 bottom-toolbar-shadow-color Color of bottom shadows on toolbars. | |
1562 (*Not* specific to the bottom-toolbar.) | |
1563 top-toolbar-shadow-color Color of top shadows on toolbars. | |
1564 (*Not* specific to the top-toolbar.) | |
1565 internal-border-width Width of internal border around text area. | |
1566 border-width Width of external border around text area. | |
1567 top Y position (in pixels) of the upper-left | |
1568 outermost corner of the frame (i.e. the | |
1569 upper-left of the window-manager | |
1570 decorations). | |
1571 left X position (in pixels) of the upper-left | |
1572 outermost corner of the frame (i.e. the | |
1573 upper-left of the window-manager | |
1574 decorations). | |
1575 border-color Color of external border around text area. | |
1576 cursor-color Color of text cursor. | |
1577 | |
1578 See also `default-frame-plist', which specifies properties which apply | |
1579 to all frames, not just Gtk frames. | |
1580 */ ); | |
1581 Vdefault_gtk_frame_plist = Qnil; | |
1582 | |
1583 gtk_console_methods->device_specific_frame_props = &Vdefault_gtk_frame_plist; | |
1584 } |