405 lines
9.7 KiB
C
405 lines
9.7 KiB
C
|
/* $NetBSD: m_main.c,v 1.1.1.2 2008/05/18 14:31:26 aymeric Exp $ */
|
|||
|
|
|||
|
/*-
|
|||
|
* Copyright (c) 1996
|
|||
|
* Rob Zimmermann. All rights reserved.
|
|||
|
* Copyright (c) 1996
|
|||
|
* Keith Bostic. All rights reserved.
|
|||
|
*
|
|||
|
* See the LICENSE file for redistribution information.
|
|||
|
*/
|
|||
|
|
|||
|
#include "config.h"
|
|||
|
|
|||
|
#ifndef lint
|
|||
|
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";
|
|||
|
#endif /* not lint */
|
|||
|
|
|||
|
#include <sys/types.h>
|
|||
|
#include <sys/queue.h>
|
|||
|
|
|||
|
#include <X11/Intrinsic.h>
|
|||
|
#include <X11/StringDefs.h>
|
|||
|
#include <Xm/MainW.h>
|
|||
|
|
|||
|
#include <bitstring.h>
|
|||
|
#include <signal.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
|
|||
|
#undef LOCK_SUCCESS
|
|||
|
#include "../common/common.h"
|
|||
|
#include "../ipc/ip.h"
|
|||
|
#include "../motif_l/m_motif.h"
|
|||
|
#include "../motif_l/vi_mextern.h"
|
|||
|
#include "extern.h"
|
|||
|
|
|||
|
int vi_ifd = -1;
|
|||
|
int vi_ofd = -1;
|
|||
|
IPVIWIN *ipvi_motif;
|
|||
|
|
|||
|
#if XtSpecificationRelease == 4
|
|||
|
#define ArgcType Cardinal *
|
|||
|
#else
|
|||
|
#define ArgcType int *
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(ColorIcon)
|
|||
|
#if XT_REVISION >= 6
|
|||
|
#include <X11/xpm.h>
|
|||
|
#else
|
|||
|
#include "xpm.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#include "nvi.xpm" /* Icon pixmap. */
|
|||
|
#else
|
|||
|
#include "nvi.xbm" /* Icon bitmap. */
|
|||
|
#endif
|
|||
|
|
|||
|
static pid_t pid;
|
|||
|
static Pixel icon_fg,
|
|||
|
icon_bg;
|
|||
|
static Pixmap icon_pm;
|
|||
|
static Widget top_level;
|
|||
|
static XtAppContext ctx;
|
|||
|
|
|||
|
static void XutInstallColormap __P((String, Widget));
|
|||
|
static void XutSetIcon __P((Widget, int, int, Pixmap));
|
|||
|
static void onchld __P((int));
|
|||
|
static void onexit __P((void));
|
|||
|
|
|||
|
#if ! defined(ColorIcon)
|
|||
|
static XutResource resource[] = {
|
|||
|
{ "iconForeground", XutRKpixel, &icon_fg },
|
|||
|
{ "iconBackground", XutRKpixel, &icon_bg },
|
|||
|
};
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
/* resources for the vi widgets unless the user overrides them */
|
|||
|
String fallback_rsrcs[] = {
|
|||
|
|
|||
|
"*font: -*-*-*-r-*--14-*-*-*-m-*-*-*",
|
|||
|
"*text*fontList: -*-*-*-r-*--14-*-*-*-m-*-*-*",
|
|||
|
"*Menu*fontList: -*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*",
|
|||
|
"*fontList: -*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*",
|
|||
|
"*pointerShape: xterm",
|
|||
|
"*busyShape: watch",
|
|||
|
"*iconName: vi",
|
|||
|
|
|||
|
#if ! defined(ColorIcon)
|
|||
|
/* coloring for the icons */
|
|||
|
"*iconForeground: XtDefaultForeground",
|
|||
|
"*iconBackground: XtDefaultBackground",
|
|||
|
#endif
|
|||
|
|
|||
|
/* layout for the tag stack dialog */
|
|||
|
"*Tags*visibleItemCount: 5",
|
|||
|
|
|||
|
/* for the text ruler */
|
|||
|
"*rulerFont: -*-helvetica-medium-r-normal--14-*-*-*-*-*-*-*",
|
|||
|
"*rulerBorder: 5",
|
|||
|
|
|||
|
/* layout for the new, temporary preferences page */
|
|||
|
"*toggleOptions.numColumns: 6", /* also used by Find */
|
|||
|
"*Preferences*tabWidthPercentage: 0",
|
|||
|
"*Preferences*tabs.shadowThickness: 2",
|
|||
|
"*Preferences*tabs.font: -*-helvetica-bold-r-normal--14-*-*-*-*-*-*-*",
|
|||
|
|
|||
|
/* --------------------------------------------------------------------- *
|
|||
|
* anything below this point is only defined when we are not running CDE *
|
|||
|
* --------------------------------------------------------------------- */
|
|||
|
|
|||
|
/* Do not define default colors when running under CDE
|
|||
|
* (e.g. VUE on HPUX). The result is that you don't look
|
|||
|
* like a normal desktop application
|
|||
|
*/
|
|||
|
"?background: gray75",
|
|||
|
"?screen.background: wheat",
|
|||
|
"?highlightColor: red",
|
|||
|
"?Preferences*options.background: gray90",
|
|||
|
};
|
|||
|
|
|||
|
#if defined(__STDC__)
|
|||
|
static String *get_fallback_rsrcs( String name )
|
|||
|
#else
|
|||
|
static String *get_fallback_rsrcs( name )
|
|||
|
String name;
|
|||
|
#endif
|
|||
|
{
|
|||
|
String *copy = (String *) malloc( (1+XtNumber(fallback_rsrcs))*sizeof(String) );
|
|||
|
int i, running_cde;
|
|||
|
Display *d;
|
|||
|
|
|||
|
/* connect to server and see if the CDE atoms are present */
|
|||
|
d = XOpenDisplay(0);
|
|||
|
running_cde = is_cde( d );
|
|||
|
XCloseDisplay(d);
|
|||
|
|
|||
|
for ( i=0; i<XtNumber(fallback_rsrcs); i++ ) {
|
|||
|
|
|||
|
/* stop here if running CDE */
|
|||
|
if ( fallback_rsrcs[i][0] == '?' ) {
|
|||
|
if ( running_cde ) break;
|
|||
|
fallback_rsrcs[i] = strdup(fallback_rsrcs[i]);
|
|||
|
fallback_rsrcs[i][0] = '*';
|
|||
|
}
|
|||
|
|
|||
|
copy[i] = malloc( strlen(name) + strlen(fallback_rsrcs[i]) + 1 );
|
|||
|
strcpy( copy[i], name );
|
|||
|
strcat( copy[i], fallback_rsrcs[i] );
|
|||
|
}
|
|||
|
|
|||
|
copy[i] = NULL;
|
|||
|
return copy;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* create the shell widgetry */
|
|||
|
|
|||
|
#if defined(__STDC__)
|
|||
|
static void create_top_level_shell( int *argc, char **argv )
|
|||
|
#else
|
|||
|
static void create_top_level_shell( argc, argv )
|
|||
|
int *argc;
|
|||
|
char **argv;
|
|||
|
#endif
|
|||
|
{
|
|||
|
char *ptr;
|
|||
|
Widget main_w, editor;
|
|||
|
Display *display;
|
|||
|
|
|||
|
/* X gets quite upset if the program name is not simple */
|
|||
|
if (( ptr = strrchr( argv[0], '/' )) != NULL ) argv[0] = ++ptr;
|
|||
|
vi_progname = argv[0];
|
|||
|
|
|||
|
/* create a top-level shell for the window manager */
|
|||
|
top_level = XtVaAppInitialize( &ctx,
|
|||
|
vi_progname,
|
|||
|
NULL, 0, /* options */
|
|||
|
(ArgcType) argc,
|
|||
|
argv, /* might get modified */
|
|||
|
get_fallback_rsrcs( argv[0] ),
|
|||
|
NULL
|
|||
|
);
|
|||
|
display = XtDisplay(top_level);
|
|||
|
|
|||
|
/* might need to go technicolor... */
|
|||
|
XutInstallColormap( argv[0], top_level );
|
|||
|
|
|||
|
/* create our icon
|
|||
|
* do this *before* realizing the shell widget in case the -iconic
|
|||
|
* option was specified.
|
|||
|
*/
|
|||
|
{
|
|||
|
#if defined(ColorIcon)
|
|||
|
int nvi_width, nvi_height;
|
|||
|
XpmAttributes attr;
|
|||
|
|
|||
|
attr.valuemask = 0;
|
|||
|
XpmCreatePixmapFromData( display,
|
|||
|
DefaultRootWindow(display),
|
|||
|
nvi_xpm,
|
|||
|
&icon_pm,
|
|||
|
NULL,
|
|||
|
&attr
|
|||
|
);
|
|||
|
nvi_width = attr.width;
|
|||
|
nvi_height = attr.height;
|
|||
|
#else
|
|||
|
/* check the resource database for interesting resources */
|
|||
|
__XutConvertResources( top_level,
|
|||
|
vi_progname,
|
|||
|
resource,
|
|||
|
XtNumber(resource)
|
|||
|
);
|
|||
|
|
|||
|
icon_pm = XCreatePixmapFromBitmapData(
|
|||
|
display,
|
|||
|
DefaultRootWindow(display),
|
|||
|
(char *) nvi_bits,
|
|||
|
nvi_width,
|
|||
|
nvi_height,
|
|||
|
icon_fg,
|
|||
|
icon_bg,
|
|||
|
DefaultDepth( display, DefaultScreen(display) )
|
|||
|
);
|
|||
|
#endif
|
|||
|
XutSetIcon( top_level, nvi_height, nvi_width, icon_pm );
|
|||
|
}
|
|||
|
|
|||
|
/* in the shell, we will stack a menubar an editor */
|
|||
|
main_w = XtVaCreateManagedWidget( "main",
|
|||
|
xmMainWindowWidgetClass,
|
|||
|
top_level,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
/* create the menubar */
|
|||
|
XtManageChild( (Widget) vi_create_menubar( main_w ) );
|
|||
|
|
|||
|
/* add the VI widget from the library */
|
|||
|
editor = vi_create_editor( "editor", main_w, onexit );
|
|||
|
|
|||
|
/* put it up */
|
|||
|
XtRealizeWidget( top_level );
|
|||
|
|
|||
|
/* We *may* want all keyboard events to go to the editing screen.
|
|||
|
* If the editor is the only widget in the shell that accepts
|
|||
|
* keyboard input, then the user will expect that he can type when
|
|||
|
* the pointer is over the scrollbar (for example). This call
|
|||
|
* causes that to happen.
|
|||
|
*/
|
|||
|
XtSetKeyboardFocus( top_level, XtNameToWidget( editor, "*screen" ) );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int
|
|||
|
main(int argc, char **argv)
|
|||
|
{
|
|||
|
IPVI* ipvi;
|
|||
|
/*
|
|||
|
* Initialize the X widgetry. We must do this before picking off
|
|||
|
* arguments as well-behaved X programs have common argument lists
|
|||
|
* (e.g. -rv for reverse video).
|
|||
|
*/
|
|||
|
create_top_level_shell(&argc, argv);
|
|||
|
|
|||
|
/* We need to know if the child process goes away. */
|
|||
|
(void)signal(SIGCHLD, onchld);
|
|||
|
|
|||
|
vi_create(&ipvi, 0);
|
|||
|
(void)ipvi->run(ipvi, argc, argv);
|
|||
|
ipvi->new_window(ipvi,&ipvi_motif,-1);
|
|||
|
ipvi_motif->set_ops(ipvi_motif, &ipsi_ops_motif);
|
|||
|
/* Run vi: the parent returns, the child is the vi process. */
|
|||
|
vi_ifd = ipvi_motif->ifd;
|
|||
|
vi_ofd = ipvi_motif->ofd;
|
|||
|
pid = ipvi->pid;
|
|||
|
|
|||
|
/* Tell X that we are interested in input on the pipe. */
|
|||
|
XtAppAddInput(ctx, vi_ifd,
|
|||
|
(XtPointer)XtInputReadMask, vi_input_func, NULL);
|
|||
|
|
|||
|
/* Main loop. */
|
|||
|
XtAppMainLoop(ctx);
|
|||
|
|
|||
|
/* NOTREACHED */
|
|||
|
abort();
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
XutSetIcon(Widget wid, int height, int width, Pixmap p)
|
|||
|
{
|
|||
|
Display *display = XtDisplay(wid);
|
|||
|
Window win;
|
|||
|
|
|||
|
/* best bet is to set the icon window */
|
|||
|
XtVaGetValues( wid, XtNiconWindow, &win, 0 );
|
|||
|
|
|||
|
if ( win == None ) {
|
|||
|
win = XCreateSimpleWindow( display,
|
|||
|
RootWindow( display,
|
|||
|
DefaultScreen( display ) ),
|
|||
|
0, 0,
|
|||
|
width, height,
|
|||
|
0,
|
|||
|
CopyFromParent,
|
|||
|
CopyFromParent
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
if ( win != None ) {
|
|||
|
XtVaSetValues( wid, XtNiconWindow, win, 0 );
|
|||
|
XSetWindowBackgroundPixmap( display, win, p );
|
|||
|
}
|
|||
|
|
|||
|
else {
|
|||
|
/* do it the old fashioned way */
|
|||
|
XtVaSetValues( wid, XtNiconPixmap, p, 0 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Support for multiple colormaps
|
|||
|
*
|
|||
|
* XutInstallColormap( String name, Widget wid )
|
|||
|
* The first time called, this routine checks to see if the
|
|||
|
* resource "name*installColormap" is "True". If so, the
|
|||
|
* widget is assigned a newly allocated colormap.
|
|||
|
*
|
|||
|
* Subsequent calls ignore the "name" parameter and use the
|
|||
|
* same colormap.
|
|||
|
*
|
|||
|
* Future versions of this routine may handle multiple colormaps
|
|||
|
* by name.
|
|||
|
*/
|
|||
|
static enum { cmap_look, cmap_use, cmap_ignore } cmap_state = cmap_look;
|
|||
|
|
|||
|
static Boolean use_colormap = False;
|
|||
|
|
|||
|
static XutResource colormap_resources[] = {
|
|||
|
{ "installColormap", XutRKboolean, &use_colormap }
|
|||
|
};
|
|||
|
|
|||
|
static void
|
|||
|
XutInstallColormap(String name, Widget wid)
|
|||
|
{
|
|||
|
static Colormap cmap = 0;
|
|||
|
static Display *cmap_display = 0;
|
|||
|
Display *display = XtDisplay(wid);
|
|||
|
|
|||
|
/* what is the current finite state? */
|
|||
|
if ( cmap_state == cmap_look ) {
|
|||
|
|
|||
|
/* what does the resource say? */
|
|||
|
__XutConvertResources( wid,
|
|||
|
name,
|
|||
|
colormap_resources,
|
|||
|
XtNumber(colormap_resources)
|
|||
|
);
|
|||
|
|
|||
|
/* was the result "True"? */
|
|||
|
if ( ! use_colormap ) {
|
|||
|
cmap_state = cmap_ignore;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
/* yes it was */
|
|||
|
cmap_state = cmap_use;
|
|||
|
cmap_display = display;
|
|||
|
cmap = XCopyColormapAndFree( display,
|
|||
|
DefaultColormap( display,
|
|||
|
DefaultScreen( display )
|
|||
|
)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
/* use the private colormap? */
|
|||
|
if ( cmap_state == cmap_use ) {
|
|||
|
XtVaSetValues( wid, XtNcolormap, cmap, 0 );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* onchld --
|
|||
|
* Handle SIGCHLD.
|
|||
|
*/
|
|||
|
static void
|
|||
|
onchld(int signo)
|
|||
|
{
|
|||
|
/* If the vi process goes away, we exit as well. */
|
|||
|
if (kill(pid, 0))
|
|||
|
vi_fatal_message(top_level, "The vi process died. Exiting.");
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* onexit --
|
|||
|
* Function called when the editor "quits".
|
|||
|
*/
|
|||
|
static void
|
|||
|
onexit(void)
|
|||
|
{
|
|||
|
exit (0);
|
|||
|
}
|