import -ko -b 1.1.3 XEmacs XEmacs-21_2 r21-2-35
[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 "console-msw.h"
26 #include "redisplay.h"
27 #include "gui.h"
28 #include "glyphs.h"
29 #include "frame.h"
30 #include "elhash.h"
31 #include "events.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. */
88   enqueue_magic_eval_event (update_widget_instances, frame);
89   return Qt;
90 }
91
92 DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /*
93 Get Windows to perform OPERATION on DOCUMENT.
94 This is a wrapper around the ShellExecute system function, which
95 invokes the application registered to handle OPERATION for DOCUMENT.
96 OPERATION is typically \"open\", \"print\" or \"explore\" (but can be
97 nil for the default action), and DOCUMENT is typically the name of a
98 document file or URL, but can also be a program executable to run or
99 a directory to open in the Windows Explorer.
100
101 If DOCUMENT is a program executable, PARAMETERS can be a string
102 containing command line parameters, but otherwise should be nil.
103
104 SHOW-FLAG can be used to control whether the invoked application is hidden
105 or minimized.  If SHOW-FLAG is nil, the application is displayed normally,
106 otherwise it is an integer representing a ShowWindow flag:
107
108   0 - start hidden
109   1 - start normally
110   3 - start maximized
111   6 - start minimized
112 */
113        (operation, document, parameters, show_flag))
114 {
115   /* Encode filename and current directory.  */
116   Lisp_Object current_dir = Ffile_name_directory (document);
117   char* path = NULL;
118   char* doc = NULL;
119   Extbyte* f=0;
120   int ret;
121   struct gcpro gcpro1, gcpro2;
122
123   CHECK_STRING (document);
124
125   if (NILP (current_dir))
126     current_dir = current_buffer->directory;
127
128   GCPRO2 (current_dir, document);
129
130   /* Use mule and cygwin-safe APIs top get at file data. */
131   if (STRINGP (current_dir))
132     {
133       TO_EXTERNAL_FORMAT (LISP_STRING, current_dir,
134                           C_STRING_ALLOCA, f,
135                           Qfile_name);
136 #ifdef CYGWIN
137       CYGWIN_WIN32_PATH (f, path);
138 #else
139       path = f;
140 #endif
141     }
142
143   if (STRINGP (document))
144     {
145       TO_EXTERNAL_FORMAT (LISP_STRING, document,
146                           C_STRING_ALLOCA, f,
147                           Qfile_name);
148 #ifdef CYGWIN
149       CYGWIN_WIN32_PATH (f, doc);
150 #else
151       doc = f;
152 #endif
153     }
154
155   UNGCPRO;
156
157   ret = (int) ShellExecute (NULL,
158                             (STRINGP (operation) ?
159                              XSTRING_DATA (operation) : NULL),
160                             doc, 
161                             (STRINGP (parameters) ?
162                              XSTRING_DATA (parameters) : NULL),
163                             path,
164                             (INTP (show_flag) ?
165                              XINT (show_flag) : SW_SHOWDEFAULT));
166
167   if (ret > 32)
168     return Qt;
169   
170   if (ret == ERROR_FILE_NOT_FOUND)
171     signal_simple_error ("file not found", document);
172   else if (ret == ERROR_PATH_NOT_FOUND)
173     signal_simple_error ("path not found", current_dir);
174   else if (ret == ERROR_BAD_FORMAT)
175     signal_simple_error ("bad executable format", document);
176   else
177     error ("internal error");
178
179   return Qnil;
180 }
181
182 void
183 syms_of_gui_mswindows (void)
184 {
185   DEFSUBR (Fmswindows_shell_execute);
186 }