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