Mercurial > hg > xemacs-beta
annotate src/device-msw.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | b5df3737028a |
children | f965e31a35f0 |
rev | line source |
---|---|
428 | 1 /* device functions for mswindows. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1994, 1995 Free Software Foundation, Inc. | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
4 Copyright (C) 2000, 2001, 2002, 2010 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Not in FSF. */ | |
24 | |
771 | 25 /* This file Mule-ized 8-11-2000. */ |
26 | |
428 | 27 /* Authorship: |
28 | |
29 Original authors: Jamie Zawinski and the FSF | |
30 Rewritten by Ben Wing and Chuck Thompson. | |
31 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. | |
510 | 32 Print support added by Kirill Katsnelson, July 2000. |
428 | 33 */ |
34 | |
771 | 35 #define NEED_MSWINDOWS_COMMCTRL |
36 #define NEED_MSWINDOWS_OBJBASE /* for CoInitialize */ | |
428 | 37 |
38 #include <config.h> | |
39 #include "lisp.h" | |
40 | |
872 | 41 #include "device-impl.h" |
800 | 42 #include "events.h" |
43 #include "faces.h" | |
44 #include "frame.h" | |
45 | |
872 | 46 #include "console-msw-impl.h" |
428 | 47 #include "console-stream.h" |
442 | 48 #include "objects-msw.h" |
800 | 49 |
428 | 50 #include "sysdep.h" |
51 | |
52 /* win32 DDE management library globals */ | |
53 #ifdef HAVE_DRAGNDROP | |
54 DWORD mswindows_dde_mlid; | |
657 | 55 int mswindows_dde_enable; |
428 | 56 HSZ mswindows_dde_service; |
57 HSZ mswindows_dde_topic_system; | |
903 | 58 HSZ mswindows_dde_topic_eval; |
59 HSZ mswindows_dde_item_result; | |
428 | 60 HSZ mswindows_dde_item_open; |
61 #endif | |
62 | |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
63 Lisp_Object Qmake_device_early_mswindows_entry_point, |
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
64 Qmake_device_late_mswindows_entry_point; |
442 | 65 Lisp_Object Qdevmodep; |
428 | 66 |
510 | 67 static Lisp_Object Q_allow_selection; |
68 static Lisp_Object Q_allow_pages; | |
69 static Lisp_Object Q_selected_page_button; | |
70 static Lisp_Object Qselected_page_button; | |
71 | |
1204 | 72 static const struct memory_description mswindows_device_data_description_1 [] = { |
73 { XD_LISP_OBJECT, offsetof (struct mswindows_device, fontlist) }, | |
74 { XD_END } | |
75 }; | |
76 | |
3092 | 77 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
78 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("mswindows-device", mswindows_device, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
79 0, mswindows_device_data_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
80 Lisp_Mswindows_Device); |
3092 | 81 #else /* not NEW_GC */ |
1204 | 82 extern const struct sized_memory_description mswindows_device_data_description; |
83 | |
84 const struct sized_memory_description mswindows_device_data_description = { | |
85 sizeof (struct mswindows_device), mswindows_device_data_description_1 | |
86 }; | |
3092 | 87 #endif /* not NEW_GC */ |
1204 | 88 |
1346 | 89 static const struct memory_description msprinter_device_data_description_1 [] = { |
90 { XD_LISP_OBJECT, offsetof (struct msprinter_device, name) }, | |
91 { XD_LISP_OBJECT, offsetof (struct msprinter_device, devmode) }, | |
92 { XD_LISP_OBJECT, offsetof (struct msprinter_device, fontlist) }, | |
93 { XD_END } | |
94 }; | |
95 | |
3092 | 96 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
97 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("msprinter-device", msprinter_device, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
98 0, msprinter_device_data_description_1, |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
99 Lisp_Msprinter_Device); |
3092 | 100 #else /* not NEW_GC */ |
1346 | 101 extern const struct sized_memory_description msprinter_device_data_description; |
102 | |
103 const struct sized_memory_description msprinter_device_data_description = { | |
104 sizeof (struct msprinter_device), msprinter_device_data_description_1 | |
105 }; | |
3092 | 106 #endif /* not NEW_GC */ |
1346 | 107 |
771 | 108 static Lisp_Object allocate_devmode (DEVMODEW *src_devmode, int do_copy, |
109 Lisp_Object src_name, struct device *d); | |
428 | 110 |
111 /************************************************************************/ | |
112 /* helpers */ | |
113 /************************************************************************/ | |
114 | |
115 static Lisp_Object | |
440 | 116 build_syscolor_string (int idx) |
428 | 117 { |
442 | 118 return (idx < 0 ? Qnil : mswindows_color_to_string (GetSysColor (idx))); |
428 | 119 } |
120 | |
121 static Lisp_Object | |
122 build_syscolor_cons (int index1, int index2) | |
123 { | |
124 Lisp_Object color1, color2; | |
125 struct gcpro gcpro1; | |
126 GCPRO1 (color1); | |
127 color1 = build_syscolor_string (index1); | |
128 color2 = build_syscolor_string (index2); | |
129 RETURN_UNGCPRO (Fcons (color1, color2)); | |
130 } | |
131 | |
132 static Lisp_Object | |
133 build_sysmetrics_cons (int index1, int index2) | |
134 { | |
135 return Fcons (index1 < 0 ? Qnil : make_int (GetSystemMetrics (index1)), | |
136 index2 < 0 ? Qnil : make_int (GetSystemMetrics (index2))); | |
137 } | |
138 | |
440 | 139 static Lisp_Object |
140 build_devicecaps_cons (HDC hdc, int index1, int index2) | |
141 { | |
142 return Fcons (index1 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index1)), | |
143 index2 < 0 ? Qnil : make_int (GetDeviceCaps (hdc, index2))); | |
144 } | |
145 | |
428 | 146 |
147 /************************************************************************/ | |
440 | 148 /* display methods */ |
428 | 149 /************************************************************************/ |
150 | |
151 static void | |
2286 | 152 mswindows_init_device (struct device *d, Lisp_Object UNUSED (props)) |
428 | 153 { |
154 HDC hdc; | |
771 | 155 WNDCLASSEXW wc; |
428 | 156 |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
157 call0 (Qmake_device_early_mswindows_entry_point); |
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
158 |
428 | 159 DEVICE_CLASS (d) = Qcolor; |
160 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1; | |
161 init_baud_rate (d); | |
162 init_one_device (d); | |
163 | |
3092 | 164 #ifdef NEW_GC |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
165 d->device_data = XMSWINDOWS_DEVICE (ALLOC_NORMAL_LISP_OBJECT (mswindows_device)); |
3092 | 166 #else /* not NEW_GC */ |
428 | 167 d->device_data = xnew_and_zero (struct mswindows_device); |
3092 | 168 #endif /* not NEW_GC */ |
428 | 169 hdc = CreateCompatibleDC (NULL); |
771 | 170 assert (hdc != NULL); |
171 DEVICE_MSWINDOWS_HCDC (d) = hdc; | |
440 | 172 DEVICE_MSWINDOWS_FONTLIST (d) = mswindows_enumerate_fonts (hdc); |
442 | 173 DEVICE_MSWINDOWS_UPDATE_TICK (d) = GetTickCount (); |
428 | 174 |
175 /* Register the main window class */ | |
771 | 176 wc.cbSize = sizeof (wc); |
428 | 177 wc.style = CS_OWNDC; /* One DC per window */ |
178 wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc; | |
179 wc.cbClsExtra = 0; | |
180 wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES; | |
181 /* This must match whatever is passed to CreateWIndowEx, NULL is ok | |
182 for this. */ | |
771 | 183 wc.hInstance = NULL; |
184 wc.hIcon = qxeLoadIcon (qxeGetModuleHandle (NULL), XETEXT (XEMACS_CLASS)); | |
185 wc.hCursor = qxeLoadCursor (NULL, IDC_ARROW); | |
428 | 186 /* Background brush is only used during sizing, when XEmacs cannot |
187 take over */ | |
771 | 188 wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1); |
428 | 189 wc.lpszMenuName = NULL; |
190 | |
771 | 191 wc.lpszClassName = (XELPTSTR) XETEXT (XEMACS_CLASS); |
192 wc.hIconSm = (HICON) qxeLoadImage (qxeGetModuleHandle (NULL), | |
193 XETEXT (XEMACS_CLASS), | |
194 IMAGE_ICON, 16, 16, 0); | |
195 qxeRegisterClassEx (&wc); | |
428 | 196 |
197 #ifdef HAVE_WIDGETS | |
198 xzero (wc); | |
199 /* Register the main window class */ | |
771 | 200 wc.cbSize = sizeof (wc); |
428 | 201 wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc; |
771 | 202 wc.lpszClassName = (XELPTSTR) XETEXT (XEMACS_CONTROL_CLASS); |
428 | 203 wc.hInstance = NULL; |
771 | 204 qxeRegisterClassEx (&wc); |
428 | 205 #endif |
206 | |
440 | 207 #if defined (HAVE_TOOLBARS) || defined (HAVE_WIDGETS) |
428 | 208 InitCommonControls (); |
209 #endif | |
210 } | |
211 | |
657 | 212 #ifdef HAVE_DRAGNDROP |
428 | 213 static void |
771 | 214 mswindows_init_dde (void) |
428 | 215 { |
216 /* Initialize DDE management library and our related globals. We execute a | |
771 | 217 * dde Open ("file") by simulating a drop, so this depends on dnd support. */ |
442 | 218 |
428 | 219 mswindows_dde_mlid = 0; |
659 | 220 mswindows_dde_enable = 0; |
771 | 221 qxeDdeInitialize (&mswindows_dde_mlid, (PFNCALLBACK)mswindows_dde_callback, |
903 | 222 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS| |
223 CBF_FAIL_POKES|CBF_SKIP_ALLNOTIFICATIONS, | |
771 | 224 0); |
225 | |
226 mswindows_dde_service = | |
227 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
228 XETEXT (XEMACS_CLASS), | |
229 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
230 /* The following strings we Unicode-ize ourselves: | |
231 -- SZDDESYS_TOPIC is system-provided | |
903 | 232 -- MSWINDOWS_DDE_TOPIC_EVAL is defined by us |
233 -- MSWINDOWS_DDE_ITEM_RESULT is defined by us | |
771 | 234 -- MSWINDOWS_DDE_ITEM_OPEN is used in internal-format comparisons |
235 */ | |
236 mswindows_dde_topic_system = | |
237 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
238 XETEXT (SZDDESYS_TOPIC), | |
239 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
903 | 240 mswindows_dde_topic_eval = |
241 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
242 XETEXT (MSWINDOWS_DDE_TOPIC_EVAL), | |
243 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
244 mswindows_dde_item_result = | |
245 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
246 XETEXT (MSWINDOWS_DDE_ITEM_RESULT), | |
247 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
771 | 248 mswindows_dde_item_open = |
249 qxeDdeCreateStringHandle (mswindows_dde_mlid, | |
250 XETEXT (MSWINDOWS_DDE_ITEM_OPEN), | |
251 XEUNICODE_P ? CP_WINUNICODE : CP_WINANSI); | |
428 | 252 DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER); |
657 | 253 } |
771 | 254 #endif /* HAVE_DRAGNDROP */ |
657 | 255 |
256 void | |
771 | 257 init_mswindows_dde_very_early (void) |
657 | 258 { |
771 | 259 #if !defined (NO_CYGWIN_COM_SUPPORT) |
260 /* Needed by SHBrowseForFolder, so do it always */ | |
261 CoInitialize (NULL); | |
262 #endif | |
263 | |
657 | 264 #ifdef HAVE_DRAGNDROP |
265 /* Initializing dde when the device is created is too late - the | |
266 client will give up waiting. Instead we initialize here and tell | |
267 the client we're too busy until the rest of initialization has | |
268 happened. */ | |
771 | 269 mswindows_init_dde (); |
657 | 270 #endif |
271 } | |
272 | |
273 static void | |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
274 mswindows_finish_init_device (struct device *d, |
2286 | 275 Lisp_Object UNUSED (props)) |
657 | 276 { |
277 #ifdef HAVE_DRAGNDROP | |
278 /* Tell pending clients we are ready. */ | |
279 mswindows_dde_enable = 1; | |
428 | 280 #endif |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
281 call1 (Qmake_device_late_mswindows_entry_point, wrap_device(d)); |
428 | 282 } |
283 | |
284 static void | |
285 mswindows_delete_device (struct device *d) | |
286 { | |
287 #ifdef HAVE_DRAGNDROP | |
442 | 288 DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_UNREGISTER); |
903 | 289 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_result); |
442 | 290 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_item_open); |
291 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_system); | |
903 | 292 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_topic_eval); |
442 | 293 DdeFreeStringHandle (mswindows_dde_mlid, mswindows_dde_service); |
428 | 294 DdeUninitialize (mswindows_dde_mlid); |
442 | 295 |
771 | 296 # if !defined (NO_CYGWIN_COM_SUPPORT) |
442 | 297 CoUninitialize (); |
298 # endif | |
428 | 299 #endif |
300 | |
771 | 301 DeleteDC (DEVICE_MSWINDOWS_HCDC (d)); |
4117 | 302 #ifndef NEW_GC |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
303 xfree (d->device_data); |
3092 | 304 #endif /* not NEW_GC */ |
442 | 305 } |
306 | |
307 void | |
308 mswindows_get_workspace_coords (RECT *rc) | |
309 { | |
771 | 310 qxeSystemParametersInfo (SPI_GETWORKAREA, 0, rc, 0); |
428 | 311 } |
312 | |
440 | 313 static void |
314 mswindows_mark_device (struct device *d) | |
315 { | |
316 mark_object (DEVICE_MSWINDOWS_FONTLIST (d)); | |
317 } | |
318 | |
428 | 319 static Lisp_Object |
320 mswindows_device_system_metrics (struct device *d, | |
321 enum device_metrics m) | |
322 { | |
442 | 323 const HDC hdc = DEVICE_MSWINDOWS_HCDC(d); |
324 | |
428 | 325 switch (m) |
326 { | |
327 case DM_size_device: | |
442 | 328 return Fcons (make_int (GetDeviceCaps (hdc, HORZRES)), |
329 make_int (GetDeviceCaps (hdc, VERTRES))); | |
428 | 330 break; |
440 | 331 case DM_device_dpi: |
442 | 332 return Fcons (make_int (GetDeviceCaps (hdc, LOGPIXELSX)), |
333 make_int (GetDeviceCaps (hdc, LOGPIXELSY))); | |
440 | 334 break; |
428 | 335 case DM_size_device_mm: |
442 | 336 return Fcons (make_int (GetDeviceCaps (hdc, HORZSIZE)), |
337 make_int (GetDeviceCaps (hdc, VERTSIZE))); | |
428 | 338 break; |
339 case DM_num_bit_planes: | |
340 /* this is what X means by bitplanes therefore we ought to be | |
341 consistent. num planes is always 1 under mswindows and | |
342 therefore useless */ | |
442 | 343 return make_int (GetDeviceCaps (hdc, BITSPIXEL)); |
428 | 344 break; |
345 case DM_num_color_cells: | |
442 | 346 /* #### SIZEPALETTE only valid if RC_PALETTE bit set in RASTERCAPS, |
347 what should we return for a non-palette-based device? */ | |
348 return make_int (GetDeviceCaps (hdc, SIZEPALETTE)); | |
428 | 349 break; |
350 | |
351 /*** Colors ***/ | |
442 | 352 #define FROB(met, fore, back) \ |
428 | 353 case DM_##met: \ |
442 | 354 return build_syscolor_cons (fore, back); |
355 | |
356 FROB (color_default, COLOR_WINDOWTEXT, COLOR_WINDOW); | |
357 FROB (color_select, COLOR_HIGHLIGHTTEXT, COLOR_HIGHLIGHT); | |
358 FROB (color_balloon, COLOR_INFOTEXT, COLOR_INFOBK); | |
359 FROB (color_3d_face, COLOR_BTNTEXT, COLOR_BTNFACE); | |
360 FROB (color_3d_light, COLOR_3DHILIGHT, COLOR_3DLIGHT); | |
361 FROB (color_3d_dark, COLOR_3DDKSHADOW, COLOR_3DSHADOW); | |
362 FROB (color_menu, COLOR_MENUTEXT, COLOR_MENU); | |
363 FROB (color_menu_highlight, COLOR_HIGHLIGHTTEXT, COLOR_HIGHLIGHT); | |
364 FROB (color_menu_button, COLOR_MENUTEXT, COLOR_MENU); | |
365 FROB (color_menu_disabled, COLOR_GRAYTEXT, COLOR_MENU); | |
366 FROB (color_toolbar, COLOR_BTNTEXT, COLOR_BTNFACE); | |
367 FROB (color_scrollbar, COLOR_CAPTIONTEXT, COLOR_SCROLLBAR); | |
428 | 368 FROB (color_desktop, -1, COLOR_DESKTOP); |
369 FROB (color_workspace, -1, COLOR_APPWORKSPACE); | |
370 #undef FROB | |
371 | |
372 /*** Sizes ***/ | |
373 #define FROB(met, index1, index2) \ | |
374 case DM_##met: \ | |
375 return build_sysmetrics_cons (index1, index2); | |
376 | |
377 FROB (size_cursor, SM_CXCURSOR, SM_CYCURSOR); | |
378 FROB (size_scrollbar, SM_CXVSCROLL, SM_CYHSCROLL); | |
379 FROB (size_menu, -1, SM_CYMENU); | |
380 FROB (size_icon, SM_CXICON, SM_CYICON); | |
381 FROB (size_icon_small, SM_CXSMICON, SM_CYSMICON); | |
382 #undef FROB | |
383 | |
384 case DM_size_workspace: | |
385 { | |
386 RECT rc; | |
442 | 387 mswindows_get_workspace_coords (&rc); |
428 | 388 return Fcons (make_int (rc.right - rc.left), |
389 make_int (rc.bottom - rc.top)); | |
390 } | |
442 | 391 |
392 case DM_offset_workspace: | |
393 { | |
394 RECT rc; | |
395 mswindows_get_workspace_coords (&rc); | |
396 return Fcons (make_int (rc.left), make_int (rc.top)); | |
397 } | |
398 | |
428 | 399 /* |
400 case DM_size_toolbar: | |
401 case DM_size_toolbar_button: | |
402 case DM_size_toolbar_border: | |
403 */ | |
404 | |
405 /*** Features ***/ | |
406 #define FROB(met, index) \ | |
407 case DM_##met: \ | |
408 return make_int (GetSystemMetrics (index)); | |
409 | |
410 FROB (mouse_buttons, SM_CMOUSEBUTTONS); | |
411 FROB (swap_buttons, SM_SWAPBUTTON); | |
412 FROB (show_sounds, SM_SHOWSOUNDS); | |
413 FROB (slow_device, SM_SLOWMACHINE); | |
414 FROB (security, SM_SECURE); | |
415 #undef FROB | |
416 | |
417 } | |
418 | |
419 /* Do not know such property */ | |
420 return Qunbound; | |
421 } | |
422 | |
423 | |
424 /************************************************************************/ | |
442 | 425 /* printer helpers */ |
440 | 426 /************************************************************************/ |
427 | |
428 static void | |
429 signal_open_printer_error (struct device *d) | |
430 { | |
442 | 431 invalid_operation ("Failed to open printer", DEVICE_CONNECTION (d)); |
432 } | |
433 | |
434 | |
435 /* Helper function */ | |
436 static int | |
771 | 437 msprinter_init_device_internal (struct device *d, Lisp_Object printer_name) |
442 | 438 { |
771 | 439 Extbyte *printer_ext; |
440 HDC hdc; | |
442 | 441 |
771 | 442 DEVICE_MSPRINTER_NAME (d) = printer_name; |
443 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
444 printer_ext = LISP_STRING_TO_TSTR (printer_name); |
771 | 445 |
446 if (!qxeOpenPrinter (printer_ext, &DEVICE_MSPRINTER_HPRINTER (d), NULL)) | |
442 | 447 { |
448 DEVICE_MSPRINTER_HPRINTER (d) = NULL; | |
449 return 0; | |
450 } | |
451 | |
771 | 452 DEVICE_MSPRINTER_HDC (d) = qxeCreateDC (XETEXT ("WINSPOOL"), printer_ext, |
453 NULL, NULL); | |
442 | 454 if (DEVICE_MSPRINTER_HDC (d) == NULL) |
455 return 0; | |
456 | |
771 | 457 hdc = CreateCompatibleDC (DEVICE_MSPRINTER_HDC (d)); |
458 DEVICE_MSPRINTER_HCDC (d) = hdc; | |
459 DEVICE_MSPRINTER_FONTLIST (d) = mswindows_enumerate_fonts (hdc); | |
442 | 460 |
461 DEVICE_CLASS (d) = (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL) | |
462 * GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), PLANES) | |
463 > 1) ? Qcolor : Qmono; | |
464 return 1; | |
440 | 465 } |
466 | |
467 static void | |
442 | 468 msprinter_delete_device_internal (struct device *d) |
469 { | |
470 if (DEVICE_MSPRINTER_HPRINTER (d)) | |
471 ClosePrinter (DEVICE_MSPRINTER_HPRINTER (d)); | |
472 if (DEVICE_MSPRINTER_HDC (d)) | |
473 DeleteDC (DEVICE_MSPRINTER_HDC (d)); | |
474 if (DEVICE_MSPRINTER_HCDC (d)) | |
475 DeleteDC (DEVICE_MSPRINTER_HCDC (d)); | |
476 | |
477 DEVICE_MSPRINTER_FONTLIST (d) = Qnil; | |
478 } | |
479 | |
480 static int | |
771 | 481 msprinter_reinit_device (struct device *d, Lisp_Object devname) |
442 | 482 { |
483 msprinter_delete_device_internal (d); | |
484 return msprinter_init_device_internal (d, devname); | |
485 } | |
486 | |
487 Lisp_Object | |
488 msprinter_default_printer (void) | |
489 { | |
490 Extbyte name[666]; | |
867 | 491 Ibyte *nameint; |
442 | 492 |
771 | 493 if (qxeGetProfileString (XETEXT ("windows"), XETEXT ("device"), NULL, name, |
494 sizeof (name) / XETCHAR_SIZE) <= 0) | |
442 | 495 return Qnil; |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
496 nameint = TSTR_TO_ITEXT (name); |
442 | 497 |
771 | 498 if (nameint[0] == '\0') |
442 | 499 return Qnil; |
500 | |
771 | 501 /* this is destructive, but that's ok because the string is either in |
851 | 502 name[] or ALLOCA ()ed */ |
771 | 503 qxestrtok (nameint, ","); |
504 | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
505 return build_istring (nameint); |
442 | 506 } |
507 | |
508 | |
509 /************************************************************************/ | |
510 /* printer methods */ | |
511 /************************************************************************/ | |
512 | |
513 static void | |
2286 | 514 msprinter_init_device (struct device *d, Lisp_Object UNUSED (props)) |
440 | 515 { |
771 | 516 DEVMODEW *pdm; |
647 | 517 LONG dm_size; |
771 | 518 Extbyte *printer_name; |
440 | 519 |
3092 | 520 #ifdef NEW_GC |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
521 d->device_data = XMSPRINTER_DEVICE (ALLOC_NORMAL_LISP_OBJECT (msprinter_device)); |
3092 | 522 #else /* not NEW_GC */ |
440 | 523 d->device_data = xnew_and_zero (struct msprinter_device); |
3092 | 524 #endif /* not NEW_GC */ |
440 | 525 |
442 | 526 DEVICE_INFD (d) = DEVICE_OUTFD (d) = -1; |
771 | 527 DEVICE_MSPRINTER_DEVMODE (d) = Qnil; |
528 DEVICE_MSPRINTER_NAME (d) = Qnil; | |
440 | 529 |
2367 | 530 #if 0 /* #### deleted in new ikeyama ws */ |
771 | 531 /* We do not use printer font list as we do with the display |
532 device. Rather, we allow GDI to pick the closest match to the | |
440 | 533 display font. */ |
534 DEVICE_MSPRINTER_FONTLIST (d) = Qnil; | |
771 | 535 #endif /* 0 */ |
440 | 536 |
442 | 537 CHECK_STRING (DEVICE_CONNECTION (d)); |
538 | |
771 | 539 if (!msprinter_init_device_internal (d, DEVICE_CONNECTION (d))) |
442 | 540 signal_open_printer_error (d); |
541 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
542 printer_name = LISP_STRING_TO_TSTR (DEVICE_CONNECTION (d)); |
442 | 543 /* Determine DEVMODE size and store the default DEVMODE */ |
771 | 544 dm_size = qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), |
545 printer_name, NULL, NULL, 0); | |
442 | 546 if (dm_size <= 0) |
547 signal_open_printer_error (d); | |
548 | |
771 | 549 pdm = (DEVMODEW *) xmalloc (dm_size); |
550 if (qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER(d), | |
551 printer_name, pdm, | |
552 NULL, DM_OUT_BUFFER) < 0) | |
552 | 553 signal_open_printer_error (d); |
442 | 554 |
555 assert (DEVMODE_SIZE (pdm) <= dm_size); | |
556 | |
771 | 557 DEVICE_MSPRINTER_DEVMODE (d) = |
558 allocate_devmode (pdm, 0, DEVICE_CONNECTION (d), d); | |
442 | 559 } |
560 | |
561 static void | |
562 msprinter_delete_device (struct device *d) | |
563 { | |
564 if (d->device_data) | |
565 { | |
566 msprinter_delete_device_internal (d); | |
567 | |
568 /* Disassociate the selected devmode with the device */ | |
569 if (!NILP (DEVICE_MSPRINTER_DEVMODE (d))) | |
570 { | |
571 XDEVMODE (DEVICE_MSPRINTER_DEVMODE (d))->device = Qnil; | |
572 DEVICE_MSPRINTER_DEVMODE (d) = Qnil; | |
573 } | |
574 | |
4117 | 575 #ifndef NEW_GC |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
576 xfree (d->device_data); |
3092 | 577 #endif /* not NEW_GC */ |
442 | 578 } |
440 | 579 } |
580 | |
581 static Lisp_Object | |
582 msprinter_device_system_metrics (struct device *d, | |
583 enum device_metrics m) | |
584 { | |
585 switch (m) | |
586 { | |
587 /* Device sizes - pixel and mm */ | |
588 #define FROB(met, index1, index2) \ | |
589 case DM_##met: \ | |
590 return build_devicecaps_cons \ | |
771 | 591 (DEVICE_MSPRINTER_HDC (d), index1, index2); |
440 | 592 |
593 FROB (size_device, PHYSICALWIDTH, PHYSICALHEIGHT); | |
594 FROB (size_device_mm, HORZSIZE, VERTSIZE); | |
595 FROB (size_workspace, HORZRES, VERTRES); | |
596 FROB (offset_workspace, PHYSICALOFFSETX, PHYSICALOFFSETY); | |
597 FROB (device_dpi, LOGPIXELSX, LOGPIXELSY); | |
598 #undef FROB | |
599 | |
600 case DM_num_bit_planes: | |
601 /* this is what X means by bitplanes therefore we ought to be | |
602 consistent. num planes is always 1 under mswindows and | |
603 therefore useless */ | |
771 | 604 return make_int (GetDeviceCaps (DEVICE_MSPRINTER_HDC (d), BITSPIXEL)); |
440 | 605 |
442 | 606 case DM_num_color_cells: /* Printers are non-palette devices */ |
440 | 607 case DM_slow_device: /* Animation would be a really bad idea */ |
608 case DM_security: /* Not provided by windows */ | |
609 return Qzero; | |
610 } | |
611 | |
612 /* Do not know such property */ | |
613 return Qunbound; | |
614 } | |
615 | |
616 static void | |
617 msprinter_mark_device (struct device *d) | |
618 { | |
619 mark_object (DEVICE_MSPRINTER_FONTLIST (d)); | |
442 | 620 mark_object (DEVICE_MSPRINTER_DEVMODE (d)); |
771 | 621 mark_object (DEVICE_MSPRINTER_NAME (d)); |
440 | 622 } |
623 | |
624 | |
625 /************************************************************************/ | |
442 | 626 /* printer Lisp subroutines */ |
440 | 627 /************************************************************************/ |
628 | |
442 | 629 static void |
630 global_free_2_maybe (HGLOBAL hg1, HGLOBAL hg2) | |
631 { | |
632 if (hg1 != NULL) | |
633 GlobalFree (hg1); | |
634 if (hg2 != NULL) | |
635 GlobalFree (hg2); | |
636 } | |
637 | |
638 static HGLOBAL | |
639 devmode_to_hglobal (Lisp_Devmode *ldm) | |
640 { | |
641 HGLOBAL hg = GlobalAlloc (GHND, XDEVMODE_SIZE (ldm)); | |
642 memcpy (GlobalLock (hg), ldm->devmode, XDEVMODE_SIZE (ldm)); | |
643 GlobalUnlock (hg); | |
644 return hg; | |
645 } | |
646 | |
647 /* Returns 0 if the printer has been deleted due to a fatal I/O error, | |
648 1 otherwise. */ | |
649 static int | |
771 | 650 sync_printer_with_devmode (struct device* d, DEVMODEW* devmode_in, |
651 DEVMODEW* devmode_out, Lisp_Object devname) | |
440 | 652 { |
442 | 653 /* Change connection if the device changed */ |
771 | 654 if (!NILP (devname) |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
655 && lisp_strcasecmp_i18n (devname, DEVICE_MSPRINTER_NAME (d)) != 0) |
442 | 656 { |
771 | 657 Lisp_Object new_connection = devname; |
442 | 658 |
659 DEVICE_CONNECTION (d) = Qnil; | |
660 if (!NILP (Ffind_device (new_connection, Qmsprinter))) | |
661 { | |
662 /* We are in trouble - second msprinter for the same device. | |
663 Nothing wrong on the Windows side, just forge a unique | |
664 connection name. Use the memory address of d as a unique | |
665 suffix. */ | |
867 | 666 Ibyte new_connext[20]; |
771 | 667 |
668 qxesprintf (new_connext, ":%X", d->header.uid); | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
669 new_connection = concat2 (devname, build_istring (new_connext)); |
442 | 670 } |
671 DEVICE_CONNECTION (d) = new_connection; | |
672 | |
673 /* Reinitialize printer. The device can pop off in process */ | |
674 if (!msprinter_reinit_device (d, devname)) | |
675 { | |
676 /* Kaboom! */ | |
677 delete_device_internal (d, 1, 0, 1); | |
678 return 0; | |
679 } | |
680 } | |
771 | 681 { |
682 Extbyte *nameext; | |
442 | 683 |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
684 nameext = LISP_STRING_TO_TSTR (DEVICE_MSPRINTER_NAME (d)); |
771 | 685 |
686 /* Apply the new devmode to the printer */ | |
687 qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), | |
688 nameext, devmode_out, devmode_in, | |
689 DM_IN_BUFFER | DM_OUT_BUFFER); | |
440 | 690 |
771 | 691 /* #### ResetDC fails sometimes, Bill only knows why. |
692 The solution below looks more like a workaround to me, | |
693 although it might be fine. --kkm */ | |
694 if (qxeResetDC (DEVICE_MSPRINTER_HDC (d), devmode_out) == NULL) | |
695 { | |
696 DeleteDC (DEVICE_MSPRINTER_HDC (d)); | |
697 DEVICE_MSPRINTER_HDC (d) = | |
698 qxeCreateDC (XETEXT ("WINSPOOL"), nameext, NULL, | |
699 devmode_out); | |
700 } | |
701 } | |
702 | |
442 | 703 return 1; |
704 } | |
705 | |
706 static void | |
707 handle_devmode_changes (Lisp_Devmode *ldm, HGLOBAL hDevNames, HGLOBAL hDevMode) | |
708 { | |
771 | 709 DEVNAMES *devnames = (DEVNAMES *) GlobalLock (hDevNames); |
710 Extbyte *new_name = | |
711 devnames ? | |
712 (Extbyte *) devnames + XETCHAR_SIZE * devnames->wDeviceOffset : NULL; | |
713 DEVMODEW *devmode = (DEVMODEW *) GlobalLock (hDevMode); | |
442 | 714 |
715 /* Size and name may have changed */ | |
771 | 716 ldm->devmode = (DEVMODEW *) xrealloc (ldm->devmode, DEVMODE_SIZE (devmode)); |
442 | 717 if (new_name) |
771 | 718 ldm->printer_name = build_tstr_string (new_name); |
440 | 719 |
442 | 720 if (!NILP (ldm->device)) |
721 { | |
722 /* Apply the new devmode to the printer and get a compete one back */ | |
723 struct device *d = XDEVICE (ldm->device); | |
771 | 724 if (!sync_printer_with_devmode (d, devmode, ldm->devmode, |
725 new_name ? ldm->printer_name : Qnil)) | |
442 | 726 { |
727 global_free_2_maybe (hDevNames, hDevMode); | |
771 | 728 signal_error |
729 (Qio_error, | |
730 "Printer device initialization I/O error, device deleted", | |
731 ldm->device); | |
442 | 732 } |
733 } | |
734 else | |
735 { | |
736 /* Just copy the devmode structure */ | |
737 memcpy (ldm->devmode, devmode, DEVMODE_SIZE (devmode)); | |
738 } | |
739 } | |
440 | 740 |
442 | 741 static void |
742 ensure_not_printing (struct device *d) | |
743 { | |
744 if (!NILP (DEVICE_FRAME_LIST (d))) | |
745 { | |
793 | 746 Lisp_Object device = wrap_device (d); |
747 | |
442 | 748 invalid_operation ("Cannot change settings while print job is active", |
749 device); | |
750 } | |
751 } | |
752 | |
753 static Lisp_Devmode * | |
754 decode_devmode (Lisp_Object dev) | |
755 { | |
756 if (DEVMODEP (dev)) | |
757 return XDEVMODE (dev); | |
758 else | |
759 { | |
760 ensure_not_printing (XDEVICE (dev)); | |
761 return XDEVMODE (DEVICE_MSPRINTER_DEVMODE (XDEVICE (dev))); | |
762 } | |
440 | 763 } |
764 | |
765 /* | |
442 | 766 * DEV can be either a printer or devmode |
440 | 767 */ |
442 | 768 static Lisp_Object |
510 | 769 print_dialog_worker (Lisp_Object dev, DWORD flags) |
442 | 770 { |
771 Lisp_Devmode *ldm = decode_devmode (dev); | |
771 | 772 PRINTDLGW pd; |
442 | 773 |
774 memset (&pd, 0, sizeof (pd)); | |
775 pd.lStructSize = sizeof (pd); | |
776 pd.hwndOwner = mswindows_get_selected_frame_hwnd (); | |
777 pd.hDevMode = devmode_to_hglobal (ldm); | |
510 | 778 pd.Flags = flags | PD_USEDEVMODECOPIESANDCOLLATE; |
442 | 779 pd.nMinPage = 0; |
780 pd.nMaxPage = 0xFFFF; | |
781 | |
771 | 782 if (!qxePrintDlg (&pd)) |
442 | 783 { |
784 global_free_2_maybe (pd.hDevNames, pd.hDevMode); | |
785 return Qnil; | |
786 } | |
787 | |
788 handle_devmode_changes (ldm, pd.hDevNames, pd.hDevMode); | |
789 | |
790 /* Finally, build the resulting plist */ | |
791 { | |
792 Lisp_Object result = Qnil; | |
793 struct gcpro gcpro1; | |
794 GCPRO1 (result); | |
795 | |
796 /* Do consing in reverse order. | |
797 Number of copies */ | |
510 | 798 result = Fcons (Qcopies, Fcons (make_int (pd.nCopies), result)); |
442 | 799 |
800 /* Page range */ | |
510 | 801 if (pd.Flags & PD_PAGENUMS) |
442 | 802 { |
803 result = Fcons (Qto_page, Fcons (make_int (pd.nToPage), result)); | |
804 result = Fcons (Qfrom_page, Fcons (make_int (pd.nFromPage), result)); | |
510 | 805 result = Fcons (Qselected_page_button, Fcons (Qpages, result)); |
442 | 806 } |
510 | 807 else if (pd.Flags & PD_SELECTION) |
808 result = Fcons (Qselected_page_button, Fcons (Qselection, result)); | |
809 else | |
810 result = Fcons (Qselected_page_button, Fcons (Qall, result)); | |
442 | 811 |
812 /* Device name */ | |
771 | 813 result = Fcons (Qname, Fcons (ldm->printer_name, result)); |
442 | 814 UNGCPRO; |
815 | |
816 global_free_2_maybe (pd.hDevNames, pd.hDevMode); | |
817 return result; | |
818 } | |
819 } | |
820 | |
821 Lisp_Object | |
2286 | 822 mswindows_handle_print_dialog_box (struct frame *UNUSED (f), Lisp_Object keys) |
442 | 823 { |
824 Lisp_Object device = Qunbound, settings = Qunbound; | |
510 | 825 DWORD flags = PD_NOSELECTION; |
442 | 826 |
827 { | |
828 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) | |
829 { | |
830 if (EQ (key, Q_device)) | |
831 { | |
832 device = wrap_device (decode_device (value)); | |
833 CHECK_MSPRINTER_DEVICE (device); | |
834 } | |
835 else if (EQ (key, Q_printer_settings)) | |
836 { | |
837 CHECK_DEVMODE (value); | |
838 settings = value; | |
839 } | |
510 | 840 else if (EQ (key, Q_allow_pages)) |
841 { | |
842 if (NILP (value)) | |
843 flags |= PD_NOPAGENUMS; | |
844 } | |
845 else if (EQ (key, Q_allow_selection)) | |
442 | 846 { |
510 | 847 if (!NILP (value)) |
848 flags &= ~PD_NOSELECTION; | |
442 | 849 } |
510 | 850 else if (EQ (key, Q_selected_page_button)) |
442 | 851 { |
510 | 852 if (EQ (value, Qselection)) |
853 flags |= PD_SELECTION; | |
854 else if (EQ (value, Qpages)) | |
855 flags |= PD_PAGENUMS; | |
856 else if (!EQ (value, Qall)) | |
563 | 857 invalid_constant ("for :selected-page-button", value); |
442 | 858 } |
859 else | |
563 | 860 invalid_constant ("Unrecognized print-dialog keyword", key); |
442 | 861 } |
862 } | |
863 | |
864 if ((UNBOUNDP (device) && UNBOUNDP (settings)) || | |
865 (!UNBOUNDP (device) && !UNBOUNDP (settings))) | |
563 | 866 sferror ("Exactly one of :device and :printer-settings must be given", |
442 | 867 keys); |
868 | |
510 | 869 return print_dialog_worker (!UNBOUNDP (device) ? device : settings, flags); |
442 | 870 } |
871 | |
506 | 872 int |
873 mswindows_get_default_margin (Lisp_Object prop) | |
874 { | |
875 if (EQ (prop, Qleft_margin)) return 1440; | |
876 if (EQ (prop, Qright_margin)) return 1440; | |
877 if (EQ (prop, Qtop_margin)) return 720; | |
878 if (EQ (prop, Qbottom_margin)) return 720; | |
2500 | 879 ABORT (); |
506 | 880 return 0; |
881 } | |
882 | |
442 | 883 static int |
798 | 884 plist_get_margin (Lisp_Object plist, Lisp_Object prop, int mm_p) |
442 | 885 { |
506 | 886 Lisp_Object val = |
887 Fplist_get (plist, prop, make_int (mswindows_get_default_margin (prop))); | |
442 | 888 if (!INTP (val)) |
889 invalid_argument ("Margin value must be an integer", val); | |
890 | |
798 | 891 return MulDiv (XINT (val), mm_p ? 254 : 100, 144); |
442 | 892 } |
893 | |
894 static Lisp_Object | |
895 plist_set_margin (Lisp_Object plist, Lisp_Object prop, int margin, int mm_p) | |
896 { | |
798 | 897 Lisp_Object val = make_int (MulDiv (margin, 144, mm_p ? 254 : 100)); |
442 | 898 return Fcons (prop, Fcons (val, plist)); |
899 } | |
900 | |
901 Lisp_Object | |
2286 | 902 mswindows_handle_page_setup_dialog_box (struct frame *UNUSED (f), |
903 Lisp_Object keys) | |
442 | 904 { |
905 Lisp_Object device = Qunbound, settings = Qunbound; | |
906 Lisp_Object plist = Qnil; | |
907 | |
908 { | |
909 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) | |
910 { | |
911 if (EQ (key, Q_device)) | |
912 { | |
913 device = wrap_device (decode_device (value)); | |
914 CHECK_MSPRINTER_DEVICE (device); | |
915 } | |
916 else if (EQ (key, Q_printer_settings)) | |
917 { | |
918 CHECK_DEVMODE (value); | |
919 settings = value; | |
920 } | |
921 else if (EQ (key, Q_properties)) | |
922 { | |
923 CHECK_LIST (value); | |
924 plist = value; | |
925 } | |
926 else | |
563 | 927 invalid_constant ("Unrecognized page-setup dialog keyword", key); |
442 | 928 } |
929 } | |
930 | |
931 if ((UNBOUNDP (device) && UNBOUNDP (settings)) || | |
932 (!UNBOUNDP (device) && !UNBOUNDP (settings))) | |
563 | 933 sferror ("Exactly one of :device and :printer-settings must be given", |
800 | 934 keys); |
442 | 935 |
936 if (UNBOUNDP (device)) | |
937 device = settings; | |
938 | |
939 { | |
940 Lisp_Devmode *ldm = decode_devmode (device); | |
771 | 941 PAGESETUPDLGW pd; |
853 | 942 Extbyte measure[2 * MAX_XETCHAR_SIZE]; |
850 | 943 int data; |
798 | 944 |
850 | 945 qxeGetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IMEASURE, |
853 | 946 measure, sizeof (measure) / XETCHAR_SIZE); |
2421 | 947 data = qxetcscmp (measure, XETEXT ("0")); |
442 | 948 |
949 memset (&pd, 0, sizeof (pd)); | |
950 pd.lStructSize = sizeof (pd); | |
951 pd.hwndOwner = mswindows_get_selected_frame_hwnd (); | |
952 pd.Flags = PSD_MARGINS; | |
798 | 953 pd.rtMargin.left = plist_get_margin (plist, Qleft_margin, !data); |
954 pd.rtMargin.top = plist_get_margin (plist, Qtop_margin, !data); | |
955 pd.rtMargin.right = plist_get_margin (plist, Qright_margin, !data); | |
956 pd.rtMargin.bottom = plist_get_margin (plist, Qbottom_margin, !data); | |
442 | 957 pd.hDevMode = devmode_to_hglobal (ldm); |
958 | |
771 | 959 if (!qxePageSetupDlg (&pd)) |
442 | 960 { |
961 global_free_2_maybe (pd.hDevNames, pd.hDevMode); | |
962 return Qnil; | |
963 } | |
964 | |
965 if (pd.hDevMode) | |
966 handle_devmode_changes (ldm, pd.hDevNames, pd.hDevMode); | |
967 | |
968 /* Finally, build the resulting plist */ | |
969 { | |
970 Lisp_Object result = Qnil; | |
971 int mm_p = pd.Flags & PSD_INHUNDREDTHSOFMILLIMETERS; | |
972 result = plist_set_margin (result, Qbottom_margin, pd.rtMargin.bottom, | |
973 mm_p); | |
974 result = plist_set_margin (result, Qright_margin, pd.rtMargin.right, | |
975 mm_p); | |
976 result = plist_set_margin (result, Qtop_margin, pd.rtMargin.top, mm_p); | |
977 result = plist_set_margin (result, Qleft_margin, pd.rtMargin.left, mm_p); | |
978 return result; | |
979 } | |
980 } | |
981 } | |
982 | |
983 DEFUN ("msprinter-get-settings", Fmsprinter_get_settings, 1, 1, 0, /* | |
984 Return the settings object currently used by DEVICE. | |
985 The object returned is not a copy, but rather a pointer to the | |
986 original one. Use `msprinter-settings-copy' to create a copy of it. | |
987 */ | |
988 (device)) | |
989 { | |
990 struct device *d = decode_device (device); | |
793 | 991 device = wrap_device (d); |
442 | 992 CHECK_MSPRINTER_DEVICE (device); |
993 return DEVICE_MSPRINTER_DEVMODE (d); | |
994 } | |
995 | |
996 DEFUN ("msprinter-select-settings", Fmsprinter_select_settings, 2, 2, 0, /* | |
997 Select SETTINGS object into a DEVICE. | |
998 The settings from the settings object are immediately applied to the | |
999 printer, possibly changing even the target printer itself, and all | |
1000 future changes are applied synchronously to the printer device and the | |
1001 selected printer object, until a different settings object is selected | |
1002 into the same printer. | |
1003 | |
1004 A settings object can be selected to no more than one printer at a time. | |
1005 | |
1006 If the supplied settings object is not specialized, it is specialized | |
1007 for the printer immediately upon selection. The object can be | |
1008 despecialized after it is unselected by calling the function | |
1009 `msprinter-settings-despecialize'. | |
1010 | |
1011 Return value is the previously selected settings object. | |
1012 */ | |
1013 (device, settings)) | |
440 | 1014 { |
442 | 1015 Lisp_Devmode *ldm; |
1016 struct device *d = decode_device (device); | |
1017 | |
1018 struct gcpro gcpro1; | |
1019 GCPRO1 (settings); | |
1020 | |
793 | 1021 device = wrap_device (d); |
442 | 1022 CHECK_MSPRINTER_DEVICE (device); |
1023 CHECK_DEVMODE (settings); | |
1024 ldm = XDEVMODE (settings); | |
1025 | |
1026 if (!NILP (ldm->device)) | |
1027 invalid_operation ("The object is currently selected into a device", | |
1028 settings); | |
1029 | |
1030 /* If the object being selected is de-specialized, then its | |
1031 size is perhaps not enough to receive the new devmode. We can ask | |
1032 for printer's devmode size here, because despecialized settings | |
1033 cannot force switching to a different printer, as they supply no | |
1034 printer name at all. */ | |
771 | 1035 if (NILP (ldm->printer_name)) |
442 | 1036 { |
771 | 1037 Extbyte *nameext; |
1038 LONG dm_size; | |
1039 | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1040 nameext = LISP_STRING_TO_TSTR (DEVICE_MSPRINTER_NAME (d)); |
771 | 1041 dm_size = qxeDocumentProperties (NULL, DEVICE_MSPRINTER_HPRINTER (d), |
1042 nameext, NULL, NULL, 0); | |
442 | 1043 if (dm_size <= 0) |
563 | 1044 signal_error (Qio_error, |
1045 "Unable to specialize settings, printer error", | |
1046 device); | |
442 | 1047 |
1048 assert (XDEVMODE_SIZE (ldm) <= dm_size); | |
771 | 1049 ldm->devmode = (DEVMODEW *) xrealloc (ldm->devmode, dm_size); |
442 | 1050 } |
1051 | |
1052 /* If we bail out on signal here, no damage is done, except that | |
1053 the storage for the DEVMODE structure might be reallocated to | |
1054 hold a larger one - not a big deal */ | |
1055 if (!sync_printer_with_devmode (d, ldm->devmode, ldm->devmode, | |
1056 ldm->printer_name)) | |
563 | 1057 signal_error (Qio_error, |
1058 "Printer device initialization I/O error, device deleted", | |
771 | 1059 device); |
442 | 1060 |
771 | 1061 if (NILP (ldm->printer_name )) |
1062 ldm->printer_name = DEVICE_MSPRINTER_NAME (d); | |
442 | 1063 |
1064 { | |
1065 Lisp_Object old_mode = DEVICE_MSPRINTER_DEVMODE (d); | |
1066 ldm->device = device; | |
1067 XDEVMODE (old_mode)->device = Qnil; | |
1068 DEVICE_MSPRINTER_DEVMODE (d) = settings; | |
1069 UNGCPRO; | |
1070 return old_mode; | |
1071 } | |
1072 } | |
1073 | |
1074 DEFUN ("msprinter-apply-settings", Fmsprinter_apply_settings, 2, 2, 0, /* | |
3025 | 1075 Apply settings from a SETTINGS object to a `msprinter' DEVICE. |
442 | 1076 The settings from the settings object are immediately applied to the |
1077 printer, possibly changing even the target printer itself. The SETTING | |
1078 object is not modified, unlike `msprinter-select-settings', and the | |
1079 supplied object is not changed. The changes are immediately recorded | |
1080 into the settings object which is currently selected into the printer | |
1081 device. | |
1082 | |
1083 Return value is the currently selected settings object. | |
1084 */ | |
1085 (device, settings)) | |
1086 { | |
1087 Lisp_Devmode *ldm_current, *ldm_new; | |
1088 struct device *d = decode_device (device); | |
1089 | |
1090 struct gcpro gcpro1; | |
1091 GCPRO1 (settings); | |
1092 | |
793 | 1093 device = wrap_device (d); |
442 | 1094 CHECK_MSPRINTER_DEVICE (device); |
1095 CHECK_DEVMODE (settings); | |
1096 ldm_new = XDEVMODE (settings); | |
1097 ldm_current = XDEVMODE (DEVICE_MSPRINTER_DEVMODE (d)); | |
1098 | |
1099 /* If the supplied devmode is not specialized, then the current | |
1100 devmode size will always be sufficient, as the printer does | |
1101 not change. If it is specialized, we must reallocate the current | |
1102 devmode storage to match with the supplied one, as it has the right | |
1103 size for the new printer, if it is going to change. The correct | |
1104 way is to use the largest of the two though, to keep the old | |
1105 contents unchanged in case of preliminary exit. | |
1106 */ | |
771 | 1107 if (!NILP (ldm_new->printer_name)) |
442 | 1108 ldm_current->devmode = |
771 | 1109 (DEVMODEW*) xrealloc (ldm_current->devmode, |
442 | 1110 max (XDEVMODE_SIZE (ldm_new), |
1111 XDEVMODE_SIZE (ldm_current))); | |
1112 | |
1113 if (!sync_printer_with_devmode (d, ldm_new->devmode, | |
1114 ldm_current->devmode, | |
1115 ldm_new->printer_name)) | |
771 | 1116 signal_error |
1117 (Qio_error, | |
1118 "Printer device initialization I/O error, device deleted", device); | |
1119 | |
1120 if (!NILP (ldm_new->printer_name)) | |
1121 ldm_current->printer_name = ldm_new->printer_name; | |
442 | 1122 |
446 | 1123 UNGCPRO; |
442 | 1124 return DEVICE_MSPRINTER_DEVMODE (d); |
1125 } | |
1126 | |
1127 /************************************************************************/ | |
1128 /* devmode */ | |
1129 /************************************************************************/ | |
1130 | |
1204 | 1131 static const struct memory_description devmode_description[] = { |
934 | 1132 { XD_LISP_OBJECT, offsetof (struct Lisp_Devmode, printer_name) }, |
964 | 1133 { XD_LISP_OBJECT, offsetof (struct Lisp_Devmode, device) }, |
934 | 1134 { XD_END } |
1135 }; | |
1136 | |
771 | 1137 static Lisp_Object |
1138 mark_devmode (Lisp_Object obj) | |
1139 { | |
1140 Lisp_Devmode *data = XDEVMODE (obj); | |
1141 mark_object (data->printer_name); | |
1142 return data->device; | |
1143 } | |
1144 | |
442 | 1145 static void |
1146 print_devmode (Lisp_Object obj, Lisp_Object printcharfun, | |
2286 | 1147 int UNUSED (escapeflag)) |
442 | 1148 { |
1149 Lisp_Devmode *dm = XDEVMODE (obj); | |
1150 if (print_readably) | |
4846 | 1151 printing_unreadable_lcrecord (obj, 0); |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1152 write_ascstring (printcharfun, "#<msprinter-settings"); |
771 | 1153 if (!NILP (dm->printer_name)) |
800 | 1154 write_fmt_string_lisp (printcharfun, " for %S", 1, dm->printer_name); |
442 | 1155 if (!NILP (dm->device)) |
800 | 1156 write_fmt_string_lisp (printcharfun, " (currently on %s)", 1, dm->device); |
1157 write_fmt_string (printcharfun, " 0x%x>", dm->header.uid); | |
442 | 1158 } |
1159 | |
1160 static void | |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
1161 finalize_devmode (Lisp_Object obj) |
442 | 1162 { |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
1163 Lisp_Devmode *dm = XDEVMODE (obj); |
442 | 1164 |
1165 assert (NILP (dm->device)); | |
1166 } | |
1167 | |
1168 static int | |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1169 equal_devmode (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth), |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1170 int UNUSED (foldcase)) |
442 | 1171 { |
1172 Lisp_Devmode *dm1 = XDEVMODE (obj1); | |
1173 Lisp_Devmode *dm2 = XDEVMODE (obj2); | |
440 | 1174 |
442 | 1175 if ((dm1->devmode != NULL) != (dm1->devmode != NULL)) |
1176 return 0; | |
1177 if (dm1->devmode == NULL) | |
1178 return 1; | |
1179 if (memcmp (dm1->devmode, dm2->devmode, XDEVMODE_SIZE (dm1)) != 0) | |
1180 return 0; | |
771 | 1181 if (NILP (dm1->printer_name) || NILP (dm2->printer_name)) |
442 | 1182 return 1; |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4846
diff
changeset
|
1183 return lisp_strcasecmp_i18n (dm1->printer_name, dm2->printer_name) == 0; |
442 | 1184 } |
1185 | |
665 | 1186 static Hashcode |
442 | 1187 hash_devmode (Lisp_Object obj, int depth) |
1188 { | |
1189 Lisp_Devmode *dm = XDEVMODE (obj); | |
1190 | |
1191 return HASH3 (XDEVMODE_SIZE (dm), | |
1192 dm->devmode ? memory_hash (dm->devmode, XDEVMODE_SIZE (dm)) | |
1193 : 0, | |
771 | 1194 internal_hash (dm->printer_name, depth + 1)); |
442 | 1195 } |
1196 | |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
1197 DEFINE_NODUMP_LISP_OBJECT ("msprinter-settings", devmode, |
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
1198 mark_devmode, print_devmode, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
1199 finalize_devmode, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
1200 equal_devmode, hash_devmode, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
1201 devmode_description, |
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5120
diff
changeset
|
1202 Lisp_Devmode); |
934 | 1203 |
442 | 1204 static Lisp_Object |
771 | 1205 allocate_devmode (DEVMODEW* src_devmode, int do_copy, |
1206 Lisp_Object src_name, struct device *d) | |
442 | 1207 { |
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
1208 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (devmode); |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1209 Lisp_Devmode *dm = XDEVMODE (obj); |
442 | 1210 |
1211 if (d) | |
793 | 1212 dm->device = wrap_device (d); |
442 | 1213 else |
1214 dm->device = Qnil; | |
1215 | |
771 | 1216 dm->printer_name = src_name; |
442 | 1217 |
1218 if (src_devmode != NULL && do_copy) | |
1219 { | |
771 | 1220 dm->devmode = (DEVMODEW*) xmalloc (DEVMODE_SIZE (src_devmode)); |
442 | 1221 memcpy (dm->devmode, src_devmode, DEVMODE_SIZE (src_devmode)); |
1222 } | |
1223 else | |
1224 { | |
1225 dm->devmode = src_devmode; | |
1226 } | |
1227 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1228 return obj; |
442 | 1229 } |
1230 | |
1231 DEFUN ("msprinter-settings-copy", Fmsprinter_settings_copy, 1, 1, 0, /* | |
1232 Create and returns an exact copy of a printer settings object. | |
1233 */ | |
1234 (settings)) | |
1235 { | |
1236 Lisp_Devmode *dm; | |
1237 | |
1238 CHECK_DEVMODE (settings); | |
1239 dm = XDEVMODE (settings); | |
1240 | |
1241 return allocate_devmode (dm->devmode, 1, dm->printer_name, NULL); | |
1242 } | |
1243 | |
1244 DEFUN ("msprinter-settings-despecialize", Fmsprinter_settings_despecialize, 1, 1, 0, /* | |
1245 Erase printer-specific settings from a printer settings object. | |
1246 */ | |
1247 (settings)) | |
1248 { | |
1249 Lisp_Devmode *ldm; | |
771 | 1250 DEVMODEW *dm; |
442 | 1251 |
1252 CHECK_DEVMODE (settings); | |
1253 ldm = XDEVMODE (settings); | |
1254 | |
1255 if (!NILP (ldm->device)) | |
1256 invalid_operation ("The object is currently selected into a device", | |
1257 settings); | |
1258 | |
1259 dm = ldm->devmode; | |
1260 | |
1261 /* #### TODO. Either remove references to device specific bins, | |
1262 paper sizes etc, or signal an error of they are present. */ | |
440 | 1263 |
442 | 1264 dm->dmDriverExtra = 0; |
1265 dm->dmDeviceName[0] = '\0'; | |
1266 | |
771 | 1267 ldm->printer_name = Qnil; |
442 | 1268 |
1269 return Qnil; | |
1270 } | |
1271 | |
1272 DEFUN ("mswindows-get-default-printer", Fmswindows_get_default_printer, 0, 0, 0, /* | |
1273 Return name of the default printer, as string, on nil if there is no default. | |
1274 */ | |
1275 ()) | |
1276 { | |
1277 return msprinter_default_printer (); | |
1278 } | |
1279 | |
1280 static void | |
1281 signal_enum_printer_error (void) | |
1282 { | |
1283 invalid_operation ("Error enumerating printers", make_int (GetLastError ())); | |
1284 } | |
1285 | |
1286 DEFUN ("mswindows-printer-list", Fmswindows_printer_list, 0, 0, 0, /* | |
1287 Return a list of string names of installed printers. | |
1288 If there is a default printer, it is returned as the first element of | |
1289 the list. If there is no default printer, the first element of the | |
1290 list will be nil. The rest of elements are guaranteed to have string | |
1291 values. Return value is nil if there are no printers installed. | |
1292 */ | |
1293 ()) | |
1294 { | |
1295 int have_nt, ok; | |
1296 BYTE *data_buf, dummy_byte; | |
665 | 1297 Bytecount enum_entry_size; |
442 | 1298 DWORD enum_flags, enum_level, bytes_needed, num_printers; |
1299 struct gcpro gcpro1, gcpro2; | |
1300 Lisp_Object result = Qnil, def_printer = Qnil; | |
1301 | |
1302 /* Determine OS flavor, to use the fastest enumeration method available */ | |
771 | 1303 have_nt = !mswindows_windows9x_p; |
442 | 1304 enum_flags = PRINTER_ENUM_LOCAL | (have_nt ? PRINTER_ENUM_CONNECTIONS : 0); |
1305 enum_level = have_nt ? 4 : 5; | |
771 | 1306 enum_entry_size = (have_nt ? sizeof (PRINTER_INFO_4) : |
1307 sizeof (PRINTER_INFO_5)); | |
442 | 1308 |
1309 /* Allocate memory for printer enum structure */ | |
771 | 1310 ok = qxeEnumPrinters (enum_flags, NULL, enum_level, &dummy_byte, 1, |
1311 &bytes_needed, &num_printers); | |
442 | 1312 if (ok) |
1313 /* No printers, if just 1 byte is enough */ | |
1314 return Qnil; | |
1315 | |
1316 if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) | |
1317 signal_enum_printer_error (); | |
1318 | |
2367 | 1319 data_buf = alloca_array (BYTE, bytes_needed); |
771 | 1320 ok = qxeEnumPrinters (enum_flags, NULL, enum_level, data_buf, bytes_needed, |
1321 &bytes_needed, &num_printers); | |
442 | 1322 if (!ok) |
1323 signal_enum_printer_error (); | |
1324 | |
1325 if (num_printers == 0) | |
1326 /* Strange but... */ | |
1327 return Qnil; | |
1328 | |
1329 GCPRO2 (result, def_printer); | |
1330 | |
1331 while (num_printers--) | |
1332 { | |
771 | 1333 Extbyte *printer_name; |
442 | 1334 if (have_nt) |
1335 { | |
771 | 1336 PRINTER_INFO_4 *info = (PRINTER_INFO_4 *) data_buf; |
1337 printer_name = (Extbyte *) info->pPrinterName; | |
442 | 1338 } |
1339 else | |
1340 { | |
771 | 1341 PRINTER_INFO_5 *info = (PRINTER_INFO_5 *) data_buf; |
1342 printer_name = (Extbyte *) info->pPrinterName; | |
442 | 1343 } |
1344 data_buf += enum_entry_size; | |
1345 | |
771 | 1346 result = Fcons (build_tstr_string (printer_name), result); |
442 | 1347 } |
1348 | |
1349 def_printer = msprinter_default_printer (); | |
1350 result = Fdelete (def_printer, result); | |
1351 result = Fcons (def_printer, result); | |
1352 | |
1353 RETURN_UNGCPRO (result); | |
440 | 1354 } |
1355 | |
1356 | |
1357 /************************************************************************/ | |
428 | 1358 /* initialization */ |
1359 /************************************************************************/ | |
1360 | |
1361 void | |
1362 syms_of_device_mswindows (void) | |
1363 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
1364 INIT_LISP_OBJECT (devmode); |
442 | 1365 |
3092 | 1366 #ifdef NEW_GC |
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
1367 INIT_LISP_OBJECT (mswindows_device); |
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
1368 INIT_LISP_OBJECT (msprinter_device); |
3092 | 1369 #endif /* NEW_GC */ |
1370 | |
442 | 1371 DEFSUBR (Fmsprinter_get_settings); |
1372 DEFSUBR (Fmsprinter_select_settings); | |
1373 DEFSUBR (Fmsprinter_apply_settings); | |
1374 DEFSUBR (Fmsprinter_settings_copy); | |
1375 DEFSUBR (Fmsprinter_settings_despecialize); | |
1376 DEFSUBR (Fmswindows_get_default_printer); | |
1377 DEFSUBR (Fmswindows_printer_list); | |
1378 | |
510 | 1379 DEFKEYWORD (Q_allow_selection); |
1380 DEFKEYWORD (Q_allow_pages); | |
1381 DEFKEYWORD (Q_selected_page_button); | |
1382 DEFSYMBOL (Qselected_page_button); | |
1383 | |
4477
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
1384 DEFSYMBOL (Qmake_device_early_mswindows_entry_point); |
e34711681f30
Don't determine whether to call general device-type code at startup,
Aidan Kehoe <kehoea@parhasard.net>
parents:
4117
diff
changeset
|
1385 DEFSYMBOL ( Qmake_device_late_mswindows_entry_point); |
428 | 1386 } |
1387 | |
1388 void | |
1389 console_type_create_device_mswindows (void) | |
1390 { | |
1391 CONSOLE_HAS_METHOD (mswindows, init_device); | |
1392 CONSOLE_HAS_METHOD (mswindows, finish_init_device); | |
440 | 1393 CONSOLE_HAS_METHOD (mswindows, mark_device); |
428 | 1394 CONSOLE_HAS_METHOD (mswindows, delete_device); |
1395 CONSOLE_HAS_METHOD (mswindows, device_system_metrics); | |
545 | 1396 CONSOLE_IMPLEMENTATION_FLAGS (mswindows, XDEVIMPF_PIXEL_GEOMETRY); |
440 | 1397 |
1398 CONSOLE_HAS_METHOD (msprinter, init_device); | |
1399 CONSOLE_HAS_METHOD (msprinter, mark_device); | |
1400 CONSOLE_HAS_METHOD (msprinter, delete_device); | |
1401 CONSOLE_HAS_METHOD (msprinter, device_system_metrics); | |
545 | 1402 CONSOLE_IMPLEMENTATION_FLAGS (msprinter, (XDEVIMPF_PIXEL_GEOMETRY |
1403 | XDEVIMPF_IS_A_PRINTER | |
1404 | XDEVIMPF_NO_AUTO_REDISPLAY | |
1405 | XDEVIMPF_DONT_PREEMPT_REDISPLAY | |
1406 | XDEVIMPF_FRAMELESS_OK)); | |
428 | 1407 } |
1408 | |
440 | 1409 |
428 | 1410 void |
1411 vars_of_device_mswindows (void) | |
1412 { | |
1413 } |