view src/frame-msw.c @ 1204:e22b0213b713

[xemacs-hg @ 2003-01-12 11:07:58 by michaels] modules/ChangeLog: 2002-12-16 Ben Wing <ben@xemacs.org> * postgresql/postgresql.c: remove ifdef USE_KKCC. src/ChangeLog: 2003-01-08 Mike Sperber <mike@xemacs.org> * console.h (CDFW_CONSOLE): Don't lead to a crash if we're dealing with a dead window/frame/device/console. 2002-12-20 Mike Sperber <mike@xemacs.org> * ui-gtk.c: Fix typo from Ben's patch: emacs_ffi_data is a typedef, not a struct. emacs_gtk_object_data is a typedef, not a struct. * gtk-glue.c (gdk_event_to_emacs_event): Fix typos from Ben's patch: le -> emacs_event + rearrange the code. * event-gtk.c (gtk_event_to_emacs_event): Fix typos from Ben's patch: ..._UNDERLYING_GDK_EVENT -> ..._GDK_EVENT, ev -> key_event. * device-gtk.c: Fix typo from Ben's patch: x_keysym_map_hash_table -> x_keysym_map_hashtable. 2002-12-19 Mike Sperber <mike@xemacs.org> * menubar-x.c (set_frame_menubar): Initialize protect_me field of popup_data. 2002-12-16 Ben Wing <ben@xemacs.org> Major cleanup of KKCC, etc. KKCC, pdump-related: -- descriptions are written for all objects. this required some changes in the format of some objects, e.g. extents, popup-data, coding system, lstream, lcrecord-list. -- KKCC now handles weakness in markers, hash tables, elsewhere correctly (formerly, you'd eventually get a stack overflow due to endlessly expanding markers). -- textual changes: lrecord_description -> memory_description, struct_description -> sized_memory_description. -- extensive comment describing descriptions and pdump. -- redo XD_UNION so it works inline and change its format to provide sufficient info for pdump. implement XD_UNION in pdump. also add XD_UNION_DYNAMIC_SIZE, which works like XD_UNION except for when auto-computing structure sizes. -- add support for XD_INDIRECT in description offsets (used by extents). -- add support for "description maps", allowing for indirect descriptions that are retrieved from an object at run-time. this generalizes XD_CODING_SYSTEM_END, XD_SPECIFIER_END, etc., which have now been eliminated. -- add a fifth field "flags" to memory_description, to support flags that can be specified for this particular line. Currently defined flags are XD_FLAG_NO_KKCC (KKCC should ignore this entry; useful for the weakness above in markers, etc.), XD_FLAG_NO_PDUMP (pdump should ignore this entry), XD_FLAG_UNION_DEFAULT_ENTRY (in union maps, this specifies a "default" entry for all remaining values), and XD_FLAG_FREE_LISP_OBJECT (for use with lcrecord-lists). -- clean up the kkcc-itis in events, so that the differences between event data as separate objects and as a union are now minimized to a small number of places. with the new XD_UNION, we no longer need event data as separate objects, so this code is no longer ifdef USE_KKCC, but instead ifdef EVENT_DATA_AS_OBJECTS, not used by default. make sure that we explicitly free the separate event data objects when no longer in use, to maintain the invariant the event processing causes no consing. -- also remove other USE_KKCC ifdefs when not necessary. -- allow for KKCC compilation under MS Windows. -- fix README.kkcc. -- dump_add_root_object -> dump_add_root_lisp_object. -- implement dump_add_root_block and use this to handle dump_add_opaque. -- factor out some code duplicated in kkcc and pdump. Other allocation/object-related: -- change various *slots.h so MARKED_SLOT() call no longer includes semicolon. -- free_marker() takes a Lisp_Object not a direct pointer. -- make bit vectors lcrecords, like vectors, and eliminate code that essentially duplicated the lcrecord handling. -- additional asserts in FREE_FIXED_TYPE, formerly duplicated in the various callers of this. -- all lcrecord allocation functions now zero out the returned lcrecords. unnecessary calls to zero_lcrecord removed. add long comment describing these functions. -- extract out process and coding system slots, like for buffers, frames, etc. -- lcrecords now set the type of items sitting on the free list to lcrecord_type_free. -- changes to the way that gap arrays are allocated, for kkcc's benefit -- now, one single memory block with a stretchy array on the end, instead of a separate block holding the array. Error-checking-related: -- now can compile with C++ under MS Windows. clean up compile errors discovered that way. (a few were real problems) -- add C++ error-checking code to verify problems with mismatched GCPRO/UNGCPRO. (there were a few in the kkcc code.) add long comment about how to catch insufficient GCPRO (yes, it's possible using C++). -- add debug_p4(), a simple object printer, when debug_print() doesn't work. -- add dp() and db() as short synonyms of debug_print(), debug_backtrace(). -- `print' tries EXTREMELY hard to avoid core dumping when printing when crashing or from debug_print(), and tries as hard as it reasonably can in other situations. -- Correct the message output upon crashing to be more up-to-date. Event-related: -- document event-matches-key-specifier-p better. -- generalize the dispatch queues formerly duplicated in the various event implementations. add event methods to drain pending events. generalize and clean up QUIT handling, removing event-specific quit processing. allow arbitrary keystrokes, not just ASCII, to be the QUIT char. among other things, this should fix some longstanding bugs in X quit handling. long comment describing the various event queues. -- implement delaying of XFlush() if there are pending expose events. SOMEONE PLEASE TRY THIS OUT. -- Fix `xemacs -batch -l dunnet' under Cygwin. Try to fix under MS Windows but not quite there yet. Other: -- class -> class_ and no more C++ games with this item. new -> new_ in the lwlib code, so far not elsewhere. -- use `struct htentry' not `struct hentry' in elhash.c to avoid debugger confusion with hash.c. -- new macros ALIST_LOOP_3, ALIST_LOOP_4. * README.kkcc: * alloc.c: * alloc.c (deadbeef_memory): * alloc.c (allocate_lisp_storage): * alloc.c (copy_lisp_object): * alloc.c (ALLOCATE_FIXED_TYPE_1): * alloc.c (FREE_FIXED_TYPE): * alloc.c (make_vector_internal): * alloc.c (make_bit_vector_internal): * alloc.c (make_key_data): * alloc.c (make_button_data): * alloc.c (make_motion_data): * alloc.c (make_process_data): * alloc.c (make_timeout_data): * alloc.c (make_magic_data): * alloc.c (make_magic_eval_data): * alloc.c (make_eval_data): * alloc.c (make_misc_user_data): * alloc.c (struct string_chars_block): * alloc.c (mark_lcrecord_list): * alloc.c (make_lcrecord_list): * alloc.c (alloc_managed_lcrecord): * alloc.c (free_managed_lcrecord): * alloc.c (alloc_automanaged_lcrecord): * alloc.c (staticpro_1): * alloc.c (staticpro): * alloc.c (lispdesc_indirect_count_1): * alloc.c (lispdesc_indirect_description_1): * alloc.c (lispdesc_one_description_line_size): * alloc.c (lispdesc_structure_size): * alloc.c (mark_object_maybe_checking_free): * alloc.c (mark_with_description): * alloc.c (mark_struct_contents): * alloc.c (mark_object): * alloc.c (tick_lcrecord_stats): * alloc.c (free_cons): * alloc.c (free_key_data): * alloc.c (free_button_data): * alloc.c (free_motion_data): * alloc.c (free_process_data): * alloc.c (free_timeout_data): * alloc.c (free_magic_data): * alloc.c (free_magic_eval_data): * alloc.c (free_eval_data): * alloc.c (free_misc_user_data): * alloc.c (free_marker): * alloc.c (compact_string_chars): * alloc.c (gc_sweep): * alloc.c (garbage_collect_1): * alloc.c (Fgarbage_collect): * alloc.c (common_init_alloc_early): * alloc.c (init_alloc_early): * alloc.c (init_alloc_once_early): * buffer.c: * buffer.c (mark_buffer): * buffer.c (MARKED_SLOT): * buffer.c (cleanup_buffer_undo_lists): * buffer.c (Fget_file_buffer): * buffer.h (MARKED_SLOT): * bufslots.h: * bytecode.c: * callint.c: * casetab.c: * chartab.c: * chartab.c (symbol_to_char_table_type): * cmdloop.c: * cmdloop.c (Fcommand_loop_1): * config.h.in (new): * conslots.h: * console-gtk-impl.h (struct gtk_frame): * console-impl.h: * console-impl.h (struct console): * console-impl.h (MARKED_SLOT): * console-impl.h (CONSOLE_QUIT_EVENT): * console-msw-impl.h (XM_BUMPQUEUE): * console-msw.c (write_string_to_mswindows_debugging_output): * console-msw.h: * console-stream-impl.h: * console-stream-impl.h (struct stream_console): * console-stream.c: * console-stream.c (stream_init_console): * console-stream.h: * console-tty.c: * console-tty.h: * console-x.h: * console.c: * console.c (mark_console): * console.c (MARKED_SLOT): * console.c (allocate_console): * console.c (get_console_variant): * console.c (create_console): * console.c (delete_console_internal): * console.c (Fset_input_mode): * console.c (Fcurrent_input_mode): * console.c (common_init_complex_vars_of_console): * console.h: * console.h (console_variant): * console.h (device_metrics): * data.c: * data.c (Faref): * data.c (Faset): * data.c (decode_weak_list_type): * database.c: * debug.c (xemacs_debug_loop): * debug.c (FROB): * debug.c (Fadd_debug_class_to_check): * debug.c (Fdelete_debug_class_to_check): * debug.c (Fset_debug_classes_to_check): * debug.c (Fset_debug_class_types_to_check): * debug.c (Fdebug_types_being_checked): * debug.h (DASSERT): * device-gtk.c: * device-impl.h (struct device): * device-impl.h (MARKED_SLOT): * device-msw.c: * device-x.c: * device-x.c (x_init_device_class): * device-x.c (x_comp_visual_info): * device-x.c (x_try_best_visual_class): * device-x.c (x_init_device): * device-x.c (construct_name_list): * device-x.c (x_get_resource_prefix): * device-x.c (Fx_get_resource): * device-x.c (Fx_display_visual_class): * device.c: * device.c (MARKED_SLOT): * device.c (allocate_device): * device.c (Fmake_device): * device.c (delete_device_internal): * device.c (Fset_device_class): * device.h: * devslots.h: * devslots.h (MARKED_SLOT): * dialog-msw.c: * dired-msw.c (mswindows_ls_sort_fcn): * dired-msw.c (mswindows_get_files): * dired-msw.c (mswindows_format_file): * doprnt.c (parse_doprnt_spec): * dumper.c: * dumper.c (struct): * dumper.c (dump_add_root_block): * dumper.c (dump_add_root_struct_ptr): * dumper.c (dump_add_root_lisp_object): * dumper.c (pdump_struct_list_elt): * dumper.c (pdump_get_entry_list): * dumper.c (pdump_backtrace): * dumper.c (pdump_bump_depth): * dumper.c (pdump_register_sub): * dumper.c (pdump_register_object): * dumper.c (pdump_register_struct_contents): * dumper.c (pdump_register_struct): * dumper.c (pdump_store_new_pointer_offsets): * dumper.c (pdump_dump_data): * dumper.c (pdump_reloc_one): * dumper.c (pdump_allocate_offset): * dumper.c (pdump_scan_by_alignment): * dumper.c (pdump_dump_root_blocks): * dumper.c (pdump_dump_rtables): * dumper.c (pdump_dump_root_lisp_objects): * dumper.c (pdump): * dumper.c (pdump_load_finish): * dumper.c (pdump_file_get): * dumper.c (pdump_resource_get): * dumper.c (pdump_load): * editfns.c (save_excursion_restore): * editfns.c (user_login_name): * editfns.c (save_restriction_restore): * elhash.c: * elhash.c (htentry): * elhash.c (struct Lisp_Hash_Table): * elhash.c (HTENTRY_CLEAR_P): * elhash.c (LINEAR_PROBING_LOOP): * elhash.c (check_hash_table_invariants): * elhash.c (mark_hash_table): * elhash.c (hash_table_equal): * elhash.c (print_hash_table_data): * elhash.c (free_hentries): * elhash.c (make_general_lisp_hash_table): * elhash.c (decode_hash_table_weakness): * elhash.c (decode_hash_table_test): * elhash.c (Fcopy_hash_table): * elhash.c (resize_hash_table): * elhash.c (pdump_reorganize_hash_table): * elhash.c (find_htentry): * elhash.c (Fgethash): * elhash.c (Fputhash): * elhash.c (remhash_1): * elhash.c (Fremhash): * elhash.c (Fclrhash): * elhash.c (copy_compress_hentries): * elhash.c (elisp_maphash_unsafe): * elhash.c (finish_marking_weak_hash_tables): * elhash.c (prune_weak_hash_tables): * elhash.h: * emacs.c: * emacs.c (main_1): * emacs.c (main): * emacs.c (shut_down_emacs): * emodules.h (dump_add_root_lisp_object): * eval.c: * eval.c (unwind_to_catch): * eval.c (maybe_signal_error_1): * eval.c (maybe_signal_continuable_error_1): * eval.c (maybe_signal_error): * eval.c (maybe_signal_continuable_error): * eval.c (maybe_signal_error_2): * eval.c (maybe_signal_continuable_error_2): * eval.c (maybe_signal_ferror): * eval.c (maybe_signal_continuable_ferror): * eval.c (maybe_signal_ferror_with_frob): * eval.c (maybe_signal_continuable_ferror_with_frob): * eval.c (maybe_syntax_error): * eval.c (maybe_sferror): * eval.c (maybe_invalid_argument): * eval.c (maybe_invalid_constant): * eval.c (maybe_invalid_operation): * eval.c (maybe_invalid_change): * eval.c (maybe_invalid_state): * eval.c (Feval): * eval.c (call_trapping_problems): * eval.c (call_with_suspended_errors): * eval.c (warn_when_safe_lispobj): * eval.c (warn_when_safe): * eval.c (vars_of_eval): * event-Xt.c: * event-Xt.c (maybe_define_x_key_as_self_inserting_character): * event-Xt.c (x_to_emacs_keysym): * event-Xt.c (x_event_to_emacs_event): * event-Xt.c (emacs_Xt_enqueue_focus_event): * event-Xt.c (emacs_Xt_format_magic_event): * event-Xt.c (emacs_Xt_compare_magic_event): * event-Xt.c (emacs_Xt_hash_magic_event): * event-Xt.c (emacs_Xt_handle_magic_event): * event-Xt.c (Xt_timeout_to_emacs_event): * event-Xt.c (Xt_process_to_emacs_event): * event-Xt.c (signal_special_Xt_user_event): * event-Xt.c (emacs_Xt_next_event): * event-Xt.c (emacs_Xt_event_handler): * event-Xt.c (emacs_Xt_drain_queue): * event-Xt.c (emacs_Xt_event_pending_p): * event-Xt.c (check_if_pending_expose_event): * event-Xt.c (reinit_vars_of_event_Xt): * event-Xt.c (vars_of_event_Xt): * event-gtk.c: * event-gtk.c (IS_MODIFIER_KEY): * event-gtk.c (emacs_gtk_format_magic_event): * event-gtk.c (emacs_gtk_compare_magic_event): * event-gtk.c (emacs_gtk_hash_magic_event): * event-gtk.c (emacs_gtk_handle_magic_event): * event-gtk.c (gtk_to_emacs_keysym): * event-gtk.c (gtk_timeout_to_emacs_event): * event-gtk.c (gtk_process_to_emacs_event): * event-gtk.c (dragndrop_data_received): * event-gtk.c (signal_special_gtk_user_event): * event-gtk.c (emacs_gtk_next_event): * event-gtk.c (gtk_event_to_emacs_event): * event-gtk.c (generic_event_handler): * event-gtk.c (emacs_shell_event_handler): * event-gtk.c (emacs_gtk_drain_queue): * event-gtk.c (emacs_gtk_event_pending_p): * event-gtk.c (reinit_vars_of_event_gtk): * event-gtk.c (vars_of_event_gtk): * event-msw.c: * event-msw.c (struct winsock_stream): * event-msw.c (winsock_reader): * event-msw.c (winsock_writer): * event-msw.c (mswindows_enqueue_dispatch_event): * event-msw.c (mswindows_enqueue_misc_user_event): * event-msw.c (mswindows_enqueue_magic_event): * event-msw.c (mswindows_enqueue_process_event): * event-msw.c (mswindows_enqueue_mouse_button_event): * event-msw.c (mswindows_enqueue_keypress_event): * event-msw.c (mswindows_dequeue_dispatch_event): * event-msw.c (emacs_mswindows_drain_queue): * event-msw.c (mswindows_need_event_in_modal_loop): * event-msw.c (mswindows_need_event): * event-msw.c (mswindows_wm_timer_callback): * event-msw.c (dde_eval_string): * event-msw.c (Fdde_alloc_advise_item): * event-msw.c (mswindows_dde_callback): * event-msw.c (mswindows_wnd_proc): * event-msw.c (remove_timeout_mapper): * event-msw.c (emacs_mswindows_remove_timeout): * event-msw.c (emacs_mswindows_event_pending_p): * event-msw.c (emacs_mswindows_format_magic_event): * event-msw.c (emacs_mswindows_compare_magic_event): * event-msw.c (emacs_mswindows_hash_magic_event): * event-msw.c (emacs_mswindows_handle_magic_event): * event-msw.c (emacs_mswindows_select_console): * event-msw.c (emacs_mswindows_unselect_console): * event-msw.c (reinit_vars_of_event_mswindows): * event-msw.c (vars_of_event_mswindows): * event-stream.c: * event-stream.c (mark_command_builder): * event-stream.c (reset_command_builder_event_chain): * event-stream.c (allocate_command_builder): * event-stream.c (copy_command_builder): * event-stream.c (command_builder_append_event): * event-stream.c (event_stream_event_pending_p): * event-stream.c (event_stream_force_event_pending): * event-stream.c (maybe_read_quit_event): * event-stream.c (event_stream_drain_queue): * event-stream.c (remove_quit_p_event): * event-stream.c (event_stream_quit_p): * event-stream.c (echo_key_event): * event-stream.c (maybe_kbd_translate): * event-stream.c (execute_help_form): * event-stream.c (event_stream_generate_wakeup): * event-stream.c (enqueue_dispatch_event): * event-stream.c (enqueue_magic_eval_event): * event-stream.c (Fenqueue_eval_event): * event-stream.c (enqueue_misc_user_event): * event-stream.c (enqueue_misc_user_event_pos): * event-stream.c (next_event_internal): * event-stream.c (Fnext_event): * event-stream.c (Faccept_process_output): * event-stream.c (execute_internal_event): * event-stream.c (munge_keymap_translate): * event-stream.c (command_builder_find_leaf_no_mule_processing): * event-stream.c (command_builder_find_leaf): * event-stream.c (lookup_command_event): * event-stream.c (is_scrollbar_event): * event-stream.c (execute_command_event): * event-stream.c (Fdispatch_event): * event-stream.c (Fread_key_sequence): * event-stream.c (dribble_out_event): * event-stream.c (vars_of_event_stream): * event-tty.c (tty_timeout_to_emacs_event): * event-tty.c (emacs_tty_next_event): * event-tty.c (emacs_tty_drain_queue): * event-tty.c (reinit_vars_of_event_tty): * event-unixoid.c: * event-unixoid.c (find_tty_or_stream_console_from_fd): * event-unixoid.c (read_event_from_tty_or_stream_desc): * event-unixoid.c (drain_tty_devices): * event-unixoid.c (poll_fds_for_input): * events.c: * events.c (deinitialize_event): * events.c (zero_event): * events.c (mark_event): * events.c (print_event_1): * events.c (print_event): * events.c (event_equal): * events.c (event_hash): * events.c (Fmake_event): * events.c (Fdeallocate_event): * events.c (Fcopy_event): * events.c (map_event_chain_remove): * events.c (character_to_event): * events.c (event_to_character): * events.c (Fevent_to_character): * events.c (format_event_object): * events.c (upshift_event): * events.c (downshift_event): * events.c (event_upshifted_p): * events.c (Fevent_live_p): * events.c (Fevent_type): * events.c (Fevent_timestamp): * events.c (CHECK_EVENT_TYPE): * events.c (CHECK_EVENT_TYPE2): * events.c (CHECK_EVENT_TYPE3): * events.c (Fevent_key): * events.c (Fevent_button): * events.c (Fevent_modifier_bits): * events.c (event_x_y_pixel_internal): * events.c (event_pixel_translation): * events.c (Fevent_process): * events.c (Fevent_function): * events.c (Fevent_object): * events.c (Fevent_properties): * events.c (syms_of_events): * events.c (vars_of_events): * events.h: * events.h (struct event_stream): * events.h (struct Lisp_Key_Data): * events.h (KEY_DATA_KEYSYM): * events.h (EVENT_KEY_KEYSYM): * events.h (struct Lisp_Button_Data): * events.h (EVENT_BUTTON_BUTTON): * events.h (struct Lisp_Motion_Data): * events.h (EVENT_MOTION_X): * events.h (struct Lisp_Process_Data): * events.h (EVENT_PROCESS_PROCESS): * events.h (struct Lisp_Timeout_Data): * events.h (EVENT_TIMEOUT_INTERVAL_ID): * events.h (struct Lisp_Eval_Data): * events.h (EVENT_EVAL_FUNCTION): * events.h (struct Lisp_Misc_User_Data): * events.h (EVENT_MISC_USER_FUNCTION): * events.h (struct Lisp_Magic_Eval_Data): * events.h (EVENT_MAGIC_EVAL_INTERNAL_FUNCTION): * events.h (struct Lisp_Magic_Data): * events.h (EVENT_MAGIC_UNDERLYING): * events.h (EVENT_MAGIC_GDK_EVENT): * events.h (struct Lisp_Event): * events.h (XEVENT_CHANNEL): * events.h (SET_EVENT_TIMESTAMP_ZERO): * events.h (SET_EVENT_CHANNEL): * events.h (SET_EVENT_NEXT): * events.h (XSET_EVENT_TYPE): * events.h (struct command_builder): * extents.c: * extents.c (gap_array_adjust_markers): * extents.c (gap_array_recompute_derived_values): * extents.c (gap_array_move_gap): * extents.c (gap_array_make_gap): * extents.c (gap_array_insert_els): * extents.c (gap_array_delete_els): * extents.c (gap_array_make_marker): * extents.c (gap_array_delete_marker): * extents.c (gap_array_move_marker): * extents.c (make_gap_array): * extents.c (free_gap_array): * extents.c (extent_list_num_els): * extents.c (extent_list_insert): * extents.c (mark_extent_auxiliary): * extents.c (allocate_extent_auxiliary): * extents.c (decode_extent_at_flag): * extents.c (verify_extent_mapper): * extents.c (symbol_to_glyph_layout): * extents.c (syms_of_extents): * faces.c: * file-coding.c: * file-coding.c (struct_detector_category_description =): * file-coding.c (detector_category_dynarr_description_1): * file-coding.c (struct_detector_description =): * file-coding.c (detector_dynarr_description_1): * file-coding.c (MARKED_SLOT): * file-coding.c (mark_coding_system): * file-coding.c (coding_system_extra_description_map): * file-coding.c (coding_system_description): * file-coding.c (allocate_coding_system): * file-coding.c (symbol_to_eol_type): * file-coding.c (Fcoding_system_aliasee): * file-coding.c (set_coding_stream_coding_system): * file-coding.c (struct convert_eol_coding_system): * file-coding.c (struct undecided_coding_system): * file-coding.c (undecided_mark_coding_stream): * file-coding.c (coding_category_symbol_to_id): * file-coding.c (struct gzip_coding_system): * file-coding.c (coding_system_type_create): * file-coding.h: * file-coding.h (struct Lisp_Coding_System): * file-coding.h (CODING_SYSTEM_SLOT_DECLARATION): * file-coding.h (coding_system_variant): * file-coding.h (struct coding_system_methods): * file-coding.h (DEFINE_CODING_SYSTEM_TYPE_WITH_DATA): * file-coding.h (INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA): * file-coding.h (struct coding_stream): * fileio.c (Fsubstitute_in_file_name): * floatfns.c: * fns.c: * fns.c (base64_encode_1): * frame-gtk.c: * frame-gtk.c (Fgtk_start_drag_internal): * frame-impl.h (struct frame): * frame-impl.h (MARKED_SLOT): * frame-msw.c: * frame-x.c: * frame-x.c (Fcde_start_drag_internal): * frame-x.c (Foffix_start_drag_internal): * frame.c: * frame.c (MARKED_SLOT): * frame.c (allocate_frame_core): * frame.c (delete_frame_internal): * frame.c (Fmouse_position_as_motion_event): * frameslots.h: * frameslots.h (MARKED_SLOT_ARRAY): * free-hook.c: * glyphs-msw.c (mswindows_widget_instantiate): * glyphs-x.c: * glyphs-x.c (convert_EImage_to_XImage): * glyphs.c: * glyphs.c (process_image_string_instantiator): * glyphs.c (mark_image_instance): * glyphs.c (allocate_image_instance): * glyphs.c (unmap_subwindow): * glyphs.c (map_subwindow): * glyphs.c (syms_of_glyphs): * glyphs.c (specifier_type_create_image): * glyphs.h: * glyphs.h (struct text_image_instance): * glyphs.h (struct Lisp_Image_Instance): * gmalloc.c: * gmalloc.c ("C"): * gpmevent.c (Freceive_gpm_event): * gpmevent.c (gpm_next_event_cb): * gpmevent.c (vars_of_gpmevent): * gtk-glue.c (gdk_event_to_emacs_event): * gtk-xemacs.c (gtk_xemacs_class_init): * gui-msw.c: * gui-msw.c (mswindows_handle_gui_wm_command): * gui-msw.c (mswindows_translate_menu_or_dialog_item): * gui-x.c: * gui-x.c (mark_popup_data): * gui-x.c (snarf_widget_value_mapper): * gui-x.c (gcpro_popup_callbacks): * gui-x.c (ungcpro_popup_callbacks): * gui-x.c (free_popup_widget_value_tree): * gui-x.c (popup_selection_callback): * gui-x.h: * gui-x.h (struct popup_data): * gui.c: * gui.c (allocate_gui_item): * gutter.c (decode_gutter_position): * hash.c (NULL_ENTRY): * indent.c (vmotion_1): * indent.c (vmotion_pixels): * input-method-motif.c (res): * input-method-xlib.c (IMInstantiateCallback): * input-method-xlib.c (XIM_init_device): * input-method-xlib.c (res): * intl-encap-win32.c: * intl-encap-win32.c (qxeSHGetDataFromIDList): * intl-win32.c: * intl-win32.c (mswindows_multibyte_cp_type): * intl-win32.c (struct mswindows_multibyte_coding_system): * keymap.c: * keymap.c (make_key_description): * keymap.c (keymap_store): * keymap.c (get_keyelt): * keymap.c (keymap_lookup_1): * keymap.c (define_key_parser): * keymap.c (key_desc_list_to_event): * keymap.c (event_matches_key_specifier_p): * keymap.c (meta_prefix_char_p): * keymap.c (ensure_meta_prefix_char_keymapp): * keymap.c (Fdefine_key): * keymap.c (struct raw_lookup_key_mapper_closure): * keymap.c (raw_lookup_key): * keymap.c (raw_lookup_key_mapper): * keymap.c (lookup_keys): * keymap.c (lookup_events): * keymap.c (Flookup_key): * keymap.c (struct map_keymap_unsorted_closure): * keymap.c (map_keymap_unsorted_mapper): * keymap.c (map_keymap_sorted): * keymap.c (map_keymap_mapper): * keymap.c (map_keymap): * keymap.c (accessible_keymaps_mapper_1): * keymap.c (Faccessible_keymaps): * keymap.c (Fsingle_key_description): * keymap.c (raw_keys_to_keys): * keymap.c (format_raw_keys): * keymap.c (where_is_recursive_mapper): * keymap.c (where_is_internal): * keymap.c (describe_map_mapper_shadow_search): * keymap.c (keymap_lookup_inherited_mapper): * keymap.c (describe_map_mapper): * keymap.h (event_matches_key_specifier_p): * lisp.h: * lisp.h (this): * lisp.h (RETURN_NOT_REACHED): * lisp.h (struct Lisp_Vector): * lisp.h (struct Lisp_Bit_Vector): * lisp.h (UNGCPRO_1): * lisp.h (NUNGCPRO): * lisp.h (NNUNGCPRO): * lisp.h (DECLARE_INLINE_HEADER): * lrecord.h: * lrecord.h (struct lrecord_header): * lrecord.h (struct lcrecord_header): * lrecord.h (lrecord_type): * lrecord.h (struct lrecord_implementation): * lrecord.h (RECORD_DUMPABLE): * lrecord.h (memory_description_type): * lrecord.h (data_description_entry_flags): * lrecord.h (struct memory_description): * lrecord.h (struct sized_memory_description): * lrecord.h (XD_INDIRECT): * lrecord.h (XD_IS_INDIRECT): * lrecord.h (XD_DYNARR_DESC): * lrecord.h (DEFINE_BASIC_LRECORD_IMPLEMENTATION): * lrecord.h (MAKE_LRECORD_IMPLEMENTATION): * lrecord.h (MAKE_EXTERNAL_LRECORD_IMPLEMENTATION): * lrecord.h (alloc_lcrecord_type): * lstream.c: * lstream.c (Lstream_new): * lstream.c (lisp_buffer_marker): * lstream.h: * lstream.h (lstream_implementation): * lstream.h (DEFINE_LSTREAM_IMPLEMENTATION): * lstream.h (DEFINE_LSTREAM_IMPLEMENTATION_WITH_DATA): * marker.c: * marker.c (copy_marker_1): * mem-limits.h: * menubar-gtk.c: * menubar-gtk.c (gtk_popup_menu): * menubar-msw.c: * menubar-msw.c (mswindows_popup_menu): * menubar-x.c (make_dummy_xbutton_event): * menubar-x.c (command_builder_operate_menu_accelerator): * menubar-x.c (menu_accelerator_safe_compare): * menubar-x.c (menu_accelerator_safe_mod_compare): * mule-charset.c: * mule-charset.c (make_charset): * mule-charset.c (Fcharset_property): * mule-coding.c: * mule-coding.c (ccs_description_1): * mule-coding.c (ccs_description =): * mule-coding.c (ccsd_description_1): * mule-coding.c (ccsd_description =): * nt.c (getpwnam): * nt.c (init_mswindows_environment): * nt.c (get_cached_volume_information): * nt.c (mswindows_is_executable): * nt.c (read_unc_volume): * nt.c (mswindows_access): * nt.c (mswindows_link): * nt.c (mswindows_fstat): * nt.c (mswindows_stat): * nt.c (mswindows_executable_type): * nt.c (Fmswindows_short_file_name): * nt.c (Fmswindows_long_file_name): * objects-impl.h (struct Lisp_Color_Instance): * objects-impl.h (struct Lisp_Font_Instance): * objects-tty.c: * objects-x.c (allocate_nearest_color): * objects.c: * objects.c (Fmake_color_instance): * objects.c (Fmake_font_instance): * objects.c (font_instantiate): * opaque.c: * opaque.c (make_opaque): * opaque.c (make_opaque_ptr): * opaque.c (reinit_opaque_early): * opaque.c (init_opaque_once_early): * print.c: * print.c (printing_badness): * print.c (printing_major_badness): * print.c (print_internal): * print.c (debug_p4): * print.c (dp): * print.c (debug_backtrace): * process-nt.c (nt_create_process): * process-nt.c (get_internet_address): * process-unix.c: * process-unix.c (struct unix_process_data): * process-unix.c (get_internet_address): * process-unix.c (unix_alloc_process_data): * process-unix.c (unix_create_process): * process-unix.c (try_to_initialize_subtty): * process-unix.c (unix_kill_child_process): * process-unix.c (process_type_create_unix): * process.c: * process.c (mark_process): * process.c (MARKED_SLOT): * process.c (make_process_internal): * process.c (Fprocess_tty_name): * process.c (decode_signal): * process.h: * procimpl.h: * procimpl.h (struct process_methods): * procimpl.h (struct Lisp_Process): * rangetab.c: * realpath.c (readlink_and_correct_case): * redisplay-x.c (x_window_output_end): * redisplay-x.c (x_redraw_exposed_area): * redisplay-x.c (x_clear_frame): * redisplay.c: * redisplay.h: * redisplay.h (struct rune_dglyph): * redisplay.h (struct rune): * scrollbar.c: * scrollbar.c (create_scrollbar_instance): * specifier.c: * specifier.c (specifier_empty_extra_description_1): * specifier.c (make_specifier_internal): * specifier.c (decode_locale_type): * specifier.c (decode_how_to_add_specification): * specifier.h: * specifier.h (struct specifier_methods): * specifier.h (DEFINE_SPECIFIER_TYPE_WITH_DATA): * specifier.h (INITIALIZE_SPECIFIER_TYPE_WITH_DATA): * symbols.c: * symbols.c (Fsetplist): * symbols.c (default_value): * symbols.c (decode_magic_handler_type): * symbols.c (handler_type_from_function_symbol): * symbols.c (Fdefvaralias): * symbols.c (init_symbols_once_early): * symbols.c (reinit_symbols_early): * symsinit.h: * sysdep.c (sys_subshell): * sysdep.c (tty_init_sys_modes_on_device): * syswindows.h: * text.c (dfc_convert_to_external_format): * text.c (dfc_convert_to_internal_format): * text.c (reinit_eistring_early): * text.c (init_eistring_once_early): * text.c (reinit_vars_of_text): * text.h: * text.h (INC_IBYTEPTR_FMT): * text.h (DEC_IBYTEPTR_FMT): * toolbar.c: * toolbar.c (decode_toolbar_position): * tooltalk.c: * ui-gtk.c: * unexnt.c: * unexnt.c (_start): * unexnt.c (unexec): * unexnt.c (get_section_info): * unicode.c: * unicode.c (vars_of_unicode): * window.c: * window.c (allocate_window): * window.c (new_window_mirror): * window.c (update_mirror_internal): * winslots.h:
author michaels
date Sun, 12 Jan 2003 11:08:22 +0000
parents ccd0667b4764
children b531bf8658e9
line wrap: on
line source

/* Functions for the mswindows window system.
   Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
   Copyright (C) 1995, 1996, 2001, 2002 Ben Wing.

This file is part of XEmacs.

XEmacs is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

XEmacs is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with XEmacs; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

/* Synched up with: Not synched with FSF. */

/* This file Mule-ized, 8-14-2000. */

/* Authorship:

   Ultimately based on FSF.
   Substantially rewritten for XEmacs by Ben Wing.
   Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
   Graphics features added and frame resizing fiddled with by Andy Piper.
 */

#include <config.h>
#include "lisp.h"

#include "buffer.h"
#include "device-impl.h"
#include "elhash.h"
#include "events.h"
#include "faces.h"
#include "frame-impl.h"
#include "redisplay.h"
#include "window.h"

#include "console-msw-impl.h"
#include "glyphs-msw.h"

#define MSWINDOWS_FRAME_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW)
#define MSWINDOWS_POPUP_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP \
			       | WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX)

#define MSWINDOWS_FRAME_EXSTYLE WS_EX_OVERLAPPEDWINDOW
#define MSWINDOWS_POPUP_EXSTYLE WS_EX_PALETTEWINDOW

/* Default popup left top corner offset from the same
   corner of the parent frame, in pixel */
#define POPUP_OFFSET 30

/* Default popup size, in characters */
#define POPUP_WIDTH 30
#define POPUP_HEIGHT 10

/* Default regular frame size, in characters; if too big, it will get
   shrunk to the workspace size */
#define DEFAULT_FRAME_WIDTH 80
#define DEFAULT_FRAME_HEIGHT 50

#ifdef HAVE_MENUBARS
#define ADJR_MENUFLAG TRUE
#else
#define ADJR_MENUFLAG FALSE
#endif

/* Default properties to use when creating frames.  */
Lisp_Object Vdefault_mswindows_frame_plist;
Lisp_Object Vdefault_msprinter_frame_plist;
Lisp_Object Vmswindows_use_system_frame_size_defaults;

/* This does not need to be GC protected, as it holds a
   frame Lisp_Object already protected by Fmake_frame */
Lisp_Object Vmswindows_frame_being_created;

static const struct memory_description mswindows_frame_data_description_1 [] = {
#ifdef HAVE_TOOLBARS
  { XD_LISP_OBJECT, offsetof (struct mswindows_frame, toolbar_hash_table) },
#endif
  { XD_LISP_OBJECT, offsetof (struct mswindows_frame, menu_hash_table) },
  { XD_LISP_OBJECT, offsetof (struct mswindows_frame, widget_hash_table1) },
  { XD_LISP_OBJECT, offsetof (struct mswindows_frame, widget_hash_table2) },
  { XD_LISP_OBJECT, offsetof (struct mswindows_frame, widget_hash_table3) },
  { XD_END }
};

extern const struct sized_memory_description mswindows_frame_data_description;

const struct sized_memory_description mswindows_frame_data_description = {
  sizeof (struct mswindows_frame), mswindows_frame_data_description_1
};

/*---------------------------------------------------------------------*/
/*-----                    DISPLAY FRAME                          -----*/
/*---------------------------------------------------------------------*/

HWND
mswindows_get_selected_frame_hwnd (void)
{
  Lisp_Object frame, device;

  device = Ffind_device (Qnil, Qmswindows);
  if (NILP (device))
    return NULL;
  frame = DEVICE_SELECTED_FRAME (XDEVICE (device));
  if (NILP (frame))
    return NULL;

  return FRAME_MSWINDOWS_HANDLE (XFRAME (frame));
}

static void
mswindows_init_frame_1 (struct frame *f, Lisp_Object props,
			int frame_name_is_defaulted)
{
  Lisp_Object initially_unmapped;
  Lisp_Object name, height, width, popup, top, left;
  Lisp_Object frame_obj = Qnil;
  RECT rect;
  XEMACS_RECT_WH rect_default;
  DWORD style, exstyle;
  HWND hwnd, hwnd_parent;

  /* Pick up relevant properties */
  initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil);
  name = Fplist_get (props, Qname, Qnil);

  popup = Fplist_get (props, Qpopup, Qnil);
  if (EQ (popup, Qt))
    popup = Fselected_frame (Qnil);

  left = Fplist_get (props, Qleft, Qnil);
  if (!NILP (left))
    CHECK_INT (left);

  top = Fplist_get (props, Qtop, Qnil);
  if (!NILP (top))
    CHECK_INT (top);

  width = Fplist_get (props, Qwidth, Qnil);
  if (!NILP (width))
    CHECK_INT (width);

  height = Fplist_get (props, Qheight, Qnil);
  if (!NILP (height))
    CHECK_INT (height);

  f->frame_data = xnew_and_zero (struct mswindows_frame);
  FRAME_MSWINDOWS_TARGET_RECT (f) = xnew_and_zero (XEMACS_RECT_WH);

  FRAME_MSWINDOWS_TARGET_RECT (f)->left = NILP (left) ? -1 : abs (XINT (left));
  FRAME_MSWINDOWS_TARGET_RECT (f)->top = NILP (top) ? -1 : abs (XINT (top));
  FRAME_MSWINDOWS_TARGET_RECT (f)->width = NILP (width) ? -1 :
    abs (XINT (width));
  FRAME_MSWINDOWS_TARGET_RECT (f)->height = NILP (height) ? -1 :
    abs (XINT (height));

  /* Misc frame stuff */
  FRAME_MSWINDOWS_MENU_HASH_TABLE (f) = Qnil;
#ifdef HAVE_TOOLBARS
  /* EQ not EQUAL or we will get QUIT crashes, see below. */
  FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f) = 
    make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
#endif
  /* hashtable of instantiated glyphs on the frame.  Make them EQ because
     we only use ints as keys.  Otherwise we run into stickiness in
     redisplay because internal_equal() can QUIT.  See
     enter_redisplay_critical_section(). */
  FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f) =
    make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ);
  FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f) =
    make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ);
  FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f) =
    make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ);
  /* Will initialize these in WM_SIZE handler. We cannot do it now,
     because we do not know what is CW_USEDEFAULT height and width */
  FRAME_WIDTH (f) = 0;
  FRAME_HEIGHT (f) = 0;
  FRAME_PIXWIDTH (f) = 0;
  FRAME_PIXHEIGHT (f) = 0;

  if (NILP (popup))
    {
      style = MSWINDOWS_FRAME_STYLE;
      exstyle = MSWINDOWS_FRAME_EXSTYLE;
      hwnd_parent = NULL;

      rect_default.left = rect_default.top = CW_USEDEFAULT;
      rect_default.width = rect_default.height = CW_USEDEFAULT;
    }
  else
    {
      style = MSWINDOWS_POPUP_STYLE;
      exstyle = MSWINDOWS_POPUP_EXSTYLE;

      CHECK_MSWINDOWS_FRAME (popup);
      hwnd_parent = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
      assert (IsWindow (hwnd_parent));

      /* We cannot use CW_USEDEFAULT when creating a popup window.
	 So by default, we offset the new popup 30 pixels right
	 and down from its parent, and give it size of 30x10 characters.
	 These dimensions look adequate on both high and low res monitors */
      GetWindowRect (hwnd_parent, &rect);
      rect_default.left = rect.left + POPUP_OFFSET;
      rect_default.top = rect.top + POPUP_OFFSET;
      char_to_real_pixel_size (f, POPUP_WIDTH, POPUP_HEIGHT,
			       &rect_default.width, &rect_default.height);
      FRAME_MSWINDOWS_POPUP (f) = 1;
    }

  AdjustWindowRectEx (&rect, style, ADJR_MENUFLAG, exstyle);

  frame_obj = wrap_frame (f);

  Vmswindows_frame_being_created = frame_obj;
  {
    const Extbyte *nameext = 0;

    if (STRINGP (f->name))
      LISP_STRING_TO_TSTR (f->name, nameext);
    else if (STRINGP (name))
      LISP_STRING_TO_TSTR (name, nameext);
    else
      nameext = XETEXT (XEMACS_CLASS);
    hwnd = qxeCreateWindowEx (exstyle,
			      XETEXT (XEMACS_CLASS),
			      nameext,
			      style,
			      rect_default.left, rect_default.top,
			      rect_default.width, rect_default.height,
			      hwnd_parent, NULL, NULL, NULL);
  }

  Vmswindows_frame_being_created = Qnil;

  if (hwnd == NULL)
    invalid_operation ("System call to create frame failed",
		       STRINGP (f->name) ? f->name :
		       STRINGP (name) ? name :
		       Qunbound);
			   
  FRAME_MSWINDOWS_HANDLE (f) = hwnd;

  qxeSetWindowLong (hwnd, XWL_FRAMEOBJ, (LONG)LISP_TO_VOID (frame_obj));
  FRAME_MSWINDOWS_DC (f) = GetDC (hwnd);
  SetTextAlign (FRAME_MSWINDOWS_DC (f), TA_BASELINE | TA_LEFT | TA_NOUPDATECP);

#ifdef HAVE_DIALOGS
  if (FRAME_MSWINDOWS_POPUP (f))
    mswindows_register_popup_frame (frame_obj);
#endif /* HAVE_DIALOGS */
}

static void
mswindows_init_frame_2 (struct frame *f, Lisp_Object props)
{
  if (NILP (Vmswindows_use_system_frame_size_defaults))
    {
      /* I don't think anything can set the frame size before this
         since we don't have X resources. This may change if we look
         at the registry. Even so these values can get overridden
         later.*/
      XEMACS_RECT_WH dest = { -1, -1, DEFAULT_FRAME_WIDTH,
			      DEFAULT_FRAME_HEIGHT };
      mswindows_size_frame_internal (f, &dest);
    }
}

/* Called after frame's properties are set */
static void
mswindows_init_frame_3 (struct frame *f)
{
  /* Don't do this earlier or we get a WM_PAINT before the frame is ready */
  ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_SHOWNORMAL);
  SetForegroundWindow (FRAME_MSWINDOWS_HANDLE (f));
  DragAcceptFiles (FRAME_MSWINDOWS_HANDLE (f), TRUE);
}

static void
mswindows_after_init_frame (struct frame *f, int first_on_device,
		            int first_on_console)
{
  /* Windows, unlike X, is very synchronous. After the initial
     frame is created, it will never be displayed, except for
     hollow border, unless we start pumping messages. Load progress
     messages show in the bottom of the hollow frame, which is ugly.
     We redisplay the initial frame here, so modeline and root window
     background show.
  */
  if (first_on_console)
    redisplay ();
}

static void
mswindows_mark_frame (struct frame *f)
{
  mark_object (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
#ifdef HAVE_TOOLBARS
  mark_object (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
#endif
  mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
  mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
  mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
}

static void
mswindows_focus_on_frame (struct frame *f)
{
  SetForegroundWindow (FRAME_MSWINDOWS_HANDLE (f));
}

static void
mswindows_delete_frame (struct frame *f)
{
  if (f->frame_data)
    {
#ifdef HAVE_DIALOGS
      mswindows_unregister_popup_frame (wrap_frame (f));
#endif
      ReleaseDC (FRAME_MSWINDOWS_HANDLE (f), FRAME_MSWINDOWS_DC (f));
      DestroyWindow (FRAME_MSWINDOWS_HANDLE (f));
      xfree (f->frame_data);
    }
  f->frame_data = 0;
}

static void
mswindows_set_frame_size (struct frame *f, int width, int height)
{
  RECT rect;
  rect.left = rect.top = 0;
  rect.right = width;
  rect.bottom = height;

  AdjustWindowRectEx (&rect,
		      qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_STYLE),
		      GetMenu (FRAME_MSWINDOWS_HANDLE (f)) != NULL,
		      qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_EXSTYLE));

  if (IsIconic (FRAME_MSWINDOWS_HANDLE (f)) || IsZoomed (FRAME_MSWINDOWS_HANDLE (f)))
    ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_RESTORE);

  SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), NULL, 
		0, 0, rect.right-rect.left, rect.bottom-rect.top,
		SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOMOVE);
}

static void
mswindows_set_frame_position (struct frame *f, int xoff, int yoff)
{
  SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), NULL, 
		xoff, yoff, 0, 0,
		SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE);
}

static void
mswindows_make_frame_visible (struct frame *f)
{
  if (!FRAME_VISIBLE_P (f))
    ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_RESTORE);
  else
    ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_SHOW);
  SetActiveWindow (FRAME_MSWINDOWS_HANDLE (f));
  f->visible = 1;
  f->iconified = 0;
}

static void
mswindows_make_frame_invisible (struct frame *f)
{
  if (!FRAME_VISIBLE_P (f))
    return;

  ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_HIDE);
  f->visible = 0;
}

static int
mswindows_frame_totally_visible_p (struct frame *f)
{
  RECT rc_me, rc_other, rc_temp;
  HWND hwnd = FRAME_MSWINDOWS_HANDLE (f);

  /* We test against not a whole window rectangle, only against its
     client part. So, if non-client are is covered and client area is
     not, we return true. */
  GetClientRect (hwnd, &rc_me);
  MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rc_me, 2);

  /* First see if we're off the desktop */
  GetWindowRect (GetDesktopWindow (), &rc_other);
  UnionRect (&rc_temp, &rc_me, &rc_other);
  if (!EqualRect (&rc_temp, &rc_other))
    return 0;

  /* Then see if any window above us obscures us */
  while ((hwnd = GetWindow (hwnd, GW_HWNDPREV)) != NULL)
    if (IsWindowVisible (hwnd))
      {
	GetWindowRect (hwnd, &rc_other);
	if (IntersectRect (&rc_temp, &rc_me, &rc_other))
	  return 0;
      }

  return 1;
}

static int
mswindows_frame_visible_p (struct frame *f)
{
  return IsWindowVisible (FRAME_MSWINDOWS_HANDLE (f))
    && !IsIconic (FRAME_MSWINDOWS_HANDLE (f));
}


static void
mswindows_iconify_frame (struct frame *f)
{
  ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_MINIMIZE);
  f->visible = 0;
  f->iconified = 1;
}

static int
mswindows_frame_iconified_p (struct frame *f)
{
  return IsIconic (FRAME_MSWINDOWS_HANDLE (f));
}

static void
mswindows_set_frame_icon (struct frame *f)
{
  if (IMAGE_INSTANCEP (f->icon)
      && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon)))
    {
      if (!XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon))
	{
	  mswindows_initialize_image_instance_icon (XIMAGE_INSTANCE (f->icon),
						    FALSE);
	}

      qxeSetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HICON,
		       (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon));
    }
}

static void
mswindows_set_frame_pointer (struct frame *f)
{
  if (IMAGE_INSTANCEP (f->pointer)
      && IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (f->pointer)) == IMAGE_POINTER)
    {
      qxeSetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
		       (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
      /* we only have to do this because GC doesn't cause a mouse
         event and doesn't give time to event processing even if it
         did. */
      SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
    }
}

static void
mswindows_set_mouse_position (struct window *w, int x, int y)
{
  struct frame *f = XFRAME (w->frame);
  POINT pt;

  pt.x = w->pixel_left + x;
  pt.y = w->pixel_top  + y;
  ClientToScreen (FRAME_MSWINDOWS_HANDLE (f), &pt);
  SetCursorPos (pt.x, pt.y);
}

static int
mswindows_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y)
{
  POINT pt;
  HWND hwnd;

  GetCursorPos (&pt);

  /* What's under cursor? */
  hwnd = WindowFromPoint (pt);
  if (hwnd == NULL)
    return 0;

  /* Get grandest parent of the window */
  {
    HWND hwnd_parent;
    while ((hwnd_parent = GetParent (hwnd)) != NULL)
      hwnd = hwnd_parent;
  }

  /* Make sure it belongs to us */
  if (GetWindowThreadProcessId (hwnd, NULL) != GetCurrentThreadId ())
    return 0;

  /* And that the window is an XEmacs frame */
  if (!mswindows_window_is_xemacs (hwnd))
    return 0;

  /* Yippie! */
  ScreenToClient (hwnd, &pt);
  *frame = VOID_TO_LISP ((void *) qxeGetWindowLong (hwnd, XWL_FRAMEOBJ));
  *x = pt.x;
  *y = pt.y;
  return 1;
}

static void
mswindows_raise_frame (struct frame *f)
{
  BringWindowToTop (FRAME_MSWINDOWS_HANDLE (f));
}

static void
mswindows_lower_frame (struct frame *f)
{
  SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), HWND_BOTTOM, 0, 0, 0, 0,
		SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
}

static void
mswindows_enable_frame (struct frame *f)
{
  EnableWindow (FRAME_MSWINDOWS_HANDLE (f), TRUE);
}

static void
mswindows_disable_frame (struct frame *f)
{
  EnableWindow (FRAME_MSWINDOWS_HANDLE (f), FALSE);
}

static void
mswindows_set_title_from_ibyte (struct frame *f, Ibyte *title)
{
  unsigned int new_checksum = hash_string (title, qxestrlen (title));
  if (new_checksum != FRAME_MSWINDOWS_TITLE_CHECKSUM (f))
    {
      Extbyte *title_ext;

      FRAME_MSWINDOWS_TITLE_CHECKSUM (f) = new_checksum;
      C_STRING_TO_TSTR (title, title_ext);
      qxeSetWindowText (FRAME_MSWINDOWS_HANDLE (f), title_ext);
    }
}

static Lisp_Object
mswindows_frame_property (struct frame *f, Lisp_Object property)
{
  if (EQ (Qleft, property) || EQ (Qtop, property))
    {
      RECT rc;
      GetWindowRect (FRAME_MSWINDOWS_HANDLE (f), &rc);
      return make_int (EQ (Qtop,  property) ? rc.top : rc.left);
    }
  return Qunbound;
}

static int
mswindows_internal_frame_property_p (struct frame *f, Lisp_Object property)
{
  return EQ (property, Qleft)
    || EQ (property, Qtop);
  /* #### frame-x.c has also this. Why?
    || STRINGP (property);
  */
}

static Lisp_Object
mswindows_frame_properties (struct frame *f)
{
  Lisp_Object props = Qnil;
  RECT rc;
  GetWindowRect (FRAME_MSWINDOWS_HANDLE (f), &rc);

  props = cons3 (Qtop,  make_int (rc.top), props);
  props = cons3 (Qleft, make_int (rc.left), props);

  return props;
}

static void
mswindows_set_frame_properties (struct frame *f, Lisp_Object plist)
{
  int x=-1, y=-1;
  int width = -1, height = -1;
  BOOL width_specified_p = FALSE;
  BOOL height_specified_p = FALSE;
  BOOL x_specified_p = FALSE;
  BOOL y_specified_p = FALSE;
  Lisp_Object tail;

  /* Extract the properties from plist */
  for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
    {
      Lisp_Object prop = Fcar (tail);
      Lisp_Object val = Fcar (Fcdr (tail));

      if (SYMBOLP (prop))
	{
	  /* Kludge to handle the font property. */
	  if (EQ (prop, Qfont))
	    {
	      /* If the value is not a string we silently ignore it. */
	      if (STRINGP (val))
		{
		  Lisp_Object frm, font_spec;

		  frm = wrap_frame (f);
		  font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);

		  Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
		  update_frame_face_values (f);
		}
	    }
	  else if (EQ (prop, Qwidth))
	    {
	      CHECK_INT (val);
	      width = XINT (val);
	      width_specified_p = TRUE;
	    }
	  else if (EQ (prop, Qheight))
	    {
	      CHECK_INT (val);
	      height = XINT (val);
	      height_specified_p = TRUE;
	    }
	  else if (EQ (prop, Qleft))
	    {
	      CHECK_INT (val);
	      x = XINT (val);
	      x_specified_p = TRUE;
	    }
	  else if (EQ (prop, Qtop))
	    {
	      CHECK_INT (val);
	      y = XINT (val);
	      y_specified_p = TRUE;
	    }
	}
    }

  /* Now we've extracted the properties, apply them.
     Do not apply geometric properties during frame creation. This
     is excessive anyways, and this loses because WM_SIZE has not
     been sent yet, so frame width and height fields are not initialized.

     unfortunately WM_SIZE loses as well since the resize is only
     applied once and the first time WM_SIZE is applied not everything
     is initialised in the frame (toolbars for instance). enabling
     this always makes no visible difference and fixes a whole host of
     bugs (and is more consistent with X) so I am going to reenable it.
     --andyp */
  if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f)
       && (width_specified_p || height_specified_p
	   || x_specified_p || y_specified_p))
    {
      XEMACS_RECT_WH dest = { x, y, width, height };

      mswindows_size_frame_internal (f, &dest);
    }
}

void
mswindows_size_frame_internal (struct frame *f, XEMACS_RECT_WH *dest)
{
  RECT rect, ws_rect;
  int pixel_width, pixel_height;
  int size_p = (dest->width >=0 || dest->height >=0);
  int move_p = (dest->top >=0 || dest->left >=0);
  char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width,
			   &pixel_height);

  if (dest->width < 0)
    pixel_width = FRAME_PIXWIDTH (f);
  if (dest->height < 0)
    pixel_height = FRAME_PIXHEIGHT (f);

  GetWindowRect (FRAME_MSWINDOWS_HANDLE (f), &rect);
  if (dest->left < 0)
    dest->left = rect.left;
  if (dest->top < 0)
    dest->top = rect.top;

  rect.left = rect.top = 0;
  rect.right = pixel_width;
  rect.bottom = pixel_height;

  AdjustWindowRectEx (&rect,
		      qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_STYLE),
		      GetMenu (FRAME_MSWINDOWS_HANDLE (f)) != NULL,
		      qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_EXSTYLE));

  /* resize and move the window so that it fits in the workspace. This is
  not restrictive since this will happen later anyway in WM_SIZE.  We
  have to do this after adjusting the rect to account for menubar
  etc. */
  mswindows_get_workspace_coords (&ws_rect);
  pixel_width = rect.right - rect.left;
  pixel_height = rect.bottom - rect.top;
  if (pixel_width > ws_rect.right - ws_rect.left)
    {
      pixel_width = ws_rect.right - ws_rect.left;
      size_p=1;
    }
  if (pixel_height > ws_rect.bottom - ws_rect.top)
    {
      pixel_height = ws_rect.bottom - ws_rect.top;
      size_p=1;
    }

  /* adjust position so window is in workspace */
  if (dest->left + pixel_width > ws_rect.right)
    {
      dest->left = ws_rect.right - pixel_width;
      move_p=1;
    }
  if (dest->left < ws_rect.left)
    {
      dest->left = ws_rect.left;
      move_p=1;
    }

  if (dest->top + pixel_height > ws_rect.bottom)
    {
      dest->top = ws_rect.bottom - pixel_height;
      move_p=1;
    }
  if (dest->top < ws_rect.top)
    {
      dest->top = ws_rect.top;
      move_p=1;
    }

  if (IsIconic (FRAME_MSWINDOWS_HANDLE (f)) 
      || IsZoomed (FRAME_MSWINDOWS_HANDLE (f)))
    ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_RESTORE);

  SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), NULL, 
		dest->left, dest->top, pixel_width, pixel_height,
		SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
		| (size_p ? 0 : SWP_NOSIZE)
		| (move_p ? 0 : SWP_NOMOVE));
}

static Lisp_Object
mswindows_get_frame_parent (struct frame *f)
{
  HWND hwnd = FRAME_MSWINDOWS_HANDLE (f);
  hwnd = GetParent (hwnd);
  if (hwnd)
    {
      Lisp_Object parent;
      parent = VOID_TO_LISP ((void *) qxeGetWindowLong (hwnd, XWL_FRAMEOBJ));
      assert (FRAME_MSWINDOWS_P (XFRAME (parent)));
      return parent;
    }
  else
    return Qnil;
}

static void
mswindows_update_frame_external_traits (struct frame *frm, Lisp_Object name)
{
}

static int
mswindows_frame_size_fixed_p (struct frame *f)
{
  /* Frame size cannot change if the frame is maximized */
  return IsZoomed (FRAME_MSWINDOWS_HANDLE (f));
}

/*---------------------------------------------------------------------*/
/*-----                    PRINTER FRAME                          -----*/
/*---------------------------------------------------------------------*/

/*
 * With some driver/os combination (I discovered this with HP drivers
 * under W2K), DC geometry is reset upon StartDoc and EndPage
 * calls. This is called every time one of these calls is made.
 */
static void
apply_dc_geometry (struct frame* f)
{
  HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
  SetTextAlign (hdc, TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
  SetViewportOrgEx (hdc, FRAME_MSPRINTER_PIXLEFT(f),
		    FRAME_MSPRINTER_PIXTOP(f), NULL);
}

void
msprinter_start_page (struct frame *f)
{
  if (!FRAME_MSPRINTER_PAGE_STARTED (f))
    {
      FRAME_MSPRINTER_PAGE_STARTED (f) = 1;
      StartPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
      apply_dc_geometry (f);
    }
}

static void
error_frame_unsizable (struct frame *f)
{
  Lisp_Object frame = wrap_frame (f);

  invalid_change ("Cannot resize frame (margins) after print job has started.",
		  frame);
}

static void
maybe_error_if_job_active (struct frame *f)
{
  if (FRAME_MSPRINTER_JOB_STARTED (f))
    error_frame_unsizable (f);
}

static void
msprinter_init_frame_1 (struct frame *f, Lisp_Object props,
			int frame_name_is_defaulted)
{
  /* Make sure this is the only frame on device. Windows printer can
     handle only one job at a time. */
  if (!NILP (DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)))))
    invalid_operation ("Only one frame (print job) at a time is allowed on "
		       "this printer device", FRAME_DEVICE (f));

  f->frame_data = xnew_and_zero (struct msprinter_frame);

  FRAME_MSPRINTER_TOP_MARGIN (f) =
    mswindows_get_default_margin (Qtop_margin);
  FRAME_MSPRINTER_BOTTOM_MARGIN (f) =
    mswindows_get_default_margin (Qbottom_margin);
  FRAME_MSPRINTER_LEFT_MARGIN (f) =
    mswindows_get_default_margin (Qleft_margin);
  FRAME_MSPRINTER_RIGHT_MARGIN (f) =
    mswindows_get_default_margin (Qright_margin);

  /* Negative for "uinspecified" */
  FRAME_MSPRINTER_CHARWIDTH (f) = -1;
  FRAME_MSPRINTER_CHARHEIGHT (f) = -1;
}

static void
msprinter_init_frame_3 (struct frame *f)
{
  DOCINFOW di;
  struct device *device = XDEVICE (FRAME_DEVICE (f));
  int frame_left, frame_top, frame_width, frame_height;
  
  /* DC might be recreated in msprinter_apply_devmode,
     so do not initialize until now */
  HDC hdc = DEVICE_MSPRINTER_HDC (device);
  int logpixelsx = GetDeviceCaps (hdc, LOGPIXELSX);
  int logpixelsy = GetDeviceCaps (hdc, LOGPIXELSY);
  int physicaloffsetx = GetDeviceCaps (hdc, PHYSICALOFFSETX);
  int physicaloffsety = GetDeviceCaps (hdc, PHYSICALOFFSETY);
  int physicalheight = GetDeviceCaps (hdc, PHYSICALHEIGHT);
  int physicalwidth = GetDeviceCaps (hdc, PHYSICALWIDTH);

  /* Compute geometry properties.
     Conversion is from TWIPS -> inches -> pixels. */
  frame_left = MulDiv (logpixelsx, FRAME_MSPRINTER_LEFT_MARGIN(f), 1440)
    - physicaloffsetx;

  if (FRAME_MSPRINTER_CHARWIDTH (f) > 0)
    {
      char_to_real_pixel_size (f, FRAME_MSPRINTER_CHARWIDTH (f), 0,
			       &frame_width, NULL);
      FRAME_MSPRINTER_RIGHT_MARGIN(f) =
	MulDiv (physicalwidth - (frame_left + frame_width), 1440,
		logpixelsx);
    }
  else
    frame_width = physicalwidth - frame_left
      - MulDiv (logpixelsx, FRAME_MSPRINTER_RIGHT_MARGIN(f), 1440)
      - physicaloffsetx;

  frame_top = MulDiv (logpixelsy, FRAME_MSPRINTER_TOP_MARGIN(f), 1440)
    - physicaloffsety;

  if (FRAME_MSPRINTER_CHARHEIGHT (f) > 0)
    {
      char_to_real_pixel_size (f, 0, FRAME_MSPRINTER_CHARHEIGHT (f),
			       NULL, &frame_height);

      FRAME_MSPRINTER_BOTTOM_MARGIN(f) =
	MulDiv (physicalheight - (frame_top + frame_height), 1440,
		logpixelsy);
    }
  else
    frame_height = physicalheight - frame_top
      - MulDiv (logpixelsy, FRAME_MSPRINTER_BOTTOM_MARGIN(f), 1440)
      - physicaloffsety;

  /* Geometry sanity checks */
  if (!frame_pixsize_valid_p (f, frame_width, frame_height))
    invalid_operation ("Area inside print margins has shrunk to naught",
		       STRINGP (f->name) ? f->name : Qunbound);

  if (frame_left < 0
      || frame_top < 0
      || frame_left + frame_width > GetDeviceCaps (hdc, HORZRES)
      || frame_top + frame_height > GetDeviceCaps (hdc, VERTRES))
    invalid_operation ("Print area is outside of the printer's "
		       "hardware printable area",
		       STRINGP (f->name) ? f->name : Qunbound);

  /* Apply XEmacs frame geometry and layout windows */
  {
    int rows, columns;
    FRAME_PIXWIDTH (f) = frame_width;
    FRAME_PIXHEIGHT (f) = frame_height;
    pixel_to_char_size (f, frame_width, frame_height, &columns, &rows);
    change_frame_size (f, rows, columns, 0);
  }

  FRAME_MSPRINTER_PIXLEFT(f) = frame_left;
  FRAME_MSPRINTER_PIXTOP(f) = frame_top;

  /* Start print job */
  di.cbSize = sizeof (di);
  {
    const Extbyte *nameext;

    if (STRINGP (f->name))
      LISP_STRING_TO_TSTR (f->name, nameext);
    else
      nameext = XETEXT ("XEmacs print document");
    di.lpszDocName = (XELPTSTR) nameext;
  }
  di.lpszOutput = NULL;
  di.lpszDatatype = NULL;
  di.fwType = 0;

  if (qxeStartDoc (hdc, &di) <= 0)
    invalid_operation ("Cannot start print job",
		       STRINGP (f->name) ? f->name : Qunbound);

  apply_dc_geometry (f);

  /* Finish frame setup */
  FRAME_MSPRINTER_JOB_STARTED (f) = 1;
  FRAME_VISIBLE_P (f) = 0;
}

static void
msprinter_mark_frame (struct frame *f)
{
}

static void
msprinter_delete_frame (struct frame *f)
{
  if (f->frame_data)
    {
      HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
      if (FRAME_MSPRINTER_PAGE_STARTED (f))
	EndPage (hdc);
      if (FRAME_MSPRINTER_JOB_STARTED (f))
	EndDoc (hdc);
      xfree (f->frame_data);
    }

  f->frame_data = 0;
}

static Lisp_Object
msprinter_frame_property (struct frame *f, Lisp_Object property)
{
  if (EQ (Qleft_margin, property))
    return make_int (FRAME_MSPRINTER_LEFT_MARGIN (f));
  else if (EQ (Qtop_margin, property))
    return make_int (FRAME_MSPRINTER_TOP_MARGIN (f));
  if (EQ (Qright_margin, property))
    return make_int (FRAME_MSPRINTER_RIGHT_MARGIN (f));
  else if (EQ (Qbottom_margin, property))
    return make_int (FRAME_MSPRINTER_BOTTOM_MARGIN (f));
  else
    return Qunbound;
}

static int
msprinter_internal_frame_property_p (struct frame *f, Lisp_Object property)
{
  return (EQ (Qleft_margin, property) || EQ (Qtop_margin, property) ||
	  EQ (Qright_margin, property) || EQ (Qbottom_margin, property));
}

static Lisp_Object
msprinter_frame_properties (struct frame *f)
{
  Lisp_Object props = Qnil;
  props = cons3 (Qbottom_margin,
		 make_int (FRAME_MSPRINTER_BOTTOM_MARGIN (f)), props);
  props = cons3 (Qright_margin,
		 make_int (FRAME_MSPRINTER_RIGHT_MARGIN (f)), props);
  props = cons3 (Qtop_margin,
		 make_int (FRAME_MSPRINTER_TOP_MARGIN (f)), props);
  props = cons3 (Qleft_margin,
		 make_int (FRAME_MSPRINTER_LEFT_MARGIN (f)), props);
  return props;
}

static void
msprinter_set_frame_properties (struct frame *f, Lisp_Object plist)
{
  Lisp_Object tail;

  /* Extract the properties from plist */
  for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
    {
      Lisp_Object prop = Fcar (tail);
      Lisp_Object val = Fcar (Fcdr (tail));

      if (SYMBOLP (prop))
	{
	  if (EQ (prop, Qwidth))
	    {
	      maybe_error_if_job_active (f);
	      if (!NILP (val))
		{
		  CHECK_NATNUM (val);
		  FRAME_MSPRINTER_CHARWIDTH (f) = XINT (val);
		}
	    }
	  if (EQ (prop, Qheight))
	    {
	      maybe_error_if_job_active (f);
	      if (!NILP (val))
		{
		  CHECK_NATNUM (val);
		  FRAME_MSPRINTER_CHARHEIGHT (f) = XINT (val);
		}
	    }
	  else if (EQ (prop, Qleft_margin))
	    {
	      maybe_error_if_job_active (f);
	      CHECK_NATNUM (val);
	      FRAME_MSPRINTER_LEFT_MARGIN (f) = XINT (val);
	    }
	  else if (EQ (prop, Qtop_margin))
	    {
	      maybe_error_if_job_active (f);
	      CHECK_NATNUM (val);
	      FRAME_MSPRINTER_TOP_MARGIN (f) = XINT (val);
	    }
	  else if (EQ (prop, Qright_margin))
	    {
	      maybe_error_if_job_active (f);
	      CHECK_NATNUM (val);
	      FRAME_MSPRINTER_RIGHT_MARGIN (f) = XINT (val);
	    }
	  else if (EQ (prop, Qbottom_margin))
	    {
	      maybe_error_if_job_active (f);
	      CHECK_NATNUM (val);
	      FRAME_MSPRINTER_BOTTOM_MARGIN (f) = XINT (val);
	    }
	}
    }
}

static void
msprinter_set_frame_size (struct frame *f, int width, int height)
{
  /* We're absolutely unsizeable */
  error_frame_unsizable (f);
}

static void
msprinter_eject_page (struct frame *f)
{
  /* #### Should we eject empty pages? */
  if (FRAME_MSPRINTER_PAGE_STARTED (f))
    {
      FRAME_MSPRINTER_PAGE_STARTED (f) = 0;
      EndPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
      apply_dc_geometry (f);
    }
}


void
console_type_create_frame_mswindows (void)
{
  /* Display frames */
  CONSOLE_HAS_METHOD (mswindows, init_frame_1);
  CONSOLE_HAS_METHOD (mswindows, init_frame_2);
  CONSOLE_HAS_METHOD (mswindows, init_frame_3);
  CONSOLE_HAS_METHOD (mswindows, after_init_frame);
  CONSOLE_HAS_METHOD (mswindows, mark_frame);
  CONSOLE_HAS_METHOD (mswindows, focus_on_frame);
  CONSOLE_HAS_METHOD (mswindows, delete_frame);
  CONSOLE_HAS_METHOD (mswindows, get_mouse_position);
  CONSOLE_HAS_METHOD (mswindows, set_mouse_position);
  CONSOLE_HAS_METHOD (mswindows, raise_frame);
  CONSOLE_HAS_METHOD (mswindows, lower_frame);
  CONSOLE_HAS_METHOD (mswindows, enable_frame);
  CONSOLE_HAS_METHOD (mswindows, disable_frame);
  CONSOLE_HAS_METHOD (mswindows, make_frame_visible);
  CONSOLE_HAS_METHOD (mswindows, make_frame_invisible);
  CONSOLE_HAS_METHOD (mswindows, iconify_frame);
  CONSOLE_HAS_METHOD (mswindows, set_frame_size);
  CONSOLE_HAS_METHOD (mswindows, set_frame_position);
  CONSOLE_HAS_METHOD (mswindows, frame_property);
  CONSOLE_HAS_METHOD (mswindows, internal_frame_property_p);
  CONSOLE_HAS_METHOD (mswindows, frame_properties);
  CONSOLE_HAS_METHOD (mswindows, set_frame_properties);
  CONSOLE_HAS_METHOD (mswindows, set_title_from_ibyte);
/*  CONSOLE_HAS_METHOD (mswindows, set_icon_name_from_ibyte); */
  CONSOLE_HAS_METHOD (mswindows, frame_visible_p);
  CONSOLE_HAS_METHOD (mswindows, frame_totally_visible_p);
  CONSOLE_HAS_METHOD (mswindows, frame_iconified_p);
  CONSOLE_HAS_METHOD (mswindows, set_frame_pointer);
  CONSOLE_HAS_METHOD (mswindows, set_frame_icon);
  CONSOLE_HAS_METHOD (mswindows, get_frame_parent);
  CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits);
  CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p);

  /* Printer frames, aka print jobs */
  CONSOLE_HAS_METHOD (msprinter, init_frame_1);
  CONSOLE_HAS_METHOD (msprinter, init_frame_3);
  CONSOLE_HAS_METHOD (msprinter, mark_frame);
  CONSOLE_HAS_METHOD (msprinter, delete_frame);
  CONSOLE_HAS_METHOD (msprinter, frame_property);
  CONSOLE_HAS_METHOD (msprinter, internal_frame_property_p);
  CONSOLE_HAS_METHOD (msprinter, frame_properties);
  CONSOLE_HAS_METHOD (msprinter, set_frame_properties);
  CONSOLE_HAS_METHOD (msprinter, set_frame_size);
  CONSOLE_HAS_METHOD (msprinter, eject_page);
}

void
syms_of_frame_mswindows (void)
{
}

void
reinit_vars_of_frame_mswindows (void)
{
  /* Needn't staticpro -- see comment above.  */
  Vmswindows_frame_being_created = Qnil;
}

void
vars_of_frame_mswindows (void)
{
  reinit_vars_of_frame_mswindows ();

  DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /*
Controls whether to use system or XEmacs defaults for frame size.
If nil then reasonable defaults are used for initial frame sizes. If t
then the system will choose default sizes for the frame.
*/ );
  Vmswindows_use_system_frame_size_defaults = Qnil;

  DEFVAR_LISP ("default-mswindows-frame-plist", &Vdefault_mswindows_frame_plist /*
Plist of default frame-creation properties for mswindows frames.
These override what is specified in `default-frame-plist', but are
overridden by the arguments to the particular call to `make-frame'.

Note: In many cases, properties of a frame are available as specifiers
instead of through the frame-properties mechanism.

Here is a list of recognized frame properties, other than those
documented in `set-frame-properties' (they can be queried and
set at any time, except as otherwise noted):

  initially-unmapped		If non-nil, the frame will not be visible
				when it is created.  In this case, you
				need to call `make-frame-visible' to make
				the frame appear.
  popup				If non-nil, it should be a frame, and this
				frame will be created as a "popup" frame
				whose parent is the given frame.  This
				will make the window manager treat the
				frame as a dialog box, which may entail
				doing different things (e.g. not asking
				for positioning, and not iconifying
				separate from its parent).
  top				Y position (in pixels) of the upper-left
				outermost corner of the frame (i.e. the
				upper-left of the window-manager
				decorations).
  left				X position (in pixels) of the upper-left
				outermost corner of the frame (i.e. the
				upper-left of the window-manager
				decorations).

See also `default-frame-plist', which specifies properties which apply
to all frames, not just mswindows frames.
*/ );
  Vdefault_mswindows_frame_plist = Qnil;

  mswindows_console_methods->device_specific_frame_props =
    &Vdefault_mswindows_frame_plist;

  DEFVAR_LISP ("default-msprinter-frame-plist", &Vdefault_msprinter_frame_plist /*
Plist of default frame-creation properties for msprinter print job frames.
These override what is specified in `default-frame-plist', but are
overridden by the arguments to the particular call to `make-frame'.

Note: In many cases, properties of a frame are available as specifiers
instead of through the frame-properties mechanism.

Here is a list of recognized frame properties, other than those
documented in `set-frame-properties' (they can be queried and
set at any time, except as otherwise noted):

  left-margin                   Margin of the page, in twips. Twip is a
  top-margin			typographical unit of measurement,
  right-margin                  equal to 1/1440 of an inch, or 1/20 of a
  bottom-margin			point, and roughly equal to 7/400 of a
				millimeter.  If not specified, the left
				and right margins default to 1 inch
				(25.4 mm) and the top and bottom margins
				to 0.5 inch (12.7 mm).

     MARGINS NOTE. right-margin and bottom-margin are overridden by
       the height and width properties. If you want to specify size
       of the printable area in character, as with the rest of XEmacs,
       use these properties. If height and/or width are nil, then
       corresponding margin setting is taken into account. If you
       specify height and/or width in `default-frame-plist', but still
       want to specify right/bottom margins, set height/width in this
       plist to nil, as in this example:

	  (setq default-frame-plist '(height 55 width 80)
		default-msprinter-frame-plist '(height nil width nil))

See also `default-frame-plist', which specifies properties which apply
to all frames, not just mswindows frames.
*/ );
  Vdefault_msprinter_frame_plist = Qnil;

  msprinter_console_methods->device_specific_frame_props =
    &Vdefault_msprinter_frame_plist;
}