Mercurial > hg > xemacs-beta
annotate src/win32.c @ 4976:16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-04 Ben Wing <ben@xemacs.org>
* alloc.c (release_breathing_space):
* alloc.c (resize_string):
* alloc.c (sweep_lcrecords_1):
* alloc.c (SWEEP_FIXED_TYPE_BLOCK_1):
* alloc.c (ADDITIONAL_FREE_compiled_function):
* alloc.c (compact_string_chars):
* alloc.c (ADDITIONAL_FREE_string):
* alloc.c (sweep_strings):
* alloca.c (xemacs_c_alloca):
* alsaplay.c (alsa_play_sound_file):
* buffer.c (init_initial_directory):
* buffer.h:
* buffer.h (BUFFER_FREE):
* console-stream.c (stream_delete_console):
* console-tty.c (free_tty_console_struct):
* data.c (Fnumber_to_string):
* device-gtk.c (gtk_init_device):
* device-gtk.c (free_gtk_device_struct):
* device-gtk.c (gtk_delete_device):
* device-msw.c (mswindows_delete_device):
* device-msw.c (msprinter_delete_device):
* device-tty.c (free_tty_device_struct):
* device-tty.c (tty_delete_device):
* device-x.c (x_init_device):
* device-x.c (free_x_device_struct):
* device-x.c (x_delete_device):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-x.c (dbox_descriptor_to_widget_value):
* dired-msw.c (Fmswindows_insert_directory):
* dired.c (free_user_cache):
* dired.c (user_name_completion_unwind):
* doc.c (unparesseuxify_doc_string):
* doc.c (Fsubstitute_command_keys):
* doprnt.c (emacs_doprnt_1):
* dumper.c (pdump_load_finish):
* dumper.c (pdump_file_free):
* dumper.c (pdump_file_unmap):
* dynarr.c:
* dynarr.c (Dynarr_free):
* editfns.c (uncache_home_directory):
* editfns.c (Fset_time_zone_rule):
* elhash.c:
* elhash.c (pdump_reorganize_hash_table):
* elhash.c (maphash_unwind):
* emacs.c (make_arg_list_1):
* emacs.c (free_argc_argv):
* emacs.c (sort_args):
* emacs.c (Frunning_temacs_p):
* emodules.c (attempt_module_delete):
* eval.c (free_pointer):
* event-Xt.c (unselect_filedesc):
* event-Xt.c (emacs_Xt_select_process):
* event-gtk.c (unselect_filedesc):
* event-gtk.c (dragndrop_data_received):
* event-msw.c (winsock_closer):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* event-stream.c (finalize_command_builder):
* event-stream.c (free_command_builder):
* extents.c (free_gap_array):
* extents.c (free_extent_list):
* extents.c (free_soe):
* extents.c (extent_fragment_delete):
* extents.c (extent_priority_sort_function):
* file-coding.c (make_coding_system_1):
* file-coding.c (coding_finalizer):
* file-coding.c (set_coding_stream_coding_system):
* file-coding.c (chain_finalize_coding_stream_1):
* file-coding.c (chain_finalize):
* file-coding.c (free_detection_state):
* file-coding.c (coding_category_symbol_to_id):
* fileio.c:
* fileio.c (Ffile_name_directory):
* fileio.c (if):
* fileio.c (Ffile_symlink_p):
* filelock.c (FREE_LOCK_INFO):
* filelock.c (current_lock_owner):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* frame-gtk.c (gtk_delete_frame):
* frame-msw.c (mswindows_delete_frame):
* frame-msw.c (msprinter_delete_frame):
* frame-x.c (x_cde_destroy_callback):
* frame-x.c (Fcde_start_drag_internal):
* frame-x.c (x_cde_transfer_callback):
* frame-x.c (x_delete_frame):
* frame.c (update_frame_title):
* frame.c (Fset_frame_pointer):
* gc.c (register_for_finalization):
* gccache-gtk.c (free_gc_cache):
* gccache-gtk.c (gc_cache_lookup):
* gccache-x.c (free_gc_cache):
* gccache-x.c (gc_cache_lookup):
* glyphs-eimage.c:
* glyphs-eimage.c (jpeg_instantiate_unwind):
* glyphs-eimage.c (gif_instantiate_unwind):
* glyphs-eimage.c (png_instantiate_unwind):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate_unwind):
* glyphs-gtk.c (convert_EImage_to_GDKImage):
* glyphs-gtk.c (gtk_finalize_image_instance):
* glyphs-gtk.c (gtk_init_image_instance_from_eimage):
* glyphs-gtk.c (gtk_xpm_instantiate):
* glyphs-msw.c (convert_EImage_to_DIBitmap):
* glyphs-msw.c (mswindows_init_image_instance_from_eimage):
* glyphs-msw.c (mswindows_initialize_image_instance_mask):
* glyphs-msw.c (xpm_to_eimage):
* glyphs-msw.c (mswindows_xpm_instantiate):
* glyphs-msw.c (xbm_create_bitmap_from_data):
* glyphs-msw.c (mswindows_finalize_image_instance):
* glyphs-x.c (convert_EImage_to_XImage):
* glyphs-x.c (x_finalize_image_instance):
* glyphs-x.c (x_init_image_instance_from_eimage):
* glyphs-x.c (x_xpm_instantiate):
* gui-x.c (free_popup_widget_value_tree):
* hash.c (free_hash_table):
* hash.c (grow_hash_table):
* hash.c (pregrow_hash_table_if_necessary):
* imgproc.c (build_EImage_quantable):
* insdel.c (uninit_buffer_text):
* intl-win32.c (convert_multibyte_to_internal_malloc):
* intl.c:
* intl.c (Fset_current_locale):
* keymap.c:
* keymap.c (where_is_recursive_mapper):
* keymap.c (where_is_internal):
* lisp.h:
* lisp.h (xfree):
* lstream.c (Lstream_close):
* lstream.c (resizing_buffer_closer):
* mule-coding.c:
* mule-coding.c (iso2022_finalize_detection_state):
* nt.c:
* nt.c (mswindows_get_long_filename):
* nt.c (nt_get_resource):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_opendir):
* nt.c (mswindows_closedir):
* nt.c (mswindows_readdir):
* nt.c (mswindows_stat):
* nt.c (mswindows_getdcwd):
* nt.c (Fmswindows_long_file_name):
* ntplay.c (nt_play_sound_file):
* ntplay.c (play_sound_data_1):
* number-gmp.c (gmp_free):
* number-gmp.c (init_number_gmp):
* number-mp.c (bignum_to_string):
* number-mp.c (BIGNUM_TO_TYPE):
* number.c (bignum_print):
* number.c (bignum_convfree):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-gtk.c (gtk_finalize_color_instance):
* objects-gtk.c (gtk_finalize_font_instance):
* objects-msw.c (mswindows_finalize_color_instance):
* objects-msw.c (mswindows_finalize_font_instance):
* objects-tty.c (tty_finalize_color_instance):
* objects-tty.c (tty_finalize_font_instance):
* objects-tty.c (tty_font_list):
* objects-x.c (x_finalize_color_instance):
* objects-x.c (x_finalize_font_instance):
* process.c:
* process.c (finalize_process):
* realpath.c:
* redisplay.c (add_propagation_runes):
* regex.c:
* regex.c (xfree):
* regex.c (REGEX_FREE_STACK):
* regex.c (FREE_STACK_RETURN):
* regex.c (regex_compile):
* regex.c (regexec):
* regex.c (regfree):
* scrollbar-gtk.c (gtk_free_scrollbar_instance):
* scrollbar-gtk.c (gtk_release_scrollbar_instance):
* scrollbar-msw.c (mswindows_free_scrollbar_instance):
* scrollbar-msw.c (unshow_that_mofo):
* scrollbar-x.c (x_free_scrollbar_instance):
* scrollbar-x.c (x_release_scrollbar_instance):
* select-gtk.c (emacs_gtk_selection_handle):
* select-msw.c (mswindows_own_selection):
* select-x.c:
* select-x.c (x_handle_selection_request):
* select-x.c (unexpect_property_change):
* select-x.c (x_handle_property_notify):
* select-x.c (receive_incremental_selection):
* select-x.c (x_get_window_property_as_lisp_data):
* select-x.c (Fx_get_cutbuffer_internal):
* specifier.c (finalize_specifier):
* syntax.c (uninit_buffer_syntax_cache):
* sysdep.c (qxe_allocating_getcwd):
* sysdep.c (qxe_lstat):
* sysdep.c (copy_in_passwd):
* sysdep.c (qxe_ctime):
* sysdep.c (closedir):
* sysdep.c (DIRSIZ):
* termcap.c (tgetent):
* termcap.c (tprint):
* tests.c (Ftest_data_format_conversion):
* text.c (new_dfc_convert_copy_data):
* text.h (eifree):
* text.h (eito_alloca):
* text.h (eito_external):
* toolbar-msw.c (mswindows_output_toolbar):
* ui-gtk.c (CONVERT_RETVAL):
* ui-gtk.c (__allocate_object_storage):
* unicode.c (free_from_unicode_table):
* unicode.c (free_to_unicode_table):
* unicode.c (free_charset_unicode_tables):
* win32.c (mswindows_read_link_1):
Rename: xfree(VAL, TYPE)->xfree(VAL)
Command used:
gr 'xfree *\((.*),.*\);' 'xfree (\1);' *.[ch]
Followed by grepping for 'xfree.*,' and fixing anything left.
Rationale: Having to specify the TYPE argument is annoying and
error-prone. It was originally put in to work around warnings
due to strict aliasing but years and years ago I rewrote it
in a way that doesn't use the TYPE argument at all and no one
has complained since then. (And anyway, XEmacs is far from
ever being in compliance with strict aliasing and would require
far-reaching changes to get that way.)
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Thu, 04 Feb 2010 07:28:14 -0600 |
parents | 304aebb79cd3 |
children | 3c3c1d139863 |
rev | line source |
---|---|
442 | 1 /* Utility routines for XEmacs on Windows 9x, NT and Cygwin. |
2367 | 2 Copyright (C) 2000, 2001, 2002, 2004 Ben Wing. |
442 | 3 |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to the Free | |
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 02111-1307, USA. */ | |
20 | |
21 #include <config.h> | |
22 #include "lisp.h" | |
23 | |
24 #include "buffer.h" | |
771 | 25 #include "console-msw.h" |
2526 | 26 #include "hash.h" |
27 #include "profile.h" | |
611 | 28 |
771 | 29 #include "sysfile.h" |
30 #include "sysproc.h" | |
859 | 31 #include "syssignal.h" |
611 | 32 #include "systime.h" |
442 | 33 |
2367 | 34 |
35 | |
36 /* | |
37 | |
38 Info on Windows issues: | |
39 | |
40 (Info-goto-node "(internals)Interface to MS Windows") | |
41 | |
42 ------- @file{src/config.h}.in vs. @file{nt/xemacs.mak} ------- | |
43 | |
44 See @file{src/config.h.in} more more info. | |
45 */ | |
46 | |
771 | 47 /* Control conversion of upper case file names to lower case. |
48 nil means no, t means yes. */ | |
49 Lisp_Object Vmswindows_downcase_file_names; | |
50 | |
2526 | 51 struct hash_table *mswindows_read_link_hash; |
52 | |
771 | 53 int mswindows_windows9x_p; |
2526 | 54 Boolint mswindows_shortcuts_are_symlinks; |
771 | 55 |
442 | 56 pfSwitchToThread_t xSwitchToThread; |
57 | |
771 | 58 pfNetUserEnum_t xNetUserEnum; |
59 pfNetApiBufferFree_t xNetApiBufferFree; | |
60 | |
61 /* Convert a filename in standard Win32 format into our internal format | |
62 (which may be significantly different if we're running on Cygwin), and | |
63 turn it into a file: URL. Return a newly malloc()ed string. | |
442 | 64 |
771 | 65 #### This comes from code that just prepended `file:', which is not |
66 good. See comment in mswindows_dde_callback(), case XTYP_EXECUTE. | |
67 */ | |
867 | 68 Ibyte * |
69 urlify_filename (Ibyte *filename) | |
771 | 70 { |
867 | 71 Ibyte *pseudo_url; |
771 | 72 |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
2526
diff
changeset
|
73 INTERNAL_MSWIN_TO_LOCAL_FILE_FORMAT (filename, filename); |
867 | 74 pseudo_url = xnew_array (Ibyte, 5 + qxestrlen (filename) + 1); |
2367 | 75 qxestrcpy_ascii (pseudo_url, "file:"); |
771 | 76 qxestrcat (pseudo_url, filename); |
77 /* URL's only have /, no backslash */ | |
78 for (filename = pseudo_url; *filename; filename++) | |
79 { | |
80 if (*filename == '\\') | |
81 *filename = '/'; | |
82 } | |
442 | 83 |
771 | 84 return pseudo_url; |
85 } | |
531 | 86 |
826 | 87 /* Convert a Win32 file name in tstr format into a local-format file name |
88 in internal format. */ | |
89 | |
442 | 90 Lisp_Object |
826 | 91 tstr_to_local_file_format (Extbyte *path) |
442 | 92 { |
867 | 93 Ibyte *ttlff; |
771 | 94 |
826 | 95 TSTR_TO_C_STRING (path, ttlff); |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
2526
diff
changeset
|
96 INTERNAL_MSWIN_TO_LOCAL_FILE_FORMAT (ttlff, ttlff); |
771 | 97 |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
98 return build_istring (ttlff); |
771 | 99 } |
100 | |
101 /* Normalize filename by converting all path separators to the specified | |
102 separator. Also conditionally convert all-upper-case path name | |
103 components to lower case. Return a newly malloc()ed string. | |
104 */ | |
105 | |
867 | 106 Ibyte * |
107 mswindows_canonicalize_filename (Ibyte *name) | |
771 | 108 { |
867 | 109 Ibyte *fp = name; |
771 | 110 DECLARE_EISTRING (newname); |
111 DECLARE_EISTRING (component); | |
112 int do_casefrob = 1; | |
442 | 113 |
771 | 114 /* Always lower-case drive letters a-z, even if the filesystem |
115 preserves case in filenames. | |
116 This is so filenames can be compared by string comparison | |
117 functions that are case-sensitive. Even case-preserving filesystems | |
118 do not distinguish case in drive letters. */ | |
119 if (name[0] >= 'A' && name[0] <= 'Z' && name[1] == ':') | |
120 { | |
121 eicat_ch (newname, name[0] + 'a' - 'A'); | |
122 eicat_ch (newname, ':'); | |
123 fp += 2; | |
124 } | |
125 | |
126 while (1) | |
127 { | |
867 | 128 Ichar ch = itext_ichar (fp); |
771 | 129 if (LOWERCASEP (0, ch)) |
130 do_casefrob = 0; /* don't convert this element */ | |
442 | 131 |
771 | 132 if (ch == 0 || IS_ANY_SEP (ch)) |
133 { | |
134 if (do_casefrob && !NILP (Vmswindows_downcase_file_names)) | |
135 eilwr (component); | |
136 do_casefrob = 1; | |
137 eicat_ei (newname, component); | |
138 eireset (component); | |
139 if (IS_DIRECTORY_SEP (ch)) | |
140 eicat_ch (newname, DIRECTORY_SEP); | |
141 else if (ch) | |
142 eicat_ch (newname, ch); | |
143 else | |
144 break; | |
145 } | |
146 else | |
147 eicat_ch (component, ch); | |
148 | |
867 | 149 INC_IBYTEPTR (fp); |
771 | 150 } |
151 | |
152 return eicpyout_malloc (newname, 0); | |
442 | 153 } |
154 | |
814 | 155 Extbyte * |
156 mswindows_get_module_file_name (void) | |
157 { | |
158 Extbyte *path = NULL; | |
159 int bufsize = 4096; | |
160 int cchpathsize; | |
161 | |
162 while (1) | |
163 { | |
164 path = (Extbyte *) xrealloc (path, bufsize * XETCHAR_SIZE); | |
165 cchpathsize = qxeGetModuleFileName (NULL, path, bufsize); | |
166 if (!cchpathsize) | |
167 return 0; | |
168 if (cchpathsize + 1 <= bufsize) | |
169 break; | |
170 bufsize *= 2; | |
171 } | |
172 | |
173 return path; | |
174 } | |
175 | |
442 | 176 static void |
177 init_potentially_nonexistent_functions (void) | |
178 { | |
771 | 179 HMODULE h_kernel = qxeGetModuleHandle (XETEXT ("kernel32")); |
531 | 180 /* the following does not seem to get mapped in automatically */ |
771 | 181 HMODULE h_netapi = qxeLoadLibrary (XETEXT ("netapi32.dll")); |
442 | 182 |
183 if (h_kernel) | |
184 { | |
185 xSwitchToThread = | |
186 (pfSwitchToThread_t) GetProcAddress (h_kernel, "SwitchToThread"); | |
187 } | |
188 | |
531 | 189 if (h_netapi) |
190 { | |
191 xNetUserEnum = | |
192 (pfNetUserEnum_t) GetProcAddress (h_netapi, "NetUserEnum"); | |
193 xNetApiBufferFree = | |
194 (pfNetApiBufferFree_t) GetProcAddress (h_netapi, "NetApiBufferFree"); | |
195 } | |
442 | 196 } |
197 | |
771 | 198 static Lisp_Object |
199 mswindows_lisp_error_1 (int errnum, int no_recurse) | |
200 { | |
201 LPTSTR lpMsgBuf; | |
202 Lisp_Object result; | |
867 | 203 Ibyte *inres; |
771 | 204 Bytecount len; |
205 int i; | |
206 | |
207 /* The docs for FormatMessage say: | |
208 | |
209 If you pass a specific LANGID in this parameter, FormatMessage | |
210 will return a message for that LANGID only. If the function | |
211 cannot find a message for that LANGID, it returns | |
212 ERROR_RESOURCE_LANG_NOT_FOUND. If you pass in zero, FormatMessage | |
213 looks for a message for LANGIDs in the following order: | |
214 | |
215 Language neutral | |
216 Thread LANGID, based on the thread's locale value | |
217 User default LANGID, based on the user's default locale value | |
218 System default LANGID, based on the system default locale value | |
219 US English | |
220 | |
221 If FormatMessage doesn't find a message for any of the preceding | |
222 LANGIDs, it returns any language message string that is present. If | |
223 that fails, it returns ERROR_RESOURCE_LANG_NOT_FOUND. (Note, this is | |
224 returned through GetLastError(), not the return value.) | |
225 | |
226 #### what the hell is "language neutral"? i can find no info on this. | |
227 so let's do our own language first. | |
228 */ | |
229 | |
230 for (i = 0; ; i++) | |
231 { | |
232 int lang = 0; | |
233 int retval; | |
234 | |
235 switch (i) | |
236 { | |
237 #ifdef MULE | |
238 /* Urk! Windows 95 doesn't let you set the thread locale! | |
239 so we have to maintain our own. */ | |
240 case 0: lang = LANGIDFROMLCID (mswindows_current_locale ()); break; | |
241 case 1: lang = 0; break; | |
242 #else | |
243 case 0: lang = 0; break; | |
244 #endif | |
2500 | 245 default: ABORT (); |
771 | 246 } |
247 | |
248 retval = qxeFormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | |
249 | FORMAT_MESSAGE_FROM_SYSTEM, | |
250 NULL, errnum, lang, | |
251 /* yeah, i'm casting a char ** to a char *. | |
252 ya gotta problem widdat? */ | |
253 (Extbyte *) &lpMsgBuf, 0, NULL); | |
254 | |
255 if (!retval) | |
256 { | |
257 if (lang != 0) | |
258 continue; | |
259 | |
260 if (no_recurse) | |
261 return emacs_sprintf_string | |
262 ("Unknown error code %d (error return %ld from FormatMessage())", | |
263 errnum, GetLastError ()); | |
264 else | |
265 return emacs_sprintf_string | |
266 ("Unknown error code %d (error return %s from FormatMessage())", | |
267 /* It's OK, emacs_sprintf_string disables GC explicitly */ | |
268 errnum, XSTRING_DATA (mswindows_lisp_error_1 (errnum, 1))); | |
269 } | |
270 else | |
271 break; | |
272 } | |
273 | |
274 TSTR_TO_C_STRING (lpMsgBuf, inres); | |
275 len = qxestrlen (inres); | |
276 /* Messages tend to end with a period and newline */ | |
2367 | 277 if (len >= 3 && !qxestrcmp_ascii (inres + len - 3, ".\r\n")) |
771 | 278 len -= 3; |
279 result = make_string (inres, len); | |
280 | |
281 LocalFree (lpMsgBuf); | |
282 return result; | |
283 } | |
284 | |
285 Lisp_Object | |
286 mswindows_lisp_error (int errnum) | |
287 { | |
288 return mswindows_lisp_error_1 (errnum, 0); | |
289 } | |
290 | |
291 void | |
4932 | 292 mswindows_output_last_error (const Ascbyte *frob) |
771 | 293 { |
294 int errval = GetLastError (); | |
295 Lisp_Object errmess = mswindows_lisp_error (errval); | |
296 | |
297 stderr_out ("last error during %s is %d: %s\n", | |
298 frob, errval, XSTRING_DATA (errmess)); | |
299 } | |
300 | |
301 DOESNT_RETURN | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
302 mswindows_report_process_error (const Ascbyte *reason, Lisp_Object data, |
771 | 303 int errnum) |
304 { | |
305 report_file_type_error (Qprocess_error, mswindows_lisp_error (errnum), | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
306 reason, data); |
771 | 307 } |
308 | |
442 | 309 DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /* |
310 Get Windows to perform OPERATION on DOCUMENT. | |
311 This is a wrapper around the ShellExecute system function, which | |
312 invokes the application registered to handle OPERATION for DOCUMENT. | |
313 OPERATION is typically \"open\", \"print\" or \"explore\" (but can be | |
314 nil for the default action), and DOCUMENT is typically the name of a | |
315 document file or URL, but can also be a program executable to run or | |
316 a directory to open in the Windows Explorer. | |
317 | |
318 If DOCUMENT is a program executable, PARAMETERS can be a string | |
319 containing command line parameters, but otherwise should be nil. | |
320 | |
321 SHOW-FLAG can be used to control whether the invoked application is hidden | |
322 or minimized. If SHOW-FLAG is nil, the application is displayed normally, | |
323 otherwise it is an integer representing a ShowWindow flag: | |
324 | |
325 0 - start hidden | |
326 1 - start normally | |
327 3 - start maximized | |
328 6 - start minimized | |
329 */ | |
330 (operation, document, parameters, show_flag)) | |
331 { | |
332 /* Encode filename and current directory. */ | |
333 Lisp_Object current_dir = Ffile_name_directory (document); | |
334 int ret; | |
335 | |
336 CHECK_STRING (document); | |
337 | |
338 if (NILP (current_dir)) | |
339 current_dir = current_buffer->directory; | |
340 | |
771 | 341 { |
342 Extbyte *opext = NULL; | |
343 Extbyte *parmext = NULL; | |
344 Extbyte *path = NULL; | |
345 Extbyte *doc = NULL; | |
442 | 346 |
771 | 347 if (STRINGP (operation)) |
348 LISP_STRING_TO_TSTR (operation, opext); | |
2526 | 349 /* #### What about path names, which may be links? */ |
771 | 350 if (STRINGP (parameters)) |
351 LISP_STRING_TO_TSTR (parameters, parmext); | |
352 if (STRINGP (current_dir)) | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
2526
diff
changeset
|
353 LISP_LOCAL_FILE_FORMAT_TO_TSTR (current_dir, path); |
826 | 354 if (STRINGP (document)) |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
2526
diff
changeset
|
355 LISP_LOCAL_FILE_FORMAT_MAYBE_URL_TO_TSTR (document, doc); |
442 | 356 |
771 | 357 ret = (int) qxeShellExecute (NULL, opext, doc, parmext, path, |
358 (INTP (show_flag) ? | |
359 XINT (show_flag) : SW_SHOWDEFAULT)); | |
360 } | |
442 | 361 |
771 | 362 if (ret <= 32) |
363 { | |
364 /* Convert to more standard errors */ | |
365 #define FROB(a, b) if (ret == a) ret = b | |
366 FROB (SE_ERR_ACCESSDENIED, ERROR_ACCESS_DENIED); | |
367 FROB (SE_ERR_ASSOCINCOMPLETE, ERROR_NO_ASSOCIATION); | |
368 FROB (SE_ERR_DDEBUSY, ERROR_DDE_FAIL); | |
369 FROB (SE_ERR_DDEFAIL, ERROR_DDE_FAIL); | |
370 FROB (SE_ERR_DDETIMEOUT, ERROR_DDE_FAIL); | |
371 FROB (SE_ERR_DLLNOTFOUND, ERROR_DLL_NOT_FOUND); | |
372 FROB (SE_ERR_FNF, ERROR_FILE_NOT_FOUND); | |
373 FROB (SE_ERR_NOASSOC, ERROR_NO_ASSOCIATION); | |
374 FROB (SE_ERR_OOM, ERROR_NOT_ENOUGH_MEMORY); | |
375 FROB (SE_ERR_PNF, ERROR_PATH_NOT_FOUND); | |
376 FROB (SE_ERR_SHARE, ERROR_SHARING_VIOLATION); | |
377 #undef FROB | |
378 | |
379 mswindows_report_process_error ("Running ShellExecute", | |
380 ret == ERROR_PATH_NOT_FOUND ? | |
381 list4 (Qunbound, operation, document, | |
382 current_dir) : | |
383 list3 (Qunbound, operation, document), | |
384 ret); | |
385 } | |
442 | 386 |
771 | 387 return Qt; |
442 | 388 } |
389 | |
673 | 390 #ifdef CYGWIN |
391 DEFUN ("mswindows-cygwin-to-win32-path", Fmswindows_cygwin_to_win32_path, 1, 1, 0, /* | |
392 Get the cygwin environment to convert the Unix PATH to win32 format. | |
393 No expansion is performed, all conversion is done by the cygwin runtime. | |
394 */ | |
395 (path)) | |
396 { | |
867 | 397 Ibyte *p; |
673 | 398 CHECK_STRING (path); |
399 | |
400 /* There appears to be a bug in the cygwin conversion routines in | |
401 that they are not idempotent. */ | |
402 p = XSTRING_DATA (path); | |
403 if (isalpha (p[0]) && (IS_DEVICE_SEP (p[1]))) | |
404 return path; | |
405 | |
406 /* Use mule and cygwin-safe APIs top get at file data. */ | |
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
2526
diff
changeset
|
407 LOCAL_FILE_FORMAT_TO_INTERNAL_MSWIN (p, p); |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
408 return build_istring (p); |
673 | 409 } |
410 #endif | |
411 | |
2526 | 412 struct read_link_hash |
413 { | |
414 Ibyte *resolved; | |
415 DWORD ticks; | |
416 }; | |
417 | |
418 static Ibyte * | |
419 mswindows_read_link_1 (const Ibyte *fname) | |
420 { | |
4879
c356806cc933
fix compile errors when --with-msw=no
Ben Wing <ben@xemacs.org>
parents:
4854
diff
changeset
|
421 #if defined (NO_CYGWIN_COM_SUPPORT) || !defined (HAVE_MS_WINDOWS) |
2526 | 422 return NULL; |
423 #else | |
424 Ibyte *retval = NULL; | |
425 Extbyte *fnameext; | |
426 HANDLE fh; | |
427 struct read_link_hash *rlh; | |
428 DWORD ticks; | |
429 | |
430 /* The call below to resolve a link is rather time-consuming. | |
431 I tried implementing a simple cache based on creation and write time | |
432 of the file, but that didn't help enough -- maybe 30% faster but still | |
433 a lot of time spent here. So just do something cheesy and don't | |
434 check again if we've recently (< a second) done so. */ | |
435 | |
436 if (!mswindows_read_link_hash) | |
437 mswindows_read_link_hash = make_string_hash_table (1000); | |
438 C_STRING_TO_TSTR (fname, fnameext); | |
439 | |
440 /* See if we can find a cached value. */ | |
441 | |
442 /* The intermediate cast fools gcc into not outputting strict-aliasing | |
443 complaints */ | |
444 ticks = GetTickCount (); | |
445 if (!gethash (fname, mswindows_read_link_hash, | |
446 (const void **) (void *) &rlh)) | |
447 { | |
448 rlh = xnew_and_zero (struct read_link_hash); | |
449 puthash (qxestrdup (fname), rlh, mswindows_read_link_hash); | |
450 } | |
451 else if (ticks - rlh->ticks < 1000) | |
452 { | |
453 return rlh->resolved ? qxestrdup (rlh->resolved) : NULL; | |
454 } | |
455 | |
456 rlh->ticks = ticks; | |
457 | |
458 /* Retrieve creation/write time of link file. */ | |
459 | |
460 /* No access rights required to get info. */ | |
461 if ((fh = qxeCreateFile (fnameext, 0, 0, NULL, OPEN_EXISTING, 0, NULL)) | |
462 == INVALID_HANDLE_VALUE) | |
463 { | |
464 CloseHandle (fh); | |
465 return NULL; | |
466 } | |
467 | |
468 CloseHandle (fh); | |
469 | |
470 /* #### | |
471 | |
472 Note the following in the docs: | |
473 | |
474 Note: The IShellLink interface has an ANSI version | |
475 (IShellLinkA) and a Unicode version (IShellLinkW). The | |
476 version that will be used depends on whether you compile | |
477 for ANSI or Unicode. However, Microsoft® Windows 95 and | |
478 Microsoft® Windows 98 only support IShellLinkA. | |
479 | |
480 We haven't yet implemented COM support in the | |
481 Unicode-splitting library. I don't quite understand how | |
482 COM works yet, but it looks like what's happening is | |
483 that the ShellLink class implements both the IShellLinkA | |
484 and IShellLinkW interfaces. To make this work at | |
485 run-time, we have to do something like this: | |
486 | |
487 -- define a new interface qxeIShellLink that uses | |
488 Extbyte * instead of LPSTR or LPWSTR. (not totally | |
489 necessary since Extbyte * == LPSTR). | |
490 | |
491 -- define a new class qxeShellLink that implements | |
492 qxeIShellLink. the methods on this class need to create | |
493 a shadow ShellLink object to do all the real work, and | |
494 call the corresponding function from either the | |
495 IShellLinkA or IShellLinkW interfaces on this object, | |
496 depending on whether XEUNICODE_P is defined. | |
497 | |
498 -- with appropriate preprocessor magic, of course, we | |
499 could make things appear transparent; but we've decided | |
500 not to do preprocessor magic for the moment. | |
501 */ | |
502 | |
503 /* #### Not Unicode-split for the moment; we have to do it | |
504 ourselves. */ | |
505 if (XEUNICODE_P) | |
506 { | |
507 IShellLinkW *psl; | |
508 | |
509 if (CoCreateInstance ( | |
510 XECOMID (CLSID_ShellLink), | |
511 NULL, | |
512 CLSCTX_INPROC_SERVER, | |
513 XECOMID (IID_IShellLinkW), | |
514 &VOIDP_CAST (psl)) == S_OK) | |
515 { | |
516 IPersistFile *ppf; | |
517 | |
518 if (XECOMCALL2 (psl, QueryInterface, | |
519 XECOMID (IID_IPersistFile), | |
520 &VOIDP_CAST (ppf)) == S_OK) | |
521 { | |
522 Extbyte *fname_unicode; | |
523 WIN32_FIND_DATAW wfd; | |
4854 | 524 LPWSTR resolved = alloca_array (WCHAR, PATH_MAX_TCHAR + 1); |
2526 | 525 |
526 /* Always Unicode. Not obvious from the | |
527 IPersistFile documentation, but look under | |
528 "Shell Link" for example code. */ | |
529 fname_unicode = fnameext; | |
530 | |
531 if (XECOMCALL2 (ppf, Load, | |
532 (LPWSTR) fname_unicode, | |
533 STGM_READ) == S_OK && | |
534 /* #### YUCK! Docs read | |
535 | |
536 cchMaxPath | |
537 | |
538 Maximum number of bytes to copy to the buffer pointed | |
539 to by the pszFile parameter. | |
540 | |
541 But "cch" means "count of characters", not bytes. | |
542 I'll assume the doc writers messed up and the | |
543 programmer was correct. Also, this approach is safe | |
544 even if it's actually the other way around. */ | |
545 #if defined (CYGWIN_HEADERS) && W32API_INSTALLED_VER < W32API_VER(2,2) | |
546 /* Another Cygwin prototype error, | |
547 fixed in v2.2 of w32api */ | |
548 XECOMCALL4 (psl, GetPath, (LPSTR) resolved, | |
4854 | 549 PATH_MAX_TCHAR, &wfd, 0) |
2526 | 550 #else |
551 XECOMCALL4 (psl, GetPath, resolved, | |
4854 | 552 PATH_MAX_TCHAR, &wfd, 0) |
2526 | 553 #endif |
554 == S_OK) | |
555 TSTR_TO_C_STRING_MALLOC (resolved, retval); | |
556 | |
557 XECOMCALL0 (ppf, Release); | |
558 } | |
559 | |
560 XECOMCALL0 (psl, Release); | |
561 } | |
562 } | |
563 else | |
564 { | |
565 IShellLinkA *psl; | |
566 | |
567 if (CoCreateInstance ( | |
568 XECOMID (CLSID_ShellLink), | |
569 NULL, | |
570 CLSCTX_INPROC_SERVER, | |
571 XECOMID (IID_IShellLinkA), | |
572 &VOIDP_CAST (psl)) == S_OK) | |
573 { | |
574 IPersistFile *ppf; | |
575 | |
576 if (XECOMCALL2 (psl, QueryInterface, | |
577 XECOMID (IID_IPersistFile), | |
578 &VOIDP_CAST (ppf)) == S_OK) | |
579 { | |
580 Extbyte *fname_unicode; | |
581 WIN32_FIND_DATAA wfd; | |
4854 | 582 LPSTR resolved = alloca_array (CHAR, PATH_MAX_TCHAR + 1); |
2526 | 583 |
584 /* Always Unicode. Not obvious from the | |
585 IPersistFile documentation, but look under | |
586 "Shell Link" for example code. */ | |
587 C_STRING_TO_EXTERNAL (fname, fname_unicode, | |
588 Qmswindows_unicode); | |
589 | |
590 if (XECOMCALL2 (ppf, Load, | |
591 (LPWSTR) fname_unicode, | |
592 STGM_READ) == S_OK | |
593 && XECOMCALL4 (psl, GetPath, resolved, | |
4854 | 594 PATH_MAX_TCHAR, &wfd, 0) == S_OK) |
2526 | 595 TSTR_TO_C_STRING_MALLOC (resolved, retval); |
596 | |
597 XECOMCALL0 (ppf, Release); | |
598 } | |
599 | |
600 XECOMCALL0 (psl, Release); | |
601 } | |
602 } | |
603 | |
604 /* Cache newly found value */ | |
605 if (rlh->resolved) | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4953
diff
changeset
|
606 xfree (rlh->resolved); |
2526 | 607 rlh->resolved = retval ? qxestrdup (retval) : NULL; |
608 | |
609 return retval; | |
610 #endif /* NO_CYGWIN_COM_SUPPORT */ | |
611 } | |
612 | |
613 /* Resolve a file that may be a shortcut. Accepts either a file ending | |
614 with .LNK or without the ending. If a shortcut is found, returns | |
615 a value that you must xfree(); otherwise NULL. */ | |
616 | |
617 Ibyte * | |
618 mswindows_read_link (const Ibyte *fname) | |
619 { | |
620 int len = qxestrlen (fname); | |
621 if (len > 4 && !qxestrcasecmp_ascii (fname + len - 4, ".LNK")) | |
622 return mswindows_read_link_1 (fname); | |
623 else | |
624 { | |
625 DECLARE_EISTRING (name2); | |
626 | |
627 eicpy_rawz (name2, fname); | |
628 eicat_ascii (name2, ".LNK"); | |
629 return mswindows_read_link_1 (eidata (name2)); | |
630 } | |
631 } | |
632 | |
633 | |
613 | 634 #if defined (WIN32_NATIVE) || defined (CYGWIN_BROKEN_SIGNALS) |
635 | |
636 /* setitimer() does not exist on native MS Windows, and appears broken | |
637 on Cygwin (random lockups when BROKEN_SIGIO is defined), so we | |
638 emulate in both cases by using multimedia timers. Furthermore, | |
639 the lockups still occur on Cygwin even when we do nothing but | |
640 use the standard signalling mechanism -- so we have to emulate | |
641 that, too. (But only for timeouts -- we have to use the standard | |
642 mechanism for SIGCHLD. Yuck.) | |
643 */ | |
644 | |
645 /*--------------------------------------------------------------------*/ | |
646 /* Signal support */ | |
647 /*--------------------------------------------------------------------*/ | |
648 | |
649 #define sigmask(nsig) (1U << nsig) | |
650 | |
651 /* We can support as many signals as fit into word */ | |
652 #define SIG_MAX 32 | |
653 | |
654 /* Signal handlers. Initial value = 0 = SIG_DFL */ | |
655 static mswindows_sighandler signal_handlers[SIG_MAX] = {0}; | |
656 | |
657 /* Signal block mask: bit set to 1 means blocked */ | |
658 unsigned signal_block_mask = 0; | |
659 | |
660 /* Signal pending mask: bit set to 1 means sig is pending */ | |
661 unsigned signal_pending_mask = 0; | |
662 | |
663 mswindows_sighandler | |
664 mswindows_sigset (int nsig, mswindows_sighandler handler) | |
665 { | |
666 /* We delegate some signals to the system function */ | |
667 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) | |
668 return signal (nsig, handler); | |
669 | |
670 if (nsig < 0 || nsig > SIG_MAX) | |
671 { | |
672 errno = EINVAL; | |
673 return NULL; | |
674 } | |
675 | |
676 /* Store handler ptr */ | |
677 { | |
678 mswindows_sighandler old_handler = signal_handlers[nsig]; | |
679 signal_handlers[nsig] = handler; | |
680 return old_handler; | |
681 } | |
682 } | |
683 | |
684 int | |
685 mswindows_sighold (int nsig) | |
686 { | |
687 if (nsig < 0 || nsig > SIG_MAX) | |
688 return errno = EINVAL; | |
689 | |
690 signal_block_mask |= sigmask (nsig); | |
691 return 0; | |
692 } | |
693 | |
694 int | |
695 mswindows_sigrelse (int nsig) | |
696 { | |
697 if (nsig < 0 || nsig > SIG_MAX) | |
698 return errno = EINVAL; | |
699 | |
700 signal_block_mask &= ~sigmask (nsig); | |
701 | |
702 if (signal_pending_mask & sigmask (nsig)) | |
703 mswindows_raise (nsig); | |
704 | |
705 return 0; | |
706 } | |
707 | |
708 int | |
2286 | 709 mswindows_sigpause (int UNUSED (nsig)) |
613 | 710 { |
711 /* This is currently not called, because the only call to sigpause | |
712 inside XEmacs is with SIGCHLD parameter. Just in case, we put an | |
2286 | 713 assert here, so anyone who adds a call to sigpause will be surprised |
613 | 714 (or surprise someone else...) */ |
715 assert (0); | |
716 return 0; | |
717 } | |
718 | |
719 int | |
720 mswindows_raise (int nsig) | |
721 { | |
722 /* We delegate some raises to the system routine */ | |
723 if (nsig == SIGFPE || nsig == SIGABRT || nsig == SIGINT) | |
724 return raise (nsig); | |
725 | |
726 if (nsig < 0 || nsig > SIG_MAX) | |
727 return errno = EINVAL; | |
728 | |
729 /* If the signal is blocked, remember to issue later */ | |
730 if (signal_block_mask & sigmask (nsig)) | |
731 { | |
732 signal_pending_mask |= sigmask (nsig); | |
733 return 0; | |
734 } | |
735 | |
736 if (signal_handlers[nsig] == SIG_IGN) | |
737 return 0; | |
738 | |
739 if (signal_handlers[nsig] != SIG_DFL) | |
740 { | |
741 (*signal_handlers[nsig]) (nsig); | |
742 return 0; | |
743 } | |
744 | |
745 /* Default signal actions */ | |
746 if (nsig == SIGALRM || nsig == SIGPROF) | |
747 exit (3); | |
748 | |
749 /* Other signals are ignored by default */ | |
750 return 0; | |
751 } | |
752 | |
611 | 753 |
754 /*--------------------------------------------------------------------*/ | |
755 /* Async timers */ | |
756 /*--------------------------------------------------------------------*/ | |
757 | |
758 /* We emulate two timers, one for SIGALRM, another for SIGPROF. | |
759 | |
760 itimerproc() function has an implementation limitation: it does | |
761 not allow to set *both* interval and period. If an attempt is | |
762 made to set both, and then they are unequal, the function | |
763 asserts. | |
764 | |
765 Minimum timer resolution on Win32 systems varies, and is greater | |
766 than or equal than 1 ms. The resolution is always wrapped not to | |
767 attempt to get below the system defined limit. | |
768 */ | |
769 | |
770 /* Timer precision, denominator of one fraction: for 100 ms | |
771 interval, request 10 ms precision | |
772 */ | |
773 const int setitimer_helper_timer_prec = 10; | |
774 | |
775 /* Last itimervals, as set by calls to setitimer */ | |
776 static struct itimerval it_alarm; | |
777 static struct itimerval it_prof; | |
778 | |
779 /* Timer IDs as returned by MM */ | |
780 MMRESULT tid_alarm = 0; | |
781 MMRESULT tid_prof = 0; | |
782 | |
783 static void CALLBACK | |
2286 | 784 setitimer_helper_proc (UINT UNUSED (uID), UINT UNUSED (uMsg), DWORD dwUser, |
785 DWORD UNUSED (dw1), DWORD UNUSED (dw2)) | |
611 | 786 { |
787 /* Just raise the signal indicated by the dwUser parameter */ | |
788 mswindows_raise (dwUser); | |
789 } | |
790 | |
791 /* Divide time in ms specified by IT by DENOM. Return 1 ms | |
792 if division results in zero */ | |
793 static UINT | |
853 | 794 setitimer_helper_period (const struct itimerval *it, UINT denom) |
611 | 795 { |
796 static TIMECAPS time_caps; | |
797 | |
798 UINT res; | |
853 | 799 const struct timeval *tv = |
611 | 800 (it->it_value.tv_sec == 0 && it->it_value.tv_usec == 0) |
801 ? &it->it_interval : &it->it_value; | |
802 | |
803 /* Zero means stop timer */ | |
804 if (tv->tv_sec == 0 && tv->tv_usec == 0) | |
805 return 0; | |
806 | |
807 /* Convert to ms and divide by denom */ | |
808 res = (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000) / denom; | |
809 | |
810 /* Converge to minimum timer resolution */ | |
811 if (time_caps.wPeriodMin == 0) | |
812 timeGetDevCaps (&time_caps, sizeof(time_caps)); | |
813 | |
814 if (res < time_caps.wPeriodMin) | |
815 res = time_caps.wPeriodMin; | |
816 | |
817 return res; | |
818 } | |
819 | |
820 static int | |
853 | 821 setitimer_helper (const struct itimerval *itnew, |
822 struct itimerval *itold, struct itimerval *itcurrent, | |
823 MMRESULT *tid, DWORD sigkind) | |
611 | 824 { |
825 UINT delay, resolution, event_type; | |
826 | |
827 /* First stop the old timer */ | |
828 if (*tid) | |
829 { | |
830 timeKillEvent (*tid); | |
831 timeEndPeriod (setitimer_helper_period (itcurrent, | |
832 setitimer_helper_timer_prec)); | |
833 *tid = 0; | |
834 } | |
835 | |
836 /* Return old itimerval if requested */ | |
837 if (itold) | |
838 *itold = *itcurrent; | |
839 | |
840 *itcurrent = *itnew; | |
841 | |
842 /* Determine if to start new timer */ | |
843 delay = setitimer_helper_period (itnew, 1); | |
844 if (delay) | |
845 { | |
846 resolution = setitimer_helper_period (itnew, | |
847 setitimer_helper_timer_prec); | |
848 event_type = (itnew->it_value.tv_sec == 0 && | |
849 itnew->it_value.tv_usec == 0) | |
850 ? TIME_ONESHOT : TIME_PERIODIC; | |
851 timeBeginPeriod (resolution); | |
852 *tid = timeSetEvent (delay, resolution, setitimer_helper_proc, sigkind, | |
853 event_type); | |
854 } | |
855 | |
856 return !delay || *tid; | |
857 } | |
858 | |
859 int | |
860 mswindows_setitimer (int kind, const struct itimerval *itnew, | |
861 struct itimerval *itold) | |
862 { | |
863 /* In this version, both interval and value are allowed | |
864 only if they are equal. */ | |
865 assert ((itnew->it_value.tv_sec == 0 && itnew->it_value.tv_usec == 0) | |
866 || (itnew->it_interval.tv_sec == 0 && | |
867 itnew->it_interval.tv_usec == 0) | |
868 || (itnew->it_value.tv_sec == itnew->it_interval.tv_sec && | |
869 itnew->it_value.tv_usec == itnew->it_interval.tv_usec)); | |
870 | |
871 if (kind == ITIMER_REAL) | |
872 return setitimer_helper (itnew, itold, &it_alarm, &tid_alarm, SIGALRM); | |
873 else if (kind == ITIMER_PROF) | |
874 return setitimer_helper (itnew, itold, &it_prof, &tid_prof, SIGPROF); | |
875 else | |
876 return errno = EINVAL; | |
877 } | |
878 | |
613 | 879 #endif /* defined (WIN32_NATIVE) || defined (CYGWIN_BROKEN_SIGNALS) */ |
880 | |
611 | 881 |
442 | 882 void |
883 syms_of_win32 (void) | |
884 { | |
885 DEFSUBR (Fmswindows_shell_execute); | |
673 | 886 #ifdef CYGWIN |
887 DEFSUBR (Fmswindows_cygwin_to_win32_path); | |
888 #endif | |
442 | 889 } |
890 | |
891 void | |
771 | 892 vars_of_win32 (void) |
893 { | |
2526 | 894 DEFVAR_LISP ("mswindows-downcase-file-names", |
895 &Vmswindows_downcase_file_names /* | |
771 | 896 Non-nil means convert all-upper case file names to lower case. |
897 This applies when performing completions and file name expansion. | |
898 */ ); | |
899 Vmswindows_downcase_file_names = Qnil; | |
2526 | 900 |
901 DEFVAR_BOOL ("mswindows-shortcuts-are-symlinks", | |
902 &mswindows_shortcuts_are_symlinks /* | |
903 Non-nil means shortcuts (.LNK files) are treated as symbolic links. | |
904 This works also for symlinks created under Cygwin, because they use .LNK | |
905 files to implement symbolic links. | |
906 */ ); | |
907 mswindows_shortcuts_are_symlinks = 1; | |
771 | 908 } |
909 | |
910 void | |
442 | 911 init_win32 (void) |
912 { | |
913 init_potentially_nonexistent_functions (); | |
914 } | |
771 | 915 |
916 void | |
2367 | 917 init_win32_very_very_early (void) |
771 | 918 { |
919 mswindows_windows9x_p = GetVersion () & 0x80000000; | |
920 } |