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