XEmacs 21.2.33 "Melpomene".
[chise/xemacs-chise.git.1] / src / gui-msw.c
1 /* mswindows GUI code. (menubars, scrollbars, toolbars, dialogs)
2    Copyright (C) 1998 Andy Piper.
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
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: Not in FSF. */
22
23 #include <config.h>
24 #include "lisp.h"
25 #include "redisplay.h"
26 #include "gui.h"
27 #include "glyphs.h"
28 #include "frame.h"
29 #include "events.h"
30 #include "elhash.h"
31 #include "console-msw.h"
32 #include "buffer.h"
33
34 /*
35  * Return value is Qt if we have dispatched the command,
36  * or Qnil if id has not been mapped to a callback.
37  * Window procedure may try other targets to route the
38  * command if we return nil
39  */
40 Lisp_Object
41 mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, LPARAM id)
42 {
43   /* Try to map the command id through the proper hash table */
44   Lisp_Object callback, callback_ex, image_instance, frame, event;
45
46   XSETFRAME (frame, f);
47
48   /* #### make_int should assert that --kkm */
49   assert (XINT (make_int (id)) == id);
50
51   image_instance = Fgethash (make_int (id), 
52                              FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f), Qnil);
53   callback = Fgethash (make_int (id), 
54                        FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f), Qnil);
55   callback_ex = Fgethash (make_int (id), 
56                           FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f), Qnil);
57
58   if (!NILP (callback_ex) && !UNBOUNDP (callback_ex))
59     {
60       event = Fmake_event (Qnil, Qnil);
61
62       XEVENT (event)->event_type = misc_user_event;
63       XEVENT (event)->channel = frame;
64       XEVENT (event)->timestamp = GetTickCount ();
65       XEVENT (event)->event.eval.function = Qeval;
66       XEVENT (event)->event.eval.object =
67         list4 (Qfuncall, callback_ex, image_instance, event);
68     }
69   else if (NILP (callback) || UNBOUNDP (callback))
70     return Qnil;
71   else
72     {
73       Lisp_Object fn, arg;
74
75       event = Fmake_event (Qnil, Qnil);
76
77       get_gui_callback (callback, &fn, &arg);
78       XEVENT (event)->event_type = misc_user_event;
79       XEVENT (event)->channel = frame;
80       XEVENT (event)->timestamp = GetTickCount ();
81       XEVENT (event)->event.eval.function = fn;
82       XEVENT (event)->event.eval.object = arg;
83     }
84
85   mswindows_enqueue_dispatch_event (event);
86   /* The result of this evaluation could cause other instances to change so 
87      enqueue an update callback to check this. We also have to make sure that
88      the function does not appear in the command history.
89      #### I'm sure someone can tell me how to optimize this. */
90   mswindows_enqueue_misc_user_event
91     (frame, Qeval, 
92      list3 (Qlet,
93             list2 (Qthis_command,
94                    Qlast_command),
95             list2 (Qupdate_widget_instances, frame)));
96   return Qt;
97 }
98
99 DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /*
100 Get Windows to perform OPERATION on DOCUMENT.
101 This is a wrapper around the ShellExecute system function, which
102 invokes the application registered to handle OPERATION for DOCUMENT.
103 OPERATION is typically \"open\", \"print\" or \"explore\" (but can be
104 nil for the default action), and DOCUMENT is typically the name of a
105 document file or URL, but can also be a program executable to run or
106 a directory to open in the Windows Explorer.
107
108 If DOCUMENT is a program executable, PARAMETERS can be a string
109 containing command line parameters, but otherwise should be nil.
110
111 SHOW-FLAG can be used to control whether the invoked application is hidden
112 or minimized.  If SHOW-FLAG is nil, the application is displayed normally,
113 otherwise it is an integer representing a ShowWindow flag:
114
115   0 - start hidden
116   1 - start normally
117   3 - start maximized
118   6 - start minimized
119 */
120        (operation, document, parameters, show_flag))
121 {
122   /* Encode filename and current directory.  */
123   Lisp_Object current_dir = Ffile_name_directory (document);
124   char* path = NULL;
125   char* doc = NULL;
126   Extbyte* f=0;
127   int ret;
128   struct gcpro gcpro1, gcpro2;
129
130   CHECK_STRING (document);
131
132   if (NILP (current_dir))
133     current_dir = current_buffer->directory;
134
135   GCPRO2 (current_dir, document);
136
137   /* Use mule and cygwin-safe APIs top get at file data. */
138   if (STRINGP (current_dir))
139     {
140       TO_EXTERNAL_FORMAT (LISP_STRING, current_dir,
141                           C_STRING_ALLOCA, f,
142                           Qfile_name);
143 #ifdef __CYGWIN32__
144       CYGWIN_WIN32_PATH (f, path);
145 #else
146       path = f;
147 #endif
148     }
149
150   if (STRINGP (document))
151     {
152       TO_EXTERNAL_FORMAT (LISP_STRING, document,
153                           C_STRING_ALLOCA, f,
154                           Qfile_name);
155 #ifdef __CYGWIN32__
156       CYGWIN_WIN32_PATH (f, doc);
157 #else
158       doc = f;
159 #endif
160     }
161
162   UNGCPRO;
163
164   ret = (int) ShellExecute (NULL,
165                             (STRINGP (operation) ?
166                              XSTRING_DATA (operation) : NULL),
167                             doc, 
168                             (STRINGP (parameters) ?
169                              XSTRING_DATA (parameters) : NULL),
170                             path,
171                             (INTP (show_flag) ?
172                              XINT (show_flag) : SW_SHOWDEFAULT));
173
174   if (ret > 32)
175     return Qt;
176   
177   if (ret == ERROR_FILE_NOT_FOUND)
178     signal_simple_error ("file not found", document);
179   else if (ret == ERROR_PATH_NOT_FOUND)
180     signal_simple_error ("path not found", current_dir);
181   else if (ret == ERROR_BAD_FORMAT)
182     signal_simple_error ("bad executable format", document);
183   else
184     error ("internal error");
185
186   return Qnil;
187 }
188
189 void
190 syms_of_gui_mswindows (void)
191 {
192   DEFSUBR (Fmswindows_shell_execute);
193 }