only clean out gs when last window goes
[nvi.git] / motif / m_main.c
blobe3bd91db881e94c284fbbc9e4ad8fec1e591748d
1 /*-
2 * Copyright (c) 1996
3 * Rob Zimmermann. All rights reserved.
4 * Copyright (c) 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "$Id: m_main.c,v 8.37 2000/07/05 11:33:18 skimo Exp $ (Berkeley) $Date: 2000/07/05 11:33:18 $";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
19 #include <X11/Intrinsic.h>
20 #include <X11/StringDefs.h>
21 #include <Xm/MainW.h>
23 #include <bitstring.h>
24 #include <signal.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
29 #include "../common/common.h"
30 #include "../ipc/ip.h"
31 #include "../motif_l/m_motif.h"
32 #include "../motif_l/vi_mextern.h"
33 #include "extern.h"
35 int vi_ifd = -1;
36 int vi_ofd = -1;
37 IPVIWIN *ipvi_motif;
39 #if XtSpecificationRelease == 4
40 #define ArgcType Cardinal *
41 #else
42 #define ArgcType int *
43 #endif
45 #if defined(ColorIcon)
46 #if XT_REVISION >= 6
47 #include <X11/xpm.h>
48 #else
49 #include "xpm.h"
50 #endif
52 #include "nvi.xpm" /* Icon pixmap. */
53 #else
54 #include "nvi.xbm" /* Icon bitmap. */
55 #endif
57 static pid_t pid;
58 static Pixel icon_fg,
59 icon_bg;
60 static Pixmap icon_pm;
61 static Widget top_level;
62 static XtAppContext ctx;
64 static void XutInstallColormap __P((String, Widget));
65 static void XutSetIcon __P((Widget, int, int, Pixmap));
66 static void onchld __P((int));
67 static void onexit __P((void));
69 #if ! defined(ColorIcon)
70 static XutResource resource[] = {
71 { "iconForeground", XutRKpixel, &icon_fg },
72 { "iconBackground", XutRKpixel, &icon_bg },
74 #endif
77 /* resources for the vi widgets unless the user overrides them */
78 String fallback_rsrcs[] = {
80 "*font: -*-*-*-r-*--14-*-*-*-m-*-*-*",
81 "*text*fontList: -*-*-*-r-*--14-*-*-*-m-*-*-*",
82 "*Menu*fontList: -*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*",
83 "*fontList: -*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*",
84 "*pointerShape: xterm",
85 "*busyShape: watch",
86 "*iconName: vi",
88 #if ! defined(ColorIcon)
89 /* coloring for the icons */
90 "*iconForeground: XtDefaultForeground",
91 "*iconBackground: XtDefaultBackground",
92 #endif
94 /* layout for the tag stack dialog */
95 "*Tags*visibleItemCount: 5",
97 /* for the text ruler */
98 "*rulerFont: -*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*",
99 "*rulerBorder: 5",
101 /* layout for the new, temporary preferences page */
102 "*toggleOptions.numColumns: 6", /* also used by Find */
103 "*Preferences*tabWidthPercentage: 0",
104 "*Preferences*tabs.shadowThickness: 2",
105 "*Preferences*tabs.font: -*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*",
107 /* --------------------------------------------------------------------- *
108 * anything below this point is only defined when we are not running CDE *
109 * --------------------------------------------------------------------- */
111 /* Do not define default colors when running under CDE
112 * (e.g. VUE on HPUX). The result is that you don't look
113 * like a normal desktop application
115 "?background: gray75",
116 "?screen.background: wheat",
117 "?highlightColor: red",
118 "?Preferences*options.background: gray90",
121 #if defined(__STDC__)
122 static String *get_fallback_rsrcs( String name )
123 #else
124 static String *get_fallback_rsrcs( name )
125 String name;
126 #endif
128 String *copy = (String *) malloc( (1+XtNumber(fallback_rsrcs))*sizeof(String) );
129 int i, running_cde;
130 Display *d;
132 /* connect to server and see if the CDE atoms are present */
133 d = XOpenDisplay(0);
134 running_cde = is_cde( d );
135 XCloseDisplay(d);
137 for ( i=0; i<XtNumber(fallback_rsrcs); i++ ) {
139 /* stop here if running CDE */
140 if ( fallback_rsrcs[i][0] == '?' ) {
141 if ( running_cde ) break;
142 fallback_rsrcs[i] = strdup(fallback_rsrcs[i]);
143 fallback_rsrcs[i][0] = '*';
146 copy[i] = malloc( strlen(name) + strlen(fallback_rsrcs[i]) + 1 );
147 strcpy( copy[i], name );
148 strcat( copy[i], fallback_rsrcs[i] );
151 copy[i] = NULL;
152 return copy;
156 /* create the shell widgetry */
158 #if defined(__STDC__)
159 static void create_top_level_shell( int *argc, char **argv )
160 #else
161 static void create_top_level_shell( argc, argv )
162 int *argc;
163 char **argv;
164 #endif
166 char *ptr;
167 Widget main_w, editor;
168 Display *display;
170 /* X gets quite upset if the program name is not simple */
171 if (( ptr = strrchr( argv[0], '/' )) != NULL ) argv[0] = ++ptr;
172 vi_progname = argv[0];
174 /* create a top-level shell for the window manager */
175 top_level = XtVaAppInitialize( &ctx,
176 vi_progname,
177 NULL, 0, /* options */
178 (ArgcType) argc,
179 argv, /* might get modified */
180 get_fallback_rsrcs( argv[0] ),
181 NULL
183 display = XtDisplay(top_level);
185 /* might need to go technicolor... */
186 XutInstallColormap( argv[0], top_level );
188 /* create our icon
189 * do this *before* realizing the shell widget in case the -iconic
190 * option was specified.
193 #if defined(ColorIcon)
194 int nvi_width, nvi_height;
195 XpmAttributes attr;
197 attr.valuemask = 0;
198 XpmCreatePixmapFromData( display,
199 DefaultRootWindow(display),
200 nvi_xpm,
201 &icon_pm,
202 NULL,
203 &attr
205 nvi_width = attr.width;
206 nvi_height = attr.height;
207 #else
208 /* check the resource database for interesting resources */
209 __XutConvertResources( top_level,
210 vi_progname,
211 resource,
212 XtNumber(resource)
215 icon_pm = XCreatePixmapFromBitmapData(
216 display,
217 DefaultRootWindow(display),
218 (char *) nvi_bits,
219 nvi_width,
220 nvi_height,
221 icon_fg,
222 icon_bg,
223 DefaultDepth( display, DefaultScreen(display) )
225 #endif
226 XutSetIcon( top_level, nvi_height, nvi_width, icon_pm );
229 /* in the shell, we will stack a menubar an editor */
230 main_w = XtVaCreateManagedWidget( "main",
231 xmMainWindowWidgetClass,
232 top_level,
233 NULL
236 /* create the menubar */
237 XtManageChild( (Widget) vi_create_menubar( main_w ) );
239 /* add the VI widget from the library */
240 editor = vi_create_editor( "editor", main_w, onexit );
242 /* put it up */
243 XtRealizeWidget( top_level );
245 /* We *may* want all keyboard events to go to the editing screen.
246 * If the editor is the only widget in the shell that accepts
247 * keyboard input, then the user will expect that he can type when
248 * the pointer is over the scrollbar (for example). This call
249 * causes that to happen.
251 XtSetKeyboardFocus( top_level, XtNameToWidget( editor, "*screen" ) );
256 main(argc, argv)
257 int argc;
258 char *argv[];
260 IPVI* ipvi;
262 * Initialize the X widgetry. We must do this before picking off
263 * arguments as well-behaved X programs have common argument lists
264 * (e.g. -rv for reverse video).
266 create_top_level_shell(&argc, argv);
268 /* We need to know if the child process goes away. */
269 (void)signal(SIGCHLD, onchld);
271 vi_create(&ipvi, 0);
272 (void)ipvi->run(ipvi, argc, argv);
273 ipvi->new_window(ipvi,&ipvi_motif);
274 ipvi_motif->set_ops(ipvi_motif, &ipsi_ops_motif);
275 /* Run vi: the parent returns, the child is the vi process. */
276 vi_ifd = ipvi_motif->ifd;
277 vi_ofd = ipvi_motif->ofd;
278 pid = ipvi->pid;
280 /* Tell X that we are interested in input on the pipe. */
281 XtAppAddInput(ctx, vi_ifd,
282 (XtPointer)XtInputReadMask, vi_input_func, NULL);
284 /* Main loop. */
285 XtAppMainLoop(ctx);
287 /* NOTREACHED */
288 abort();
291 static void
292 XutSetIcon(wid, height, width, p)
293 Widget wid;
294 int height, width;
295 Pixmap p;
297 Display *display = XtDisplay(wid);
298 Window win;
300 /* best bet is to set the icon window */
301 XtVaGetValues( wid, XtNiconWindow, &win, 0 );
303 if ( win == None ) {
304 win = XCreateSimpleWindow( display,
305 RootWindow( display,
306 DefaultScreen( display ) ),
307 0, 0,
308 width, height,
310 CopyFromParent,
311 CopyFromParent
315 if ( win != None ) {
316 XtVaSetValues( wid, XtNiconWindow, win, 0 );
317 XSetWindowBackgroundPixmap( display, win, p );
320 else {
321 /* do it the old fashioned way */
322 XtVaSetValues( wid, XtNiconPixmap, p, 0 );
326 /* Support for multiple colormaps
328 * XutInstallColormap( String name, Widget wid )
329 * The first time called, this routine checks to see if the
330 * resource "name*installColormap" is "True". If so, the
331 * widget is assigned a newly allocated colormap.
333 * Subsequent calls ignore the "name" parameter and use the
334 * same colormap.
336 * Future versions of this routine may handle multiple colormaps
337 * by name.
339 static enum { cmap_look, cmap_use, cmap_ignore } cmap_state = cmap_look;
341 static Boolean use_colormap = False;
343 static XutResource colormap_resources[] = {
344 { "installColormap", XutRKboolean, &use_colormap }
347 static void
348 XutInstallColormap(name, wid)
349 String name;
350 Widget wid;
352 static Colormap cmap = 0;
353 static Display *cmap_display = 0;
354 Display *display = XtDisplay(wid);
356 /* what is the current finite state? */
357 if ( cmap_state == cmap_look ) {
359 /* what does the resource say? */
360 __XutConvertResources( wid,
361 name,
362 colormap_resources,
363 XtNumber(colormap_resources)
366 /* was the result "True"? */
367 if ( ! use_colormap ) {
368 cmap_state = cmap_ignore;
369 return;
372 /* yes it was */
373 cmap_state = cmap_use;
374 cmap_display = display;
375 cmap = XCopyColormapAndFree( display,
376 DefaultColormap( display,
377 DefaultScreen( display )
382 /* use the private colormap? */
383 if ( cmap_state == cmap_use ) {
384 XtVaSetValues( wid, XtNcolormap, cmap, 0 );
389 * onchld --
390 * Handle SIGCHLD.
392 static void
393 onchld(signo)
394 int signo;
396 /* If the vi process goes away, we exit as well. */
397 if (kill(pid, 0))
398 vi_fatal_message(top_level, "The vi process died. Exiting.");
402 * onexit --
403 * Function called when the editor "quits".
405 static void
406 onexit()
408 exit (0);