Mercurial > hg > xemacs-beta
annotate src/frame-gtk.c @ 4952:19a72041c5ed
Mule-izing, various fixes related to char * arguments
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
* postgresql/postgresql.c (CHECK_LIVE_CONNECTION):
* postgresql/postgresql.c (print_pgresult):
* postgresql/postgresql.c (Fpq_conn_defaults):
* postgresql/postgresql.c (Fpq_connectdb):
* postgresql/postgresql.c (Fpq_connect_start):
* postgresql/postgresql.c (Fpq_result_status):
* postgresql/postgresql.c (Fpq_res_status):
Mule-ize large parts of it.
2010-01-26 Ben Wing <ben@xemacs.org>
* ldap/eldap.c (print_ldap):
* ldap/eldap.c (allocate_ldap):
Use write_ascstring().
src/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (build_ascstring):
* alloc.c (build_msg_cistring):
* alloc.c (staticpro_1):
* alloc.c (staticpro_name):
* alloc.c (staticpro_nodump_1):
* alloc.c (staticpro_nodump_name):
* alloc.c (unstaticpro_nodump_1):
* alloc.c (mcpro_1):
* alloc.c (mcpro_name):
* alloc.c (object_memory_usage_stats):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_once_early):
* buffer.c (print_buffer):
* buffer.c (vars_of_buffer):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.c (init_initial_directory):
* bytecode.c (invalid_byte_code):
* bytecode.c (print_compiled_function):
* bytecode.c (mark_compiled_function):
* chartab.c (print_table_entry):
* chartab.c (print_char_table):
* config.h.in:
* console-gtk.c:
* console-gtk.c (gtk_device_to_console_connection):
* console-gtk.c (gtk_semi_canonicalize_console_connection):
* console-gtk.c (gtk_canonicalize_console_connection):
* console-gtk.c (gtk_semi_canonicalize_device_connection):
* console-gtk.c (gtk_canonicalize_device_connection):
* console-stream.c (stream_init_frame_1):
* console-stream.c (vars_of_console_stream):
* console-stream.c (init_console_stream):
* console-x.c (x_semi_canonicalize_console_connection):
* console-x.c (x_semi_canonicalize_device_connection):
* console-x.c (x_canonicalize_device_connection):
* console-x.h:
* data.c (eq_with_ebola_notice):
* data.c (Fsubr_interactive):
* data.c (Fnumber_to_string):
* data.c (digit_to_number):
* device-gtk.c (gtk_init_device):
* device-msw.c (print_devmode):
* device-x.c (x_event_name):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-msw.c (handle_file_dialog_box):
* dialog-msw.c (vars_of_dialog_mswindows):
* doc.c (weird_doc):
* doc.c (Fsnarf_documentation):
* doc.c (vars_of_doc):
* dumper.c (pdump):
* dynarr.c:
* dynarr.c (Dynarr_realloc):
* editfns.c (Fuser_real_login_name):
* editfns.c (get_home_directory):
* elhash.c (print_hash_table_data):
* elhash.c (print_hash_table):
* emacs.c (main_1):
* emacs.c (vars_of_emacs):
* emodules.c:
* emodules.c (_emodules_list):
* emodules.c (Fload_module):
* emodules.c (Funload_module):
* emodules.c (Flist_modules):
* emodules.c (find_make_module):
* emodules.c (attempt_module_delete):
* emodules.c (emodules_load):
* emodules.c (emodules_doc_subr):
* emodules.c (emodules_doc_sym):
* emodules.c (syms_of_module):
* emodules.c (vars_of_module):
* emodules.h:
* eval.c (print_subr):
* eval.c (signal_call_debugger):
* eval.c (build_error_data):
* eval.c (signal_error):
* eval.c (maybe_signal_error):
* eval.c (signal_continuable_error):
* eval.c (maybe_signal_continuable_error):
* eval.c (signal_error_2):
* eval.c (maybe_signal_error_2):
* eval.c (signal_continuable_error_2):
* eval.c (maybe_signal_continuable_error_2):
* eval.c (signal_ferror):
* eval.c (maybe_signal_ferror):
* eval.c (signal_continuable_ferror):
* eval.c (maybe_signal_continuable_ferror):
* eval.c (signal_ferror_with_frob):
* eval.c (maybe_signal_ferror_with_frob):
* eval.c (signal_continuable_ferror_with_frob):
* eval.c (maybe_signal_continuable_ferror_with_frob):
* eval.c (syntax_error):
* eval.c (syntax_error_2):
* eval.c (maybe_syntax_error):
* eval.c (sferror):
* eval.c (sferror_2):
* eval.c (maybe_sferror):
* eval.c (invalid_argument):
* eval.c (invalid_argument_2):
* eval.c (maybe_invalid_argument):
* eval.c (invalid_constant):
* eval.c (invalid_constant_2):
* eval.c (maybe_invalid_constant):
* eval.c (invalid_operation):
* eval.c (invalid_operation_2):
* eval.c (maybe_invalid_operation):
* eval.c (invalid_change):
* eval.c (invalid_change_2):
* eval.c (maybe_invalid_change):
* eval.c (invalid_state):
* eval.c (invalid_state_2):
* eval.c (maybe_invalid_state):
* eval.c (wtaerror):
* eval.c (stack_overflow):
* eval.c (out_of_memory):
* eval.c (print_multiple_value):
* eval.c (issue_call_trapping_problems_warning):
* eval.c (backtrace_specials):
* eval.c (backtrace_unevalled_args):
* eval.c (Fbacktrace):
* eval.c (warn_when_safe):
* event-Xt.c (modwarn):
* event-Xt.c (modbarf):
* event-Xt.c (check_modifier):
* event-Xt.c (store_modifier):
* event-Xt.c (emacs_Xt_format_magic_event):
* event-Xt.c (describe_event):
* event-gtk.c (dragndrop_data_received):
* event-gtk.c (store_modifier):
* event-gtk.c (gtk_reset_modifier_mapping):
* event-msw.c (dde_eval_string):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (FROB):
* event-msw.c (emacs_mswindows_format_magic_event):
* event-stream.c (external_debugging_print_event):
* event-stream.c (execute_help_form):
* event-stream.c (vars_of_event_stream):
* events.c (print_event_1):
* events.c (print_event):
* events.c (event_equal):
* extents.c (print_extent_1):
* extents.c (print_extent):
* extents.c (vars_of_extents):
* faces.c (print_face):
* faces.c (complex_vars_of_faces):
* file-coding.c:
* file-coding.c (print_coding_system):
* file-coding.c (print_coding_system_in_print_method):
* file-coding.c (default_query_method):
* file-coding.c (find_coding_system):
* file-coding.c (make_coding_system_1):
* file-coding.c (chain_print):
* file-coding.c (undecided_print):
* file-coding.c (gzip_print):
* file-coding.c (vars_of_file_coding):
* file-coding.c (complex_vars_of_file_coding):
* fileio.c:
* fileio.c (report_file_type_error):
* fileio.c (report_error_with_errno):
* fileio.c (report_file_error):
* fileio.c (barf_or_query_if_file_exists):
* fileio.c (vars_of_fileio):
* floatfns.c (matherr):
* fns.c (print_bit_vector):
* fns.c (Fmapconcat):
* fns.c (add_suffix_to_symbol):
* fns.c (add_prefix_to_symbol):
* frame-gtk.c:
* frame-gtk.c (Fgtk_window_id):
* frame-x.c (def):
* frame-x.c (x_cde_transfer_callback):
* frame.c:
* frame.c (Fmake_frame):
* gc.c (show_gc_cursor_and_message):
* gc.c (vars_of_gc):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate):
* glyphs-gtk.c (gtk_print_image_instance):
* glyphs-msw.c (mswindows_print_image_instance):
* glyphs-x.c (x_print_image_instance):
* glyphs-x.c (update_widget_face):
* glyphs.c (make_string_from_file):
* glyphs.c (print_image_instance):
* glyphs.c (signal_image_error):
* glyphs.c (signal_image_error_2):
* glyphs.c (signal_double_image_error):
* glyphs.c (signal_double_image_error_2):
* glyphs.c (xbm_mask_file_munging):
* glyphs.c (pixmap_to_lisp_data):
* glyphs.h:
* gui.c (gui_item_display_flush_left):
* hpplay.c (player_error_internal):
* hpplay.c (myHandler):
* intl-win32.c:
* intl-win32.c (langcode_to_lang):
* intl-win32.c (sublangcode_to_lang):
* intl-win32.c (Fmswindows_get_locale_info):
* intl-win32.c (lcid_to_locale_mule_or_no):
* intl-win32.c (mswindows_multibyte_to_unicode_print):
* intl-win32.c (complex_vars_of_intl_win32):
* keymap.c:
* keymap.c (print_keymap):
* keymap.c (ensure_meta_prefix_char_keymapp):
* keymap.c (Fkey_description):
* keymap.c (Ftext_char_description):
* lisp.h:
* lisp.h (struct):
* lisp.h (DECLARE_INLINE_HEADER):
* lread.c (Fload_internal):
* lread.c (locate_file):
* lread.c (read_escape):
* lread.c (read_raw_string):
* lread.c (read1):
* lread.c (read_list):
* lread.c (read_compiled_function):
* lread.c (init_lread):
* lrecord.h:
* marker.c (print_marker):
* marker.c (marker_equal):
* menubar-msw.c (displayable_menu_item):
* menubar-x.c (command_builder_operate_menu_accelerator):
* menubar.c (vars_of_menubar):
* minibuf.c (reinit_complex_vars_of_minibuf):
* minibuf.c (complex_vars_of_minibuf):
* mule-charset.c (Fmake_charset):
* mule-charset.c (complex_vars_of_mule_charset):
* mule-coding.c (iso2022_print):
* mule-coding.c (fixed_width_query):
* number.c (bignum_print):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-msw.c:
* objects-msw.c (mswindows_color_to_string):
* objects-msw.c (mswindows_color_list):
* objects-tty.c:
* objects-tty.c (tty_font_list):
* objects-tty.c (tty_find_charset_font):
* objects-xlike-inc.c (xft_find_charset_font):
* objects-xlike-inc.c (endif):
* print.c:
* print.c (write_istring):
* print.c (write_ascstring):
* print.c (Fterpri):
* print.c (Fprint):
* print.c (print_error_message):
* print.c (print_vector_internal):
* print.c (print_cons):
* print.c (print_string):
* print.c (printing_unreadable_object):
* print.c (print_internal):
* print.c (print_float):
* print.c (print_symbol):
* process-nt.c (mswindows_report_winsock_error):
* process-nt.c (nt_canonicalize_host_name):
* process-unix.c (unix_canonicalize_host_name):
* process.c (print_process):
* process.c (report_process_error):
* process.c (report_network_error):
* process.c (make_process_internal):
* process.c (Fstart_process_internal):
* process.c (status_message):
* process.c (putenv_internal):
* process.c (vars_of_process):
* process.h:
* profile.c (vars_of_profile):
* rangetab.c (print_range_table):
* realpath.c (vars_of_realpath):
* redisplay.c (vars_of_redisplay):
* search.c (wordify):
* search.c (Freplace_match):
* sheap.c (sheap_adjust_h):
* sound.c (report_sound_error):
* sound.c (Fplay_sound_file):
* specifier.c (print_specifier):
* symbols.c (Fsubr_name):
* symbols.c (do_symval_forwarding):
* symbols.c (set_default_buffer_slot_variable):
* symbols.c (set_default_console_slot_variable):
* symbols.c (store_symval_forwarding):
* symbols.c (default_value):
* symbols.c (defsymbol_massage_name_1):
* symbols.c (defsymbol_massage_name_nodump):
* symbols.c (defsymbol_massage_name):
* symbols.c (defsymbol_massage_multiword_predicate_nodump):
* symbols.c (defsymbol_massage_multiword_predicate):
* symbols.c (defsymbol_nodump):
* symbols.c (defsymbol):
* symbols.c (defkeyword):
* symbols.c (defkeyword_massage_name):
* symbols.c (check_module_subr):
* symbols.c (deferror_1):
* symbols.c (deferror):
* symbols.c (deferror_massage_name):
* symbols.c (deferror_massage_name_and_message):
* symbols.c (defvar_magic):
* symeval.h:
* symeval.h (DEFVAR_SYMVAL_FWD):
* sysdep.c:
* sysdep.c (init_system_name):
* sysdll.c:
* sysdll.c (MAYBE_PREPEND_UNDERSCORE):
* sysdll.c (dll_function):
* sysdll.c (dll_variable):
* sysdll.c (dll_error):
* sysdll.c (dll_open):
* sysdll.c (dll_close):
* sysdll.c (image_for_address):
* sysdll.c (my_find_image):
* sysdll.c (search_linked_libs):
* sysdll.h:
* sysfile.h:
* sysfile.h (DEFAULT_DIRECTORY_FALLBACK):
* syswindows.h:
* tests.c (DFC_CHECK_LENGTH):
* tests.c (DFC_CHECK_CONTENT):
* tests.c (Ftest_hash_tables):
* text.c (vars_of_text):
* text.h:
* tooltalk.c (tt_opnum_string):
* tooltalk.c (tt_message_arg_ival_string):
* tooltalk.c (Ftooltalk_default_procid):
* tooltalk.c (Ftooltalk_default_session):
* tooltalk.c (init_tooltalk):
* tooltalk.c (vars_of_tooltalk):
* ui-gtk.c (Fdll_load):
* ui-gtk.c (type_to_marshaller_type):
* ui-gtk.c (Fgtk_import_function_internal):
* ui-gtk.c (emacs_gtk_object_printer):
* ui-gtk.c (emacs_gtk_boxed_printer):
* unicode.c (unicode_to_ichar):
* unicode.c (unicode_print):
* unicode.c (unicode_query):
* unicode.c (vars_of_unicode):
* unicode.c (complex_vars_of_unicode):
* win32.c:
* win32.c (mswindows_report_process_error):
* window.c (print_window):
* xemacs.def.in.in:
BASIC IDEA: Further fixing up uses of char * and CIbyte *
to reflect their actual semantics; Mule-izing some code;
redoing of the not-yet-working code to handle message translation.
Clean up code to handle message-translation (not yet working).
Create separate versions of build_msg_string() for working with
Ibyte *, CIbyte *, and Ascbyte * arguments. Assert that Ascbyte *
arguments are pure-ASCII. Make build_msg_string() be the same
as build_msg_ascstring(). Create same three versions of GETTEXT()
and DEFER_GETTEXT(). Also create build_defer_string() and
variants for the equivalent of DEFER_GETTEXT() when building a
string. Remove old CGETTEXT(). Clean up code where GETTEXT(),
DEFER_GETTEXT(), build_msg_string(), etc. was being called and
introduce some new calls to build_msg_string(), etc. Remove
GETTEXT() from calls to weird_doc() -- we assume that the
message snarfer knows about weird_doc(). Remove uses of
DEFER_GETTEXT() from error messages in sysdep.c and instead use
special comments /* @@@begin-snarf@@@ */ and /* @@@end-snarf@@@ */
that the message snarfer presumably knows about.
Create build_ascstring() and use it in many instances in place
of build_string(). The purpose of having Ascbyte * variants is
to make the code more self-documenting in terms of what sort of
semantics is expected for char * strings. In fact in the process
of looking for uses of build_string(), much improperly Mule-ized
was discovered.
Mule-ize a lot of code as described in previous paragraph,
e.g. in sysdep.c.
Make the error functions take Ascbyte * strings and fix up a
couple of places where non-pure-ASCII strings were being passed in
(file-coding.c, mule-coding.c, unicode.c). (It's debatable whether
we really need to make the error functions work this way. It
helps catch places where code is written in a way that message
translation won't work, but we may well never implement message
translation.)
Make staticpro() and friends take Ascbyte * strings instead of
raw char * strings. Create a const_Ascbyte_ptr dynarr type
to describe what's held by staticpro_names[] and friends,
create pdump descriptions for const_Ascbyte_ptr dynarrs, and
use them in place of specially-crafted staticpro descriptions.
Mule-ize certain other functions (e.g. x_event_name) by correcting
raw use of char * to Ascbyte *, Rawbyte * or another such type,
and raw use of char[] buffers to another type (usually Ascbyte[]).
Change many uses of write_c_string() to write_msg_string(),
write_ascstring(), etc.
Mule-ize emodules.c, emodules.h, sysdll.h.
Fix some un-Mule-ized code in intl-win32.c.
A comment in event-Xt.c and the limitations of the message
snarfer (make-msgfile or whatever) is presumably incorrect --
it should be smart enough to handle function calls spread over
more than one line. Clean up code in event-Xt.c that was
written awkwardly for this reason.
In config.h.in, instead of NEED_ERROR_CHECK_TYPES_INLINES,
create a more general XEMACS_DEFS_NEEDS_INLINE_DECLS to
indicate when inlined functions need to be declared in
xemacs.defs.in.in, and make use of it in xemacs.defs.in.in.
We need to do this because postgresql.c now calls qxestrdup(),
which is an inline function.
Make nconc2() and other such functions MODULE_API and put
them in xemacs.defs.in.in since postgresql.c now uses them.
Clean up indentation in lread.c and a few other places.
In text.h, document ASSERT_ASCTEXT_ASCII() and
ASSERT_ASCTEXT_ASCII_LEN(), group together the stand-in
encodings and add some more for DLL symbols, function and
variable names, etc.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Tue, 26 Jan 2010 23:22:30 -0600 |
parents | 229bd619740a |
children | e813cf16c015 |
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 | |
64 #include <gdk/gdkx.h> | |
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 { |
335 char *tmp; | |
336 C_STRING_TO_EXTERNAL (value, tmp, Qctext); | |
337 the_text = tmp; | |
338 break; | |
339 } | |
340 } | |
341 #endif /* MULE */ | |
342 | |
343 (*func) (arg, (gchar *) the_text); | |
344 } | |
345 | |
346 static void | |
867 | 347 gtk_set_title_from_ibyte (struct frame *f, Ibyte *name) |
462 | 348 { |
349 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (f))) | |
350 gtk_set_frame_text_value (f, name, | |
351 (void (*)(gpointer, gchar *)) | |
352 gtk_window_set_title, FRAME_GTK_SHELL_WIDGET (f)); | |
353 } | |
354 | |
355 static void | |
867 | 356 gtk_set_icon_name_from_ibyte (struct frame *f, Ibyte *name) |
462 | 357 { |
358 gtk_set_frame_text_value (f, name, | |
359 (void (*)(gpointer, gchar *)) | |
360 gdk_window_set_icon_name, FRAME_GTK_SHELL_WIDGET (f)->window); | |
361 } | |
362 | |
363 /* Set the initial frame size as specified. This function is used | |
364 when the frame's widgets have not yet been realized. | |
365 */ | |
366 static void | |
367 gtk_set_initial_frame_size (struct frame *f, int x, int y, | |
368 unsigned int w, unsigned int h) | |
369 { | |
370 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
371 GdkGeometry geometry; | |
372 | |
373 if (GTK_IS_WINDOW (shell)) | |
374 { | |
2054 | 375 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC; |
462 | 376 /* Deal with the cell size */ |
771 | 377 default_face_height_and_width (wrap_frame (f), &geometry.height_inc, &geometry.width_inc); |
462 | 378 |
379 gtk_window_set_geometry_hints (GTK_WINDOW (shell), | |
380 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask); | |
381 gdk_window_set_hints (GET_GTK_WIDGET_WINDOW (shell), x, y, 0, 0, 0, 0, GDK_HINT_POS); | |
382 gtk_window_set_policy (GTK_WINDOW (shell), TRUE, TRUE, FALSE); | |
383 } | |
384 | |
385 FRAME_HEIGHT (f) = h; | |
386 FRAME_WIDTH (f) = w; | |
387 | |
388 change_frame_size (f, h, w, 0); | |
389 { | |
390 GtkRequisition req; | |
391 | |
392 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req); | |
393 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height); | |
394 } | |
395 } | |
396 | |
397 /* Report that a frame property of frame S is being set or changed. | |
398 If the property is not specially recognized, do nothing. | |
399 */ | |
400 | |
401 static void | |
402 gtk_set_frame_properties (struct frame *f, Lisp_Object plist) | |
403 { | |
404 gint x, y; | |
405 gint width = 0, height = 0; | |
406 gboolean width_specified_p = FALSE; | |
407 gboolean height_specified_p = FALSE; | |
408 gboolean x_position_specified_p = FALSE; | |
409 gboolean y_position_specified_p = FALSE; | |
410 Lisp_Object tail; | |
411 | |
412 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | |
413 { | |
414 Lisp_Object prop = Fcar (tail); | |
415 Lisp_Object val = Fcar (Fcdr (tail)); | |
416 | |
417 if (SYMBOLP (prop)) | |
418 { | |
419 if (EQ (prop, Qfont)) | |
420 { | |
421 /* If the value is not a string we silently ignore it. */ | |
422 if (STRINGP (val)) | |
423 { | |
424 Lisp_Object frm, font_spec; | |
425 | |
793 | 426 frm = wrap_frame (f); |
462 | 427 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil); |
428 | |
429 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil); | |
430 update_frame_face_values (f); | |
431 } | |
432 continue; | |
433 } | |
434 else if (EQ (prop, Qwidth)) | |
435 { | |
436 CHECK_INT (val); | |
437 width = XINT (val); | |
438 width_specified_p = TRUE; | |
439 continue; | |
440 } | |
441 else if (EQ (prop, Qheight)) | |
442 { | |
443 CHECK_INT (val); | |
444 height = XINT (val); | |
445 height_specified_p = TRUE; | |
446 continue; | |
447 } | |
448 /* Further kludge the x/y. */ | |
449 else if (EQ (prop, Qx)) | |
450 { | |
451 CHECK_INT (val); | |
452 x = (gint) XINT (val); | |
453 x_position_specified_p = TRUE; | |
454 continue; | |
455 } | |
456 else if (EQ (prop, Qy)) | |
457 { | |
458 CHECK_INT (val); | |
459 y = (gint) XINT (val); | |
460 y_position_specified_p = TRUE; | |
461 continue; | |
462 } | |
463 } | |
464 } | |
465 | |
466 /* Kludge kludge kludge. We need to deal with the size and position | |
467 specially. */ | |
468 { | |
469 int size_specified_p = width_specified_p || height_specified_p; | |
470 int position_specified_p = x_position_specified_p || y_position_specified_p; | |
471 | |
472 if (!width_specified_p) | |
473 width = 80; | |
474 if (!height_specified_p) | |
475 height = 30; | |
476 | |
477 /* Kludge kludge kludge kludge. */ | |
478 if (position_specified_p && | |
479 (!x_position_specified_p || !y_position_specified_p)) | |
480 { | |
481 gint dummy; | |
482 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
483 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), | |
484 (x_position_specified_p ? &dummy : &x), | |
485 (y_position_specified_p ? &dummy : &y)); | |
486 } | |
487 | |
488 if (!f->init_finished) | |
489 { | |
490 if (size_specified_p || position_specified_p) | |
491 gtk_set_initial_frame_size (f, x, y, width, height); | |
492 } | |
493 else | |
494 { | |
495 if (size_specified_p) | |
496 { | |
793 | 497 Lisp_Object frame = wrap_frame (f); |
498 | |
462 | 499 Fset_frame_size (frame, make_int (width), make_int (height), Qnil); |
500 } | |
501 if (position_specified_p) | |
502 { | |
793 | 503 Lisp_Object frame = wrap_frame (f); |
504 | |
462 | 505 Fset_frame_position (frame, make_int (x), make_int (y)); |
506 } | |
507 } | |
508 } | |
509 } | |
510 | |
511 | |
512 /************************************************************************/ | |
513 /* widget creation */ | |
514 /************************************************************************/ | |
515 /* Figure out what size the shell widget should initially be, | |
516 and set it. Should be called after the default font has been | |
517 determined but before the widget has been realized. */ | |
518 | |
519 extern Lisp_Object Vgtk_initial_geometry; | |
520 | |
521 #ifndef HAVE_GNOME | |
522 static int | |
523 get_number (const char **geometry) | |
524 { | |
525 int value = 0; | |
526 int mult = 1; | |
527 | |
528 if (**geometry == '-'){ | |
529 mult = -1; | |
530 (*geometry)++; | |
531 } | |
532 while (**geometry && isdigit (**geometry)){ | |
533 value = value * 10 + (**geometry - '0'); | |
534 (*geometry)++; | |
535 } | |
536 return value * mult; | |
537 } | |
538 | |
539 /* | |
540 */ | |
541 | |
542 /** | |
543 * gnome_parse_geometry | |
544 * @geometry: geometry string to be parsed | |
545 * @xpos: X position geometry component | |
546 * @ypos: Y position geometry component | |
547 * @width: pixel width geometry component | |
548 * @height: pixel height geometry component | |
549 * | |
550 * Description: | |
551 * Parses the geometry string passed in @geometry, and fills | |
552 * @xpos, @ypos, @width, and @height with | |
553 * the corresponding values upon completion of the parse. | |
554 * If the parse fails, it should be assumed that @xpos, @ypos, @width, | |
555 * and @height contain undefined values. | |
556 * | |
557 * Returns: | |
558 * %TRUE if the geometry was successfully parsed, %FALSE otherwise. | |
559 **/ | |
560 | |
561 static gboolean | |
562 gnome_parse_geometry (const gchar *geometry, gint *xpos, | |
563 gint *ypos, gint *width, gint *height) | |
564 { | |
565 int subtract; | |
566 | |
567 g_return_val_if_fail (xpos != NULL, FALSE); | |
568 g_return_val_if_fail (ypos != NULL, FALSE); | |
569 g_return_val_if_fail (width != NULL, FALSE); | |
570 g_return_val_if_fail (height != NULL, FALSE); | |
571 | |
572 *xpos = *ypos = *width = *height = -1; | |
573 | |
574 if (!geometry) | |
575 return FALSE; | |
576 | |
577 if (*geometry == '=') | |
578 geometry++; | |
579 if (!*geometry) | |
580 return FALSE; | |
581 if (isdigit (*geometry)) | |
582 *width = get_number (&geometry); | |
583 if (!*geometry) | |
584 return TRUE; | |
585 if (*geometry == 'x' || *geometry == 'X'){ | |
586 geometry++; | |
587 *height = get_number (&geometry); | |
588 } | |
589 if (!*geometry) | |
590 return 1; | |
591 if (*geometry == '+'){ | |
592 subtract = 0; | |
593 geometry++; | |
594 } else if (*geometry == '-'){ | |
595 subtract = gdk_screen_width (); | |
596 geometry++; | |
597 } else | |
598 return FALSE; | |
599 *xpos = get_number (&geometry); | |
600 if (subtract) | |
601 *xpos = subtract - *xpos; | |
602 if (!*geometry) | |
603 return TRUE; | |
604 if (*geometry == '+'){ | |
605 subtract = 0; | |
606 geometry++; | |
607 } else if (*geometry == '-'){ | |
608 subtract = gdk_screen_height (); | |
609 geometry++; | |
610 } else | |
611 return FALSE; | |
612 *ypos = get_number (&geometry); | |
613 if (subtract) | |
614 *ypos = subtract - *ypos; | |
615 return TRUE; | |
616 } | |
617 #endif | |
618 | |
619 static void | |
620 gtk_initialize_frame_size (struct frame *f) | |
621 { | |
622 gint x = 10, y = 10, w = 80, h = 30; | |
623 | |
624 if (STRINGP (Vgtk_initial_geometry)) | |
625 { | |
2054 | 626 if (!gnome_parse_geometry ((char*) XSTRING_DATA (Vgtk_initial_geometry), &x,&y,&w,&h)) |
462 | 627 { |
628 x = y = 10; | |
629 w = 80; | |
630 h = 30; | |
631 } | |
632 } | |
633 | |
634 /* set the position of the frame's root window now. When the | |
635 frame was created, the position was initialized to (0,0). */ | |
636 { | |
637 struct window *win = XWINDOW (f->root_window); | |
638 | |
639 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f); | |
640 WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f); | |
641 | |
642 if (!NILP (f->minibuffer_window)) | |
643 { | |
644 win = XWINDOW (f->minibuffer_window); | |
645 WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f); | |
646 } | |
647 } | |
648 | |
649 gtk_set_initial_frame_size (f, x, y, w, h); | |
650 } | |
651 | |
652 static gboolean | |
2286 | 653 resize_event_cb (GtkWidget *UNUSED (w), GtkAllocation *allocation, |
654 gpointer user_data) | |
462 | 655 { |
656 struct frame *f = (struct frame *) user_data; | |
657 | |
658 f->pixwidth = allocation->width; | |
659 f->pixheight = allocation->height; | |
660 | |
661 if (FRAME_GTK_TEXT_WIDGET (f)->window) | |
662 { | |
793 | 663 Lisp_Object frame = wrap_frame (f); |
664 | |
462 | 665 Fredraw_frame (frame, Qt); |
666 } | |
667 | |
668 return (FALSE); | |
669 } | |
670 | |
671 static gboolean | |
2286 | 672 delete_event_cb (GtkWidget *UNUSED (w), GdkEvent *UNUSED (ev), |
673 gpointer user_data) | |
462 | 674 { |
675 struct frame *f = (struct frame *) user_data; | |
793 | 676 Lisp_Object frame = wrap_frame (f); |
462 | 677 |
678 enqueue_misc_user_event (frame, Qeval, list3 (Qdelete_frame, frame, Qt)); | |
679 | |
680 /* See if tickling the event queue helps us with our delays when | |
681 clicking 'close' */ | |
682 signal_fake_event (); | |
683 | |
684 return (TRUE); | |
685 } | |
686 | |
687 extern gboolean emacs_shell_event_handler (GtkWidget *wid, GdkEvent *event, gpointer closure); | |
688 extern Lisp_Object build_gtk_object (GtkObject *obj); | |
689 | |
690 #ifndef GNOME_IS_APP | |
691 #define GNOME_IS_APP(x) 0 | |
692 #define gnome_app_set_contents(x,y) 0 | |
693 #endif | |
694 | |
695 static void | |
696 cleanup_deleted_frame (gpointer data) | |
697 { | |
698 struct frame *f = (struct frame *) data; | |
793 | 699 Lisp_Object frame = wrap_frame (f); |
462 | 700 |
701 Fdelete_frame (frame, Qt); | |
702 } | |
703 | |
704 #ifdef HAVE_DRAGNDROP | |
705 extern void | |
706 dragndrop_data_received (GtkWidget *widget, | |
707 GdkDragContext *context, | |
708 gint x, | |
709 gint y, | |
710 GtkSelectionData *data, | |
711 guint info, | |
712 guint time); | |
713 | |
714 extern gboolean | |
715 dragndrop_dropped (GtkWidget *widget, | |
716 GdkDragContext *drag_context, | |
717 gint x, | |
718 gint y, | |
719 guint time, | |
720 gpointer user_data); | |
721 | |
722 Lisp_Object Vcurrent_drag_object; | |
723 | |
724 #define DRAG_SELECTION_DATA_ERROR "Error converting drag data to external format" | |
725 static void | |
2286 | 726 dragndrop_get_drag (GtkWidget *UNUSED (widget), |
727 GdkDragContext *UNUSED (drag_context), | |
462 | 728 GtkSelectionData *data, |
729 guint info, | |
2286 | 730 guint UNUSED (time), |
731 gpointer UNUSED (user_data)) | |
462 | 732 { |
733 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, 8, | |
734 DRAG_SELECTION_DATA_ERROR, | |
735 strlen (DRAG_SELECTION_DATA_ERROR)); | |
736 | |
737 switch (info) | |
738 { | |
739 case TARGET_TYPE_STRING: | |
740 { | |
741 Lisp_Object string = Vcurrent_drag_object; | |
742 | |
743 if (!STRINGP (Vcurrent_drag_object)) | |
744 { | |
745 string = Fprin1_to_string (string, Qnil); | |
746 /* Convert to a string */ | |
747 } | |
748 | |
749 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, | |
750 8, XSTRING_DATA (string), XSTRING_LENGTH (string)); | |
751 } | |
752 break; | |
753 case TARGET_TYPE_URI_LIST: | |
754 break; | |
755 default: | |
756 break; | |
757 } | |
758 Vcurrent_drag_object = Qnil; | |
759 } | |
760 | |
761 DEFUN ("gtk-start-drag-internal", Fgtk_start_drag_internal, 2, 3, 0, /* | |
762 Start a GTK drag from a buffer. | |
763 First arg is the event that started the drag, | |
764 second arg should be some string, and the third | |
765 is the type of the data (this should be a MIME type as a string (ie: text/plain)). | |
766 The type defaults to text/plain. | |
767 */ | |
768 (event, data, dtyp)) | |
769 { | |
770 if (EVENTP(event)) | |
771 { | |
772 struct frame *f = decode_gtk_frame (Fselected_frame (Qnil)); | |
773 GtkWidget *wid = FRAME_GTK_TEXT_WIDGET (f); | |
774 struct Lisp_Event *lisp_event = XEVENT(event); | |
775 GdkAtom dnd_typ; | |
776 GtkTargetList *tl = gtk_target_list_new (dnd_target_table, dnd_n_targets); | |
777 | |
778 /* only drag if this is really a press */ | |
779 if (EVENT_TYPE(lisp_event) != button_press_event) | |
780 return Qnil; | |
781 | |
782 /* get the desired type */ | |
783 if (!NILP (dtyp) && STRINGP (dtyp)) | |
784 dnd_typ = gdk_atom_intern (XSTRING_DATA (dtyp), FALSE); | |
785 | |
1204 | 786 gtk_drag_begin (wid, tl, GDK_ACTION_COPY, |
787 EVENT_BUTTON_BUTTON (lisp_event), NULL); | |
462 | 788 |
789 Vcurrent_drag_object = data; | |
790 | |
791 gtk_target_list_unref (tl); | |
792 } | |
793 return Qnil; | |
794 } | |
795 #endif | |
796 | |
797 /* Creates the widgets for a frame. | |
798 lisp_window_id is a Lisp description of an X window or Xt | |
799 widget to parse. | |
800 | |
801 This function does not map the windows. (That is | |
802 done by gtk_popup_frame().) | |
803 */ | |
804 static void | |
805 gtk_create_widgets (struct frame *f, Lisp_Object lisp_window_id, Lisp_Object parent) | |
806 { | |
807 const char *name; | |
808 GtkWidget *text, *container, *shell; | |
809 gboolean embedded_p = !NILP (lisp_window_id); | |
810 #ifdef HAVE_MENUBARS | |
811 int menubar_visible; | |
812 #endif | |
813 | |
814 if (STRINGP (f->name)) | |
815 TO_EXTERNAL_FORMAT (LISP_STRING, f->name, C_STRING_ALLOCA, name, Qctext); | |
816 else | |
817 name = "emacs"; | |
818 | |
819 FRAME_GTK_TOP_LEVEL_FRAME_P (f) = 1; | |
820 | |
821 if (embedded_p) | |
822 { | |
823 CHECK_GTK_OBJECT (lisp_window_id); | |
824 | |
825 if (!GTK_IS_CONTAINER (XGTK_OBJECT (lisp_window_id)->object)) | |
826 { | |
563 | 827 invalid_argument ("Window ID must be a GtkContainer subclass", lisp_window_id); |
462 | 828 } |
829 | |
830 shell = gtk_vbox_new (FALSE, 0); | |
831 | |
832 gtk_object_weakref (GTK_OBJECT (shell), cleanup_deleted_frame, f); | |
833 gtk_container_add (GTK_CONTAINER (XGTK_OBJECT (lisp_window_id)->object), shell); | |
834 } | |
835 else | |
836 { | |
837 #ifdef HAVE_GNOME | |
838 shell = GTK_WIDGET (gnome_app_new ("XEmacs", "XEmacs/GNOME")); | |
839 #else | |
840 shell = GTK_WIDGET (gtk_window_new (GTK_WINDOW_TOPLEVEL)); | |
841 #endif | |
842 } | |
843 | |
844 if (!NILP (parent)) | |
845 { | |
846 /* If this is a transient window, keep the parent info around */ | |
847 GtkWidget *parentwid = FRAME_GTK_SHELL_WIDGET (XFRAME (parent)); | |
848 gtk_object_set_data (GTK_OBJECT (shell), TRANSIENT_DATA_IDENTIFIER, parentwid); | |
849 gtk_window_set_transient_for (GTK_WINDOW (shell), GTK_WINDOW (parentwid)); | |
850 } | |
851 | |
852 gtk_container_set_border_width (GTK_CONTAINER (shell), 0); | |
853 | |
2168 | 854 /* Add a mapping from widget to frame to help widget callbacks quickly find |
855 their corresponding frame. */ | |
856 gtk_object_set_data (GTK_OBJECT (shell), GTK_DATA_FRAME_IDENTIFIER, f); | |
462 | 857 |
858 FRAME_GTK_SHELL_WIDGET (f) = shell; | |
859 | |
860 text = GTK_WIDGET (gtk_xemacs_new (f)); | |
861 | |
862 if (!GNOME_IS_APP (shell)) | |
863 container = GTK_WIDGET (gtk_vbox_new (FALSE, INTERNAL_BORDER_WIDTH)); | |
864 else | |
865 container = shell; | |
866 | |
867 FRAME_GTK_CONTAINER_WIDGET (f) = container; | |
868 FRAME_GTK_TEXT_WIDGET (f) = text; | |
869 | |
870 #ifdef HAVE_DRAGNDROP | |
871 gtk_drag_dest_set (text, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT, | |
872 dnd_target_table, dnd_n_targets, | |
873 GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK); | |
874 gtk_signal_connect (GTK_OBJECT (text), "drag_drop", | |
875 GTK_SIGNAL_FUNC (dragndrop_dropped), text); | |
876 gtk_signal_connect (GTK_OBJECT (text), "drag_data_received", | |
877 GTK_SIGNAL_FUNC (dragndrop_data_received), text); | |
878 gtk_signal_connect (GTK_OBJECT (text), "drag_data_get", | |
879 GTK_SIGNAL_FUNC (dragndrop_get_drag), NULL); | |
880 #endif | |
881 | |
882 #ifdef HAVE_MENUBARS | |
883 /* Create the initial menubar widget. */ | |
884 menubar_visible = gtk_initialize_frame_menubar (f); | |
885 | |
886 if (menubar_visible) | |
887 { | |
888 gtk_widget_show_all (FRAME_GTK_MENUBAR_WIDGET (f)); | |
889 } | |
890 #endif /* HAVE_MENUBARS */ | |
891 | |
892 if (GNOME_IS_APP (shell)) | |
893 gnome_app_set_contents (GNOME_APP (shell), text); | |
894 else | |
895 /* Now comes the drawing area, which should fill the rest of the | |
896 ** frame completely. | |
897 */ | |
898 gtk_box_pack_end (GTK_BOX (container), text, TRUE, TRUE, 0); | |
899 | |
900 /* Connect main event handler */ | |
901 gtk_signal_connect (GTK_OBJECT (shell), "delete-event", GTK_SIGNAL_FUNC (delete_event_cb), f); | |
902 | |
903 { | |
904 static char *events_to_frob[] = { "focus-in-event", | |
905 "focus-out-event", | |
906 "enter-notify-event", | |
907 "leave-notify-event", | |
908 "map-event", | |
909 "unmap-event", | |
910 "property-notify-event", | |
911 "selection-clear-event", | |
912 "selection-request-event", | |
913 "selection-notify-event", | |
914 "client-event", | |
915 /* "configure-event", */ | |
916 "visibility-notify-event", | |
917 NULL }; | |
918 int i; | |
919 | |
920 for (i = 0; events_to_frob[i]; i++) | |
921 { | |
922 gtk_signal_connect (GTK_OBJECT (shell), events_to_frob[i], | |
923 GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); | |
924 } | |
925 } | |
926 | |
927 gtk_signal_connect (GTK_OBJECT (shell), "size-allocate", GTK_SIGNAL_FUNC (resize_event_cb), f); | |
928 | |
929 /* This might be safe to call now... */ | |
930 /* gtk_signal_connect (GTK_OBJECT (shell), "event", GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); */ | |
931 | |
932 /* Let's make sure we get all the events we can */ | |
933 gtk_widget_set_events (text, GDK_ALL_EVENTS_MASK); | |
934 | |
935 if (shell != container) | |
936 gtk_container_add (GTK_CONTAINER (shell), container); | |
937 | |
938 gtk_widget_set_name (shell, "XEmacs::shell"); | |
939 gtk_widget_set_name (container, "XEmacs::container"); | |
940 gtk_widget_set_name (text, "XEmacs::text"); | |
941 | |
942 FRAME_GTK_LISP_WIDGETS(f)[0] = build_gtk_object (GTK_OBJECT (shell)); | |
943 FRAME_GTK_LISP_WIDGETS(f)[1] = build_gtk_object (GTK_OBJECT (container)); | |
944 FRAME_GTK_LISP_WIDGETS(f)[2] = build_gtk_object (GTK_OBJECT (text)); | |
945 | |
946 gtk_widget_realize (shell); | |
947 } | |
948 | |
949 /* create the windows for the specified frame and display them. | |
950 Note that the widgets have already been created, and any | |
951 necessary geometry calculations have already been done. */ | |
952 static void | |
953 gtk_popup_frame (struct frame *f) | |
954 { | |
955 /* */ | |
956 | |
957 if (gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), UNMAPPED_DATA_IDENTIFIER)) | |
958 { | |
959 FRAME_GTK_TOTALLY_VISIBLE_P (f) = 0; | |
960 f->visible = 0; | |
961 gtk_widget_realize (FRAME_GTK_SHELL_WIDGET (f)); | |
962 gtk_widget_realize (FRAME_GTK_TEXT_WIDGET (f)); | |
963 gtk_widget_hide_all (FRAME_GTK_SHELL_WIDGET (f)); | |
964 } | |
965 else | |
966 { | |
967 gtk_widget_show_all (FRAME_GTK_SHELL_WIDGET (f)); | |
968 } | |
969 } | |
970 | |
971 static void | |
972 allocate_gtk_frame_struct (struct frame *f) | |
973 { | |
1346 | 974 int i; |
975 | |
462 | 976 /* zero out all slots. */ |
3092 | 977 #ifdef NEW_GC |
978 f->frame_data = alloc_lrecord_type (struct gtk_frame, &lrecord_gtk_frame); | |
979 #else /* not NEW_GC */ | |
462 | 980 f->frame_data = xnew_and_zero (struct gtk_frame); |
3092 | 981 #endif /* not NEW_GC */ |
462 | 982 |
983 /* yeah, except the lisp ones */ | |
984 FRAME_GTK_ICON_PIXMAP (f) = Qnil; | |
985 FRAME_GTK_ICON_PIXMAP_MASK (f) = Qnil; | |
1346 | 986 FRAME_GTK_MENUBAR_DATA (f) = Qnil; |
987 for (i = 0; i < 3; i++) | |
988 FRAME_GTK_LISP_WIDGETS (f)[i] = Qnil; | |
2168 | 989 |
990 /* | |
991 Hashtables of callback data for glyphs on the frame. Make them EQ because | |
992 we only use ints as keys. Otherwise we run into stickiness in redisplay | |
993 because internal_equal() can QUIT. See enter_redisplay_critical_section(). | |
994 */ | |
995 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f) = | |
996 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
997 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f) = | |
998 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
999 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f) = | |
1000 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
462 | 1001 } |
1002 | |
1003 | |
1004 /************************************************************************/ | |
1005 /* Lisp functions */ | |
1006 /************************************************************************/ | |
1007 | |
1008 static void | |
771 | 1009 gtk_init_frame_1 (struct frame *f, Lisp_Object props, |
2286 | 1010 int UNUSED (frame_name_is_defaulted)) |
462 | 1011 { |
1012 /* This function can GC */ | |
1013 Lisp_Object initially_unmapped; | |
1014 Lisp_Object device = FRAME_DEVICE (f); | |
1015 Lisp_Object lisp_window_id = Fplist_get (props, Qwindow_id, Qnil); | |
1016 Lisp_Object popup = Fplist_get (props, Qpopup, Qnil); | |
1017 | |
1018 if (!NILP (popup)) | |
1019 { | |
1020 if (EQ (popup, Qt)) | |
1021 popup = Fselected_frame (device); | |
1022 CHECK_LIVE_FRAME (popup); | |
1023 if (!EQ (device, FRAME_DEVICE (XFRAME (popup)))) | |
563 | 1024 invalid_argument_2 ("Parent must be on same device as frame", |
1025 device, popup); | |
462 | 1026 } |
1027 | |
1028 initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil); | |
1029 | |
1030 /* | |
1031 * Previously we set this only if NILP (DEVICE_SELECTED_FRAME (d)) | |
1032 * to make sure that messages were displayed as soon as possible | |
1033 * if we're creating the first frame on a device. But it is | |
1034 * better to just set this all the time, so that when a new frame | |
1035 * is created that covers the selected frame, echo area status | |
1036 * messages can still be seen. f->visible is reset later if the | |
1037 * initially-unmapped property is found to be non-nil in the | |
1038 * frame properties. | |
1039 */ | |
1040 f->visible = 1; | |
1041 | |
1042 allocate_gtk_frame_struct (f); | |
1043 gtk_create_widgets (f, lisp_window_id, popup); | |
1044 | |
1045 if (!NILP (initially_unmapped)) | |
1046 { | |
1047 gtk_object_set_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), | |
1048 UNMAPPED_DATA_IDENTIFIER, (gpointer) 1); | |
1049 } | |
1050 } | |
1051 | |
1052 static void | |
2286 | 1053 gtk_init_frame_2 (struct frame *f, Lisp_Object UNUSED (props)) |
462 | 1054 { |
1055 /* Set up the values of the widget/frame. A case could be made for putting | |
1056 this inside of the widget's initialize method. */ | |
1057 | |
1058 update_frame_face_values (f); | |
1059 gtk_initialize_frame_size (f); | |
1060 /* Kyle: | |
1061 * update_frame_title() can't be done here, because some of the | |
1062 * modeline specs depend on the frame's device having a selected | |
1063 * frame, and that may not have been set up yet. The redisplay | |
1064 * will update the frame title anyway, so nothing is lost. | |
1065 * JV: | |
1066 * It turns out it gives problems with FVWMs name based mapping. | |
1067 * We'll just need to be carefull in the modeline specs. | |
1068 */ | |
1069 update_frame_title (f); | |
1070 } | |
1071 | |
1072 static void | |
1073 gtk_init_frame_3 (struct frame *f) | |
1074 { | |
1075 /* Pop up the frame. */ | |
1076 gtk_popup_frame (f); | |
1077 } | |
1078 | |
1079 static void | |
1080 gtk_mark_frame (struct frame *f) | |
1081 { | |
1082 mark_object (FRAME_GTK_ICON_PIXMAP (f)); | |
1083 mark_object (FRAME_GTK_ICON_PIXMAP_MASK (f)); | |
1346 | 1084 mark_object (FRAME_GTK_MENUBAR_DATA (f)); |
462 | 1085 mark_object (FRAME_GTK_LISP_WIDGETS (f)[0]); |
1086 mark_object (FRAME_GTK_LISP_WIDGETS (f)[1]); | |
1087 mark_object (FRAME_GTK_LISP_WIDGETS (f)[2]); | |
2168 | 1088 mark_object (FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f)); |
1089 mark_object (FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f)); | |
1090 mark_object (FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f)); | |
462 | 1091 } |
1092 | |
1093 static void | |
1094 gtk_set_frame_icon (struct frame *f) | |
1095 { | |
1096 GdkPixmap *gtk_pixmap = NULL, *gtk_mask = NULL; | |
1097 | |
1098 if (IMAGE_INSTANCEP (f->icon) | |
1099 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon))) | |
1100 { | |
1101 gtk_pixmap = XIMAGE_INSTANCE_GTK_PIXMAP (f->icon); | |
1102 gtk_mask = XIMAGE_INSTANCE_GTK_MASK (f->icon); | |
1103 } | |
1104 else | |
1105 { | |
1106 gtk_pixmap = 0; | |
1107 gtk_mask = 0; | |
1108 } | |
1109 | |
1110 gdk_window_set_icon (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)), NULL, gtk_pixmap, gtk_mask); | |
1111 } | |
1112 | |
1113 static void | |
1114 gtk_set_frame_pointer (struct frame *f) | |
1115 { | |
1116 GtkWidget *w = FRAME_GTK_TEXT_WIDGET (f); | |
1117 GdkCursor *c = XIMAGE_INSTANCE_GTK_CURSOR (f->pointer); | |
1118 | |
1119 if (POINTER_IMAGE_INSTANCEP (f->pointer)) | |
1120 { | |
1121 gdk_window_set_cursor (GET_GTK_WIDGET_WINDOW (w), c); | |
1122 gdk_flush (); | |
1123 } | |
1124 else | |
1125 { | |
2500 | 1126 /* ABORT()? */ |
462 | 1127 stderr_out ("POINTER_IMAGE_INSTANCEP (f->pointer) failed!\n"); |
1128 } | |
1129 } | |
1130 | |
1131 static Lisp_Object | |
1132 gtk_get_frame_parent (struct frame *f) | |
1133 { | |
2054 | 1134 GtkWidget *parentwid = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), |
1135 TRANSIENT_DATA_IDENTIFIER); | |
462 | 1136 |
1137 /* find the frame whose wid is parentwid */ | |
1138 if (parentwid) | |
1139 { | |
1140 Lisp_Object frmcons; | |
1141 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f))) | |
1142 { | |
1143 Lisp_Object frame = XCAR (frmcons); | |
1144 if (FRAME_GTK_SHELL_WIDGET (XFRAME (frame)) == parentwid) | |
1145 return frame; | |
1146 } | |
1147 } | |
1148 return Qnil; | |
1149 } | |
1150 | |
1151 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1152 DEFUN ("gtk-window-id", Fgtk_window_id, 0, 1, 0, /* | |
1153 Get the ID of the Gtk window. | |
1154 This gives us a chance to manipulate the Emacs window from within a | |
1155 different program. Since the ID is an unsigned long, we return it as | |
1156 a string. | |
1157 */ | |
1158 (frame)) | |
1159 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
1160 Ascbyte str[255]; |
462 | 1161 struct frame *f = decode_gtk_frame (frame); |
1162 | |
1163 /* Arrrrggghhh... this defeats the whole purpose of using Gdk... do we really need this? */ | |
1164 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
|
1165 return build_ascstring (str); |
462 | 1166 } |
1167 #endif | |
1168 | |
1169 | |
1170 /************************************************************************/ | |
1171 /* manipulating the X window */ | |
1172 /************************************************************************/ | |
1173 | |
1174 static void | |
1175 gtk_set_frame_position (struct frame *f, int xoff, int yoff) | |
1176 { | |
1177 gtk_widget_set_uposition (FRAME_GTK_SHELL_WIDGET (f), xoff, yoff); | |
1178 } | |
1179 | |
1180 /* Call this to change the size of frame S's x-window. */ | |
1181 | |
1182 static void | |
1183 gtk_set_frame_size (struct frame *f, int cols, int rows) | |
1184 { | |
1185 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
1186 GdkGeometry geometry; | |
1187 | |
1188 if (GTK_IS_WINDOW (shell)) | |
1189 { | |
2054 | 1190 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC; |
1191 | |
462 | 1192 /* Update the cell size */ |
771 | 1193 default_face_height_and_width (wrap_frame (f), &geometry.height_inc, &geometry.width_inc); |
462 | 1194 |
1195 gtk_window_set_geometry_hints (GTK_WINDOW (shell), | |
1196 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask); | |
1197 } | |
1198 | |
1199 change_frame_size (f, rows, cols, 0); | |
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)) | |
1726 | 1356 xfree (FRAME_GTK_GEOM_FREE_ME_PLEASE (f), char *); |
4117 | 1357 #ifndef NEW_GC |
1726 | 1358 xfree (f->frame_data, void *); |
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 | |
771 | 1374 default_face_height_and_width (wrap_frame (frm), &height_inc, &width_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 |
1476 INIT_LRECORD_IMPLEMENTATION (gtk_frame); | |
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 } |