1 /*
2 * mash-console.cc --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1997-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 static const char *rcsid = "@(#) $Header: /usr/mash/src/repository/mash/mash-1/compat/mash-console.cc,v 1.8 2003/09/09 15:41:57 djones Exp $";
36 #endif
37
38 #include <windows.h>
39 #include "tclcl.h"
40 #include "console.h"
41 #include "misc/all-types.h"
42 #include "tclcl-mappings.h"
43
44 #define IDM_SHOWHIDECONSOLE 9999
45
46
47 class OTclMashConsole : public TclObject {
48 public:
49 OTclMashConsole() : TclObject() { };
50 ~OTclMashConsole();
51
52 int show(int argc, const char *const *argv);
53 int hide(int argc, const char *const *argv);
54 int toggle(int argc, const char *const *argv);
55 int set_title(int argc, const char *const *argv);
56 int is_visible(int argc, const char *const *argv);
57 int set_buffer_size(int argc, const char *const *argv);
58
59 int alloc(int argc, const char *const *argv);
60 int free(int argc, const char *const *argv);
61
62 int destroy(int argc, const char *const *argv);
63
64 int init(int argc, const char * const *argv) {
65 if (instance_) {
66 Tcl::instance().result("there is already one instance"
67 " of this class; multiple "
68 "instances are forbidden");
69 return TCL_ERROR;
70 }
71 instance_ = this;
72 return TCL_OK;
73 }
74
75 int create_sysmenu(int argc, const char *const *argv);
76 static MashConsole mainConsole_;
77 private:
78 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg,
79 WPARAM wParam, LPARAM lParam);
80
81 HMENU sysMenu_;
82 HWND attachedHwnd_;
83
84 static WNDPROC origWindowProc_;
85 static OTclMashConsole *instance_;
86 };
87
88
89 WNDPROC OTclMashConsole::origWindowProc_=NULL;
90 OTclMashConsole *OTclMashConsole::instance_=NULL;
91 MashConsole OTclMashConsole::mainConsole_;
92
93
94 DEFINE_OTCL_CLASS(OTclMashConsole, "MashConsole")
95 {
96 INSTPROC_PUBLIC(show);
97 INSTPROC_PUBLIC(hide);
98 INSTPROC_PUBLIC(toggle);
99 INSTPROC_PUBLIC(set_title);
100 INSTPROC_PUBLIC(set_buffer_size);
101 INSTPROC_PUBLIC(alloc);
102 INSTPROC_PUBLIC(free);
103
104 INSTPROC_PRIVATE(create_sysmenu);
105 INSTPROC_PRIVATE(destroy);
106 }
107
108
109 OTclMashConsole::~OTclMashConsole()
110 {
111 if (sysMenu_) {
112 if (IsWindow(attachedHwnd_)) {
113 SetWindowLong(attachedHwnd_, GWL_WNDPROC,
114 (LONG)origWindowProc_);
115 }
116 sysMenu_ = NULL;
117 attachedHwnd_ = NULL;
118 origWindowProc_ = NULL;
119 }
120
121 if (instance_==this) instance_=NULL;
122 }
123
124
125 int
126 OTclMashConsole::show(int argc, const char *const *argv)
127 {
128 BEGIN_PARSE_ARGS(argc, argv);
129 END_PARSE_ARGS;
130 mainConsole_.Show(TRUE);
131 return TCL_OK;
132 }
133
134
135 int
136 OTclMashConsole::hide(int argc, const char *const *argv)
137 {
138 BEGIN_PARSE_ARGS(argc, argv);
139 END_PARSE_ARGS;
140 mainConsole_.Show(FALSE);
141 return TCL_OK;
142 }
143
144
145 int
146 OTclMashConsole::toggle(int argc, const char *const *argv)
147 {
148 BEGIN_PARSE_ARGS(argc, argv);
149 END_PARSE_ARGS;
150 Tcl::instance().resultf("%d", mainConsole_.Toggle());
151 return TCL_OK;
152 }
153
154
155 int
156 OTclMashConsole::set_title(int argc, const char *const *argv)
157 {
158 const char *title;
159 BEGIN_PARSE_ARGS(argc, argv);
160 ARG(title);
161 END_PARSE_ARGS;
162 mainConsole_.SetTitle(title);
163 return TCL_OK;
164 }
165
166
167 int
168 OTclMashConsole::is_visible(int argc, const char *const *argv)
169 {
170 BEGIN_PARSE_ARGS(argc, argv);
171 END_PARSE_ARGS;
172 Tcl::instance().resultf("%d", mainConsole_.IsVisible());
173 return TCL_OK;
174 }
175
176
177 int
178 OTclMashConsole::set_buffer_size(int argc, const char *const *argv)
179 {
180 u_int32_t size;
181 BEGIN_PARSE_ARGS(argc, argv);
182 ARG(size);
183 END_PARSE_ARGS;
184 int retval = mainConsole_.SetBufferSize(size);
185 Tcl::instance().resultf("%d", retval);
186 return TCL_OK;
187 }
188
189
190 int
191 OTclMashConsole::alloc(int argc, const char *const *argv)
192 {
193 u_int32_t x, y, width, height;
194 BEGIN_PARSE_ARGS(argc, argv);
195 ARG_DEFAULT(x, CW_USEDEFAULT);
196 ARG_DEFAULT(y, CW_USEDEFAULT);
197 ARG_DEFAULT(width, CW_USEDEFAULT);
198 ARG_DEFAULT(height, CW_USEDEFAULT);
199 END_PARSE_ARGS;
200 mainConsole_.Create(x, y, width, height);
201 return TCL_OK;
202 }
203
204
205 int
206 OTclMashConsole::free(int argc, const char *const *argv)
207 {
208 BEGIN_PARSE_ARGS(argc, argv);
209 END_PARSE_ARGS;
210 mainConsole_.Destroy();
211 return TCL_OK;
212 }
213
214
215 int
216 OTclMashConsole::create_sysmenu(int argc, const char *const *argv)
217 {
218 u_int32_t hwndId;
219 BEGIN_PARSE_ARGS(argc, argv);
220 ARG(hwndId);
221 END_PARSE_ARGS;
222 BOOL success = FALSE;
223
224 attachedHwnd_ = (HWND) hwndId;
225 if (attachedHwnd_) {
226 HMENU sysMenu = GetSystemMenu(attachedHwnd_, FALSE);
227 while (!sysMenu && attachedHwnd_) {
228 attachedHwnd_ = GetParent(attachedHwnd_);
229 if (attachedHwnd_ && (HINSTANCE)
230 GetWindowLong(attachedHwnd_, GWL_HINSTANCE)==
231 mainConsole_.hInstance_)
232 sysMenu = GetSystemMenu(attachedHwnd_, FALSE);
233 }
234
235 if (sysMenu) {
236 AppendMenu(sysMenu, MF_SEPARATOR, 0, NULL);
237 AppendMenu(sysMenu, MF_STRING, IDM_SHOWHIDECONSOLE,
238 "Show Mash Co&nsole");
239
240 sysMenu_ = sysMenu;
241 origWindowProc_ = (WNDPROC)
242 SetWindowLong(attachedHwnd_, GWL_WNDPROC,
243 (LONG)WindowProc);
244 success = TRUE;
245 }
246 }
247
248 Tcl::instance().resultf("%d", success);
249 return TCL_OK;
250 }
251
252
253 int
254 OTclMashConsole::destroy(int argc, const char *const *argv)
255 {
256 BEGIN_PARSE_ARGS(argc, argv);
257 END_PARSE_ARGS;
258
259 Tcl::instance().result("destroying the MashConsole object is not "
260 "permitted");
261 return TCL_ERROR;
262 }
263
264
265 LRESULT CALLBACK OTclMashConsole::WindowProc(HWND hWnd, UINT msg,
266 WPARAM wParam, LPARAM lParam)
267 {
268 BOOL isSysMenu;
269 HMENU hmenu;
270 MENUITEMINFO info;
271
272 switch (msg) {
273 case WM_INITMENUPOPUP:
274 isSysMenu = (BOOL) HIWORD(lParam); // window menu flag
275 hmenu = (HMENU) wParam; // handle of submenu
276
277 if (isSysMenu && instance_ && hmenu==instance_->sysMenu_) {
278 info.cbSize = sizeof(info);
279 info.fMask = MIIM_TYPE | MIIM_STATE;
280 info.fType = MFT_STRING;
281 info.fState = (mainConsole_.Exists() ?
282 MFS_ENABLED : MFS_GRAYED);
283 info.wID = IDM_SHOWHIDECONSOLE;
284 info.hSubMenu = NULL;
285 info.hbmpChecked = NULL;
286 info.hbmpUnchecked = NULL;
287 info.dwItemData = NULL;
288
289 if (mainConsole_.IsVisible()) {
290 info.dwTypeData = "Hide Mash Co&nsole";
291 } else {
292 info.dwTypeData = "Show Mash Co&nsole";
293 }
294 info.cch = strlen(info.dwTypeData);
295
296 SetMenuItemInfo(instance_->sysMenu_,
297 IDM_SHOWHIDECONSOLE,
298 FALSE, &info);
299 }
300
301 // always fall through to the orig proc
302 break;
303
304 case WM_SYSCOMMAND:
305 switch (LOWORD(wParam)) {
306 case IDM_SHOWHIDECONSOLE:
307 mainConsole_.Toggle();
308 return 0;
309 }
310 break;
311 }
312
313 if (origWindowProc_)
314 return origWindowProc_(hWnd, msg, wParam, lParam);
315 return 0;
316 }
317
318
319
320
321
322 extern "C"
323 void MashConsoleInit(HINSTANCE hInstance)
324 {
325 OTclMashConsole::mainConsole_.Init(hInstance);
326 OTclMashConsole::mainConsole_.Create();
327 }
328
329
330 extern "C"
331 void MashConsoleShow(BOOL show)
332 {
333 OTclMashConsole::mainConsole_.Show(show);
334 }
335
336 extern "C"
337 void MashConsoleDoModal()
338 {
339 OTclMashConsole::mainConsole_.DoModal();
340 }
341
342 extern "C"
343 BOOL MashConsoleAttach()
344 {
345 OTclMashConsole *console =
346 (OTclMashConsole*)TclObject::New("MashConsole");
347
348 if (!console) return FALSE;
349 Tcl_SetVar2(Tcl::instance().interp(), "mash", "console",
350 (char*) console->name(), TCL_GLOBAL_ONLY);
351 return TRUE;
352 }
353
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.