Home | History | Annotate | Line # | Download | only in motif
      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 */
     84 String	fallback_rsrcs[] = {
     85 
     86     "*font:			-*-*-*-r-*--14-*-*-*-m-*-*-*",
     87     "*text*fontList:		-*-*-*-r-*--14-*-*-*-m-*-*-*",
     88     "*Menu*fontList:		-*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*",
     89     "*fontList:			-*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*",
     90     "*pointerShape:		xterm",
     91     "*busyShape:		watch",
     92     "*iconName:			vi",
     93 
     94 #if ! defined(ColorIcon)
     95     /* coloring for the icons */
     96     "*iconForeground:	XtDefaultForeground",
     97     "*iconBackground:	XtDefaultBackground",
     98 #endif
     99 
    100     /* layout for the tag stack dialog */
    101     "*Tags*visibleItemCount:			5",
    102 
    103     /* for the text ruler */
    104     "*rulerFont:		-*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*",
    105     "*rulerBorder:		5",
    106 
    107     /* layout for the new, temporary preferences page */
    108     "*toggleOptions.numColumns:			6",	/* also used by Find */
    109     "*Preferences*tabWidthPercentage:		0",
    110     "*Preferences*tabs.shadowThickness:		2",
    111     "*Preferences*tabs.font:	-*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*",
    112 
    113     /* --------------------------------------------------------------------- *
    114      * anything below this point is only defined when we are not running CDE *
    115      * --------------------------------------------------------------------- */
    116 
    117     /* Do not define default colors when running under CDE
    118      * (e.g. VUE on HPUX). The result is that you don't look
    119      * like a normal desktop application
    120      */
    121     "?background:			gray75",
    122     "?screen.background:		wheat",
    123     "?highlightColor:			red",
    124     "?Preferences*options.background:	gray90",
    125 };
    126 
    127 #if defined(__STDC__)
    128 static	String	*get_fallback_rsrcs( String name )
    129 #else
    130 static	String	*get_fallback_rsrcs( name )
    131 	String	name;
    132 #endif
    133 {
    134     String	*copy = (String *) malloc( (1+XtNumber(fallback_rsrcs))*sizeof(String) );
    135     int		i, running_cde;
    136     Display	*d;
    137 
    138     /* connect to server and see if the CDE atoms are present */
    139     d = XOpenDisplay(0);
    140     running_cde = is_cde( d );
    141     XCloseDisplay(d);
    142 
    143     for ( i=0; i<XtNumber(fallback_rsrcs); i++ ) {
    144 
    145 	/* stop here if running CDE */
    146 	if ( fallback_rsrcs[i][0] == '?' ) {
    147 	    if ( running_cde ) break;
    148 	    fallback_rsrcs[i] = strdup(fallback_rsrcs[i]);
    149 	    fallback_rsrcs[i][0] = '*';
    150 	}
    151 
    152 	copy[i] = malloc( strlen(name) + strlen(fallback_rsrcs[i]) + 1 );
    153 	strcpy( copy[i], name );
    154 	strcat( copy[i], fallback_rsrcs[i] );
    155     }
    156 
    157     copy[i] = NULL;
    158     return copy;
    159 }
    160 
    161 
    162 /* create the shell widgetry */
    164 
    165 #if defined(__STDC__)
    166 static	void	create_top_level_shell( int *argc, char **argv )
    167 #else
    168 static	void	create_top_level_shell( argc, argv )
    169 	int	*argc;
    170 	char	**argv;
    171 #endif
    172 {
    173     char	*ptr;
    174     Widget	main_w, editor;
    175     Display	*display;
    176 
    177     /* X gets quite upset if the program name is not simple */
    178     if (( ptr = strrchr( argv[0], '/' )) != NULL ) argv[0] = ++ptr;
    179     vi_progname = argv[0];
    180 
    181     /* create a top-level shell for the window manager */
    182     top_level = XtVaAppInitialize( &ctx,
    183 				   vi_progname,
    184 				   NULL, 0,	/* options */
    185 				   (ArgcType) argc,
    186 				   argv,	/* might get modified */
    187 				   get_fallback_rsrcs( argv[0] ),
    188 				   NULL
    189 				   );
    190     display = XtDisplay(top_level);
    191 
    192     /* might need to go technicolor... */
    193     XutInstallColormap( argv[0], top_level );
    194 
    195     /* create our icon
    196      * do this *before* realizing the shell widget in case the -iconic
    197      * option was specified.
    198      */
    199     {
    200 #if defined(ColorIcon)
    201     int			nvi_width, nvi_height;
    202     XpmAttributes	attr;
    203 
    204     attr.valuemask = 0;
    205     XpmCreatePixmapFromData( display,
    206 			     DefaultRootWindow(display),
    207 			     nvi_xpm,
    208 			     &icon_pm,
    209 			     NULL,
    210 			     &attr
    211 			     );
    212     nvi_width = attr.width;
    213     nvi_height = attr.height;
    214 #else
    215     /* check the resource database for interesting resources */
    216     __XutConvertResources( top_level,
    217 			 vi_progname,
    218 			 resource,
    219 			 XtNumber(resource)
    220 			 );
    221 
    222     icon_pm = XCreatePixmapFromBitmapData(
    223 			display,
    224 		        DefaultRootWindow(display),
    225 			(char *) nvi_bits,
    226 			nvi_width,
    227 			nvi_height,
    228 			icon_fg,
    229 			icon_bg,
    230 			DefaultDepth( display, DefaultScreen(display) )
    231 			);
    232 #endif
    233     XutSetIcon( top_level, nvi_height, nvi_width, icon_pm );
    234     }
    235 
    236     /* in the shell, we will stack a menubar an editor */
    237     main_w = XtVaCreateManagedWidget( "main",
    238 				      xmMainWindowWidgetClass,
    239 				      top_level,
    240 				      NULL
    241 				      );
    242 
    243     /* create the menubar */
    244     XtManageChild( (Widget) vi_create_menubar( main_w ) );
    245 
    246     /* add the VI widget from the library */
    247     editor = vi_create_editor( "editor", main_w, onexit );
    248 
    249     /* put it up */
    250     XtRealizeWidget( top_level );
    251 
    252     /* We *may* want all keyboard events to go to the editing screen.
    253      * If the editor is the only widget in the shell that accepts
    254      * keyboard input, then the user will expect that he can type when
    255      * the pointer is over the scrollbar (for example).  This call
    256      * causes that to happen.
    257      */
    258     XtSetKeyboardFocus( top_level, XtNameToWidget( editor, "*screen" ) );
    259 }
    260 
    261 
    262 int
    264 main(int argc, char **argv)
    265 {
    266 	IPVI* ipvi;
    267 	/*
    268 	 * Initialize the X widgetry.  We must do this before picking off
    269 	 * arguments as well-behaved X programs have common argument lists
    270 	 * (e.g. -rv for reverse video).
    271 	 */
    272 	create_top_level_shell(&argc, argv);
    273 
    274 	/* We need to know if the child process goes away. */
    275 	(void)signal(SIGCHLD, onchld);
    276 
    277 	vi_create(&ipvi, 0);
    278 	(void)ipvi->run(ipvi, argc, argv);
    279 	ipvi->new_window(ipvi,&ipvi_motif,-1);
    280 	ipvi_motif->set_ops(ipvi_motif, &ipsi_ops_motif);
    281 	/* Run vi: the parent returns, the child is the vi process. */
    282 	vi_ifd = ipvi_motif->ifd;
    283 	vi_ofd = ipvi_motif->ofd;
    284 	pid = ipvi->pid;
    285 
    286 	/* Tell X that we are interested in input on the pipe. */
    287 	XtAppAddInput(ctx, vi_ifd,
    288 	    (XtPointer)XtInputReadMask, vi_input_func, NULL);
    289 
    290 	/* Main loop. */
    291 	XtAppMainLoop(ctx);
    292 
    293 	/* NOTREACHED */
    294 	abort();
    295 }
    296 
    297 static void
    298 XutSetIcon(Widget wid, int height, int width, Pixmap p)
    299 {
    300     Display	*display = XtDisplay(wid);
    301     Window	win;
    302 
    303     /* best bet is to set the icon window */
    304     XtVaGetValues( wid, XtNiconWindow, &win, 0 );
    305 
    306     if ( win == None ) {
    307 	win = XCreateSimpleWindow( display,
    308 				   RootWindow( display,
    309 				   DefaultScreen( display ) ),
    310 				   0, 0,
    311 				   width, height,
    312 				   0,
    313 				   CopyFromParent,
    314 				   CopyFromParent
    315 				   );
    316     }
    317 
    318     if ( win != None ) {
    319 	XtVaSetValues( wid, XtNiconWindow, win, 0 );
    320 	XSetWindowBackgroundPixmap( display, win, p );
    321     }
    322 
    323     else {
    324 	/* do it the old fashioned way */
    325 	XtVaSetValues( wid, XtNiconPixmap, p, 0 );
    326     }
    327 }
    328 
    329 /* Support for multiple colormaps
    330  *
    331  * XutInstallColormap( String name, Widget wid )
    332  *	The first time called, this routine checks to see if the
    333  *	resource "name*installColormap" is "True".  If so, the
    334  *	widget is assigned a newly allocated colormap.
    335  *
    336  *	Subsequent calls ignore the "name" parameter and use the
    337  *	same colormap.
    338  *
    339  *	Future versions of this routine may handle multiple colormaps
    340  *	by name.
    341  */
    342 static	enum { cmap_look, cmap_use, cmap_ignore } cmap_state = cmap_look;
    343 
    344 static	Boolean	use_colormap = False;
    345 
    346 static XutResource	colormap_resources[] = {
    347     { "installColormap",	XutRKboolean,	&use_colormap	}
    348 };
    349 
    350 static void
    351 XutInstallColormap(String name, Widget wid)
    352 {
    353     static Colormap cmap = 0;
    354     static Display  *cmap_display = 0;
    355     Display	*display = XtDisplay(wid);
    356 
    357     /* what is the current finite state? */
    358     if ( cmap_state == cmap_look ) {
    359 
    360 	/* what does the resource say? */
    361 	__XutConvertResources( wid,
    362 			     name,
    363 			     colormap_resources,
    364 			     XtNumber(colormap_resources)
    365 			     );
    366 
    367 	/* was the result "True"? */
    368 	if ( ! use_colormap ) {
    369 	    cmap_state = cmap_ignore;
    370 	    return;
    371 	}
    372 
    373 	/* yes it was */
    374 	cmap_state = cmap_use;
    375 	cmap_display = display;
    376 	cmap = XCopyColormapAndFree( display,
    377 				     DefaultColormap( display,
    378 						      DefaultScreen( display )
    379 						      )
    380 				     );
    381     }
    382 
    383     /* use the private colormap? */
    384     if ( cmap_state == cmap_use ) {
    385 	XtVaSetValues( wid, XtNcolormap, cmap, 0 );
    386     }
    387 }
    388 
    389 /*
    390  * onchld --
    391  *	Handle SIGCHLD.
    392  */
    393 static void
    394 onchld(int signo)
    395 {
    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.");
    399 }
    400 
    401 /*
    402  * onexit --
    403  *	Function called when the editor "quits".
    404  */
    405 static void
    406 onexit(void)
    407 {
    408 	exit (0);
    409 }
    410