--- axe-6.1.2.orig/Axe.rules +++ axe-6.1.2/Axe.rules @@ -72,7 +72,10 @@ #define InstallCoaxe(bindest) @@\ InstallProgram(coaxe,bindest) @@\ install:: @@\ - if [ -f bindest/faxe ]; then set +x; \ @@\ - else (cd bindest; set -x; $(LN) coaxe faxe); fi @@\ - if [ -f bindest/poleaxe ]; then set +x; \ @@\ - else (cd bindest; set -x; $(LN) coaxe poleaxe); fi + if [ -f $(DESTDIR)$(Bindir)/faxe ]; then set +x; \ @@\ + else (cd $(DESTDIR)$(Bindir); set -x; $(LN) coaxe faxe); fi @@\ +/** H. S. Teoh: disabled poleaxe -- coaxe.c seems to have only partial code + ** that handles poleaxe; possibly dysfunctional. + if [ -f $(DESTDIR)$(BINDIR)/poleaxe ]; then set +x; \ @@\ + else (cd $(DESTDIR)$(BINDIR); set -x; $(LN) coaxe poleaxe); fi + **/ --- axe-6.1.2.orig/Axe.tmpl +++ axe-6.1.2/Axe.tmpl @@ -1,21 +1,24 @@ /* Where do you want the executables to be installed */ -Bindir = ${BINDIR} +/*Bindir = ${BINDIR}*/ +Bindir = /usr/bin /* Where do you want the app defaults file to be installed */ Appdir = ${XAPPLOADDIR} /* Where do you want the man page to be installed */ -Mandir = ${MANDIR} +/*Mandir = ${MANDIR}*/ +Mandir = /usr/share/man/man1 /* Where do you want the ancilliary files to be installed */ -AxeLibdir = ${LIBDIR} +/*AxeLibdir = ${LIBDIR}*/ +AxeLibdir = /usr/lib /* As of aXe 6.0 the help is presented using a separate application called */ /* axinfo. Repeat the above exercise for it. */ InfoBindir = ${Bindir} InfoAppdir = ${Appdir} InfoMandir = ${Mandir} -InfoLibdir = ${AxeLibdir} +InfoLibdir = /usr/share/info @@ -35,13 +38,13 @@ /* If you want to incorporate the optional extension language feature first */ /* read the file INSTALL for more information and uncomment the next line */ -/* #define Extension */ +#define Extension /* ...and state where the Tcl include files are */ -/* #define TclIncDir /usr/local/tcl/include */ +#define TclIncDir /usr/include/tcl /* ...and where the library is, i.e. TclLibDir/libtcl.a (or .so.?.?) exists */ -/* #define TclLibDir /usr/local/tcl/lib */ +/* #define TclLibDir /usr/lib */ @@ -107,8 +110,9 @@ #ifdef Extension EXTN_SRCS = Language.c EXTN_OBJS = Language.o -EXTN_INCLUDES = -I/**/TclIncDir +EXTN_INCLUDES = -I/**/TclIncDir -DUSE_INTERP_RESULT EXTN_LDFLAGS = -L/**/TclLibDir +/* EXTN_LIBS = -ltcl8.0 -lm */ EXTN_LIBS = -ltcl -lm EXTENSION = -DEXTENSION #endif --- axe-6.1.2.orig/Help/Axinfo.ad +++ axe-6.1.2/Help/Axinfo.ad @@ -0,0 +1,62 @@ +Axinfo.version: axinfo 1.0 +*infoPath: /usr/share/info + +*hyperwin.title: axinfo +*hyperwin.iconName: axinfo +*hyperwin.translations: #override \n\ + WM_PROTOCOLS:delete-hyper() + +*view.allowVert: True +*view.forceBars: True + +*hyper.rows: 24 +*hyper.columns: 80 + +*Hyper.normalFont: 7x13 +*Hyper.highlightFont: 7x13bold +*Hyper.margin: 4 + +*hpane*Command.translations: #override \n\ + : highlight() show-info() \n\ + : reset() clear-info() + +*last.label: Last + +*map.label: Tree + +*treewin.title: axinfo +*treewin.iconName: axinfo-tree +*treewin.translations: #override \n\ + WM_PROTOCOLS:delete-tree() + +*Paned*showGrip: False + +*porthole.width: 450 +*porthole.height: 326 +*porthole.borderWidth: 0 + +*tree.translations: #override \n\ + : show-info() \n\ + : clear-info() \n\ + : start-drag() \n\ + : drag() + +*treewin*Command.translations: #override \n\ + : highlight() show-info() \n\ + : reset() clear-info() + +*quit.label: Quit +*close.label: Delete +*info.label: + +*Confirmer*Label.borderWidth: 0 +*Confirmer*Box.orientation: horizontal +*Confirmer*Box.borderWidth: 0 +*Confirmer*Box.vSpace: 2 +*Confirmer*confirm.accelerators:Ctrla: set() notify() reset() +*Confirmer*alternative.accelerators:Ctrlb: set() notify() reset() +*Confirmer*cancel.label: cancel (^C) +*Confirmer*cancel.accelerators: Ctrlc: set() notify() reset() + +*listen.translations: #override \n\ + AXE_AXINFO: notify() --- axe-6.1.2.orig/Help/Hyper.c +++ axe-6.1.2/Help/Hyper.c @@ -977,9 +977,12 @@ char *fname; { Widget widget = (Widget) hyper; +#if !defined(__GLIBC__) || __GLIBC__ < 2 extern char *sys_errlist[]; +#endif FILE *f = fopen(fname,"r"); + fprintf(stderr,"opening info file %s\n",fname); if(f) { set_text(hyper,get_from_file,(XtPointer)f); --- axe-6.1.2.orig/Help/Imakefile +++ axe-6.1.2/Help/Imakefile @@ -10,7 +10,7 @@ LOCAL_LIBRARIES = ../Widgets/libaxe.a ${XAW3D_LIBS} ${TABLE_LIBS} SYS_LIBRARIES = XawClientLibs DEPLIBS = ../Widgets/libaxe.a XawClientDepLibs - + ComplaxeProgramTarget(axinfo,${InfoBindir},${InfoMandir}) InstallAxeDefaults(Axinfo,${InfoAppdir}) InstallMultiple(axe.info axe.info-1 axe.info-2,${InfoLibdir}) @@ -54,3 +54,6 @@ A4master:A4ps psbook axe.A4.ps | psnup -2 >A4master.ps + +axinfo.o:axinfo.c + --- axe-6.1.2.orig/Help/axinfo.c +++ axe-6.1.2/Help/axinfo.c @@ -43,9 +43,10 @@ #include #include +#include extern char *getenv(); -extern char *malloc(), *realloc(); +extern void *malloc(), *realloc(); #include "Confirmer.h" #include "Hyper.h" @@ -325,7 +326,10 @@ { FILE *inf; struct stat fstats; - + char *s; + void *b; + int l; + if (currentfile) { if (file != currentfile) @@ -338,8 +342,37 @@ return; } } - inf = fopen(file, "r"); + +#define PAGESIZE 4096 + /* this is needed so that axinfo can read gzipped info files, the + preferred standard in Debian + Note that "currentfile" will be the name of the + file without the .gz extension + */ + if (!inf){ + s=(char*)malloc(sizeof(char)*(strlen(file)+15)); + strcpy(s,"gunzip -c "); + strcat(s,file); + strcat(s,".gz"); + inf=popen(s,"r"); + if(inf){ + buffer=malloc(PAGESIZE); + s=buffer; + while((l=fread(s,1,PAGESIZE,inf))==PAGESIZE){ + s+=PAGESIZE; + l=s-(char*)buffer; + buffer=realloc(buffer,l+PAGESIZE); + s=buffer+l; + } + buflen=l+s-(char*)buffer; + buffer=realloc(buffer,buflen+1); + *((char*)buffer+buflen)=0; + currentfile = file; + fclose(inf); + return; + } + } if (!inf) { Widget conf; @@ -350,7 +383,7 @@ NULL); XtAddCallback(conf, XtNpopdownCallback, Exit, (XtPointer) 0); - sprintf(message, "Unable to open\n%s", file); + sprintf(message, "Unable to open\n%s or %s", currentfile, file); ConfirmerRequestConfirmation(conf, message, "acknowledge", ConfirmerPopdown, "unused", NULL, --- axe-6.1.2.orig/Help/axinfo.man +++ axe-6.1.2/Help/axinfo.man @@ -1,4 +1,4 @@ -.TH AXINFO 1 "January 1994" "axinfo Release 1.0" +.TH AXINFO 1x "January 1994" "axinfo Release 1.0" .SH NAME axinfo - an X info reader .SH SYNOPSIS --- axe-6.1.2.orig/Imakefile +++ axe-6.1.2/Imakefile @@ -14,7 +14,7 @@ SRCS = axe.c OBJS = axe.o - EXTRA_INCLUDES = -I. -I./Widgets ${EXTN_INCLUDES} + EXTRA_INCLUDES = -g3 -I. -I./Widgets ${EXTN_INCLUDES} LOCAL_LDFLAGS = ${TABLE_LDFLAGS} ${EXTN_LDFLAGS} ${XAW3D_LDFLAGS} SYS_LIBRARIES = XawClientLibs LOCAL_LIBRARIES = Widgets/libaxe.a ${TABLE_LIBS} ${EXTN_LIBS} ${XAW3D_LIBS} --- axe-6.1.2.orig/Widgets/AxeEditor.c +++ axe-6.1.2/Widgets/AxeEditor.c @@ -53,9 +53,12 @@ #include extern int errno; #ifndef __BSD_4_4__ +#if !defined(__GLIBC__) || __GLIBC__ < 2 extern char *sys_errlist[]; #endif +#endif #include +#include #ifdef EXTENSION #include "Language.h" @@ -405,12 +408,16 @@ { char *dir; +/* H. S. Teoh: always use getcwd(); getwd() is unsafe. #if defined(SYSV) || defined(SVR4) +*/ extern char *getcwd(); #define getwd(buf) getcwd(buf,MAXPATHLEN) +/* #else extern char *getwd(); #endif +*/ extern char *getenv(); --- axe-6.1.2.orig/Widgets/AxeEditor.c.ORIG +++ axe-6.1.2/Widgets/AxeEditor.c.ORIG @@ -0,0 +1,4240 @@ +/* + * Copyright 1992, 1993 The University of Newcastle upon Tyne + * + * Permission to use, copy, modify and distribute this software and its + * documentation for any purpose other than its commercial exploitation + * is hereby granted without fee, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of The University of Newcastle upon Tyne not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The University of + * Newcastle upon Tyne makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF NEWCASTLE UPON TYNE DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * NEWCASTLE UPON TYNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Wight (j.k.wight@newcastle.ac.uk) + * Department of Computing Science + * University of Newcastle upon Tyne, UK + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +extern int errno; +#ifndef __BSD_4_4__ +#if !defined(__GLIBC__) || __GLIBC__ < 2 +extern char *sys_errlist[]; +#endif +#endif +#include + +#ifdef EXTENSION +#include "Language.h" +#endif + +#include "AxeEditorP.h" +extern char *getenv(); + +#include "regexp.h" +#include "util.h" + +#include "version.h" + +#include "axeLogo.xbm" +#include "fwdArrow.xbm" +#include "bwdArrow.xbm" +#include "vtCentre.xbm" +#include "hzCentre.xbm" +#include "tickMark.xbm" +#include "modMark.xbm" + +static Boolean validAction; + +/* + * The names in the first column must be the same + * as those in the defaultMenuList that follows + */ +static MenuRecord chosenMenus[] = { + "move", False, + "search", False, + "insert", False, + "delete", False, + "help", False, + "misc", False, + "font", False, + "window", False, + "buffer", False, + "show", False, + "file", False, + "quit", False, + 0, False, +}; + +#define defaultMenuList "move search insert delete help misc font window \ + buffer show file quit logo" + +#define defaultFontList "Small:6x13 Medium:8x13 Large:9x15 Huge:10x20" + +#define defaultMiniMenu "print:lpr spell nroff mail | \ + exec:mini-commit abort:mini-abort | \ + print:lpr\n spell:spell\n nroff:nroff\n" + +#define Offset(field) XtOffsetOf(AxeEditorRec, axeEditor.field) + +static XtResource resources[] = { + {XtNfile, XtCFile, XtRString, sizeof(String), + Offset(file), XtRString, NULL}, + {XtNmenuList, XtCMenuList, XtRString, sizeof(String), + Offset(menu_list), XtRString, defaultMenuList}, + {XtNbuttons, XtCButtons, XtRBoolean, sizeof(Boolean), + Offset(buttons), XtRImmediate, (XtPointer) False}, + {XtNbuttonList, XtCButtonList, XtRString, sizeof(String), + Offset(button_list), XtRString, NULL}, + {XtNinfoTimeout, XtCInfoTimeout, XtRInt, sizeof(int), + Offset(info_timeout), XtRImmediate, (XtPointer) 0}, + {XtNfocusToText, XtCFocusToText, XtRBoolean, sizeof(Boolean), + Offset(focus_to_text), XtRImmediate, (XtPointer) False}, + {XtNsuppressFilename, XtCSuppressPane, XtRBoolean, sizeof(Boolean), + Offset(suppressFilename), XtRImmediate, (XtPointer) False}, + {XtNsuppressInfobar, XtCSuppressPane, XtRBoolean, sizeof(Boolean), + Offset(suppressInfobar), XtRImmediate, (XtPointer) False}, + {XtNsuppressMinibuffer, XtCSuppressPane, XtRBoolean, sizeof(Boolean), + Offset(suppressMinibuffer), XtRImmediate, (XtPointer) False}, + {XtNfontList, XtCFontList, XtRString, sizeof(String), + Offset(font_list), XtRString, defaultFontList}, + {XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension), + Offset(internal_border_width), XtRImmediate, (XtPointer) 1}, + {XtNfullPathnames, XtCFullPathnames, XtRBoolean, sizeof(Boolean), + Offset(full_pathnames), XtRImmediate, (XtPointer) False}, + {XtNchangeCallback, XtCCallback, XtRCallback, sizeof(XtPointer), + Offset(change_callbacks), XtRCallback, (XtPointer) NULL}, +}; + +#undef Offset + +#define INCREMENT 5 +#define MAXSTRLEN 16 +#define CHUNK 10 + +#define EDITORS axeEditorClassRec.axeEditor_class.editors +#define NUMBEROFEDITORS axeEditorClassRec.axeEditor_class.numberOfEditors +#define MAXEDITORS axeEditorClassRec.axeEditor_class.maxEditors + +#define CLASS(field) axeEditorClassRec.axeEditor_class.field +#define PRIVATE(w,field) (((AxeEditorWidget) w)->axeEditor.field) + +static void ClassInitialize(), PseudoClassInitialize(), Initialize(); +static void CalculateSize(), Resize(), Realize(); +static void Destroy(); +static XtGeometryResult GeometryManager(); +static void InsertChild(), DeleteChild(); + +static XpTableLoc MakeButtonsLayout(); +static void NewEditor(), DeckChange(), SetKeyboardFocus(); +static Widget MakeMenu(); +static void MakeOneMenu(); +static void MakeFontMenu(), MakeShowMenu(), MakeLogoMenu(), MakeMiniMenu(); +static void MakeButtons(); + +static void RePopulateShowMenu(), FreeFontList(); +static FontListStruct *ParseFontList(); + +static void UpdateFileName(), UpdateTitles(); +static Widget AxeEditorOf(), ShellOf(); +static String HomeFile(); +String AxeEditorExpandName(); + +static void Help(); +static void NewWindow(), CloseWindow(), CloseAll(), IconifyAll(), Restack(); +static void NewBuffer(), CloseBuffer(); +static void SaveAndClose(), SaveAll(); +static void miniSearch(), miniInsert(), miniSaveAs(), miniLoad(), miniPipe(); +static void miniClear(), miniSelect(), miniAbort(), MiniLeave(), MiniCommit(); +static void miniShell(), miniStuff(); +#ifdef EXTENSION +static int MiniInterp(); +#endif +static void MiniUninstallAccelerators(); +static void startMacro(), endMacro(), execMacro(), repeatMacro(); +static void UpdateInfo(), UpdateInfoBar(); + +static char commandButtonsLayout[] = "\ + mbeg 0 1 wW; sbtext 1 1 wW; ifile 2 1 wW; \ + mend 0 2 wW; sftext 1 2 wW; isel 2 2 wW; \ + mup 0 3 wW; sline 1 3 wW; ipaste 2 3 wW; \ + mdown 0 4 wW; scaret 1 4 wW; ictrl 2 4 wW; \ + mtop 0 5 wW; sbsel 1 5 wW; \ + mbot 0 6 wW; sfsel 1 6 wW; \ +\ + dword 3 1 wW; hgnrl 4 1 wW; mundo 5 1 wW; \ + dline 3 2 wW; hbind 4 2 wW; mwhere 5 2 wW; \ + dsel 3 3 wW; hcust 4 3 wW; mform 5 3 wW; \ + dcut 3 4 wW; hpop 4 4 wW; mcentre 5 4 wW; \ + hextn 4 5 wW; mhcentr 5 5 wW; \ + hchng 4 6 wW; mpref 5 6 wW; \ +\ + wnew 7 1 wW; bempty 8 1 wW; fsvex 10 1 wW; \ + wfull 7 2 wW; bfull 8 2 wW; fsvall 10 2 wW; \ + wclose 7 3 wW; bclear 8 3 wW; fsave 10 3 wW; \ + wclall 7 4 wW; bclose 8 4 wW; fsvas 10 4 wW; \ + wicon 7 5 wW; fload 10 5 wW; \ + wdeicon 7 6 wW; frvrt 10 6 wW; \ +\ + qquit 11 1 wW; \ + qsvex 11 2 wW; \ + qsvclw 11 3 wW; \ + qsvclb 11 4 wW;"; + +static ButtonRecord buttonActions[] = { +"mMove", NULL, + "mbeg", "beginning-of-line", + "mend", "end-of-line", + "mup", "previous-page", + "mdown", "next-page", + "mtop", "beginning-of-file", + "mbot", "end-of-file", + +"mSearch", NULL, + "sbtext", "search(backward)", + "sftext", "search(forward)", + "sline", "goto-line", + "scaret", "search-caret", + "sbsel", "backward-search-selection", + "sfsel", "forward-search-selection", + +"mInsert", NULL, + "ifile", "include-file", + "isel", "include-selection", + "ipaste", "paste", + "ictrl", "insert-control", + +"mDelete", NULL, + "dword", "delete-word", + "dline", "delete-line", + "dsel", "delete-selection", + "dcut", "kill-selection", + +"mHelp", NULL, + "hgnrl", "help(Introduction)", + "hbind", "help(Bindings)", + "hcust", "help(Customise)", + "hpop", "help(Popups)", +#ifdef EXTENSION + "hextn", "help(Language)", +#endif + "hchng", "help(Changes)", + +"mMisc", NULL, + "mundo", "undo", + "mwhere", "where", + "mform", "form-paragraph", + "mcentre", "redraw-display", + "mhcentr", "centre-line", + "mpref", "set-preferences", + +"mWindow", NULL, + "wnew", "new-window", + "wfull", "new-window(load)", + "wclose", "close-window", + "wclall", "close-all", + "wicon", "iconify-all(I)", + "wdeicon", "iconify-all(D)", + +"mBuffer", NULL, + "bempty", "new-buffer", + "bfull", "new-buffer(load)", + "bclear", "clear-buffer", + "bclose", "close-buffer", + +"mFile", NULL, + "fsvex", "save-and-close", + "fsvall", "save-all", + "fsave", "save-file", + "fsvas", "save-as", + "fload", "load-file", + "frvrt", "reload-file", + +"mQuit", NULL, + "qquit", "close-all", + "qsvex", "save-and-close", + "qsvclw", "save-and-close(window)", + "qsvclb", "save-and-close(buffer)", +}; + +static char miniTranslationsTable[] = "\ + : display-caret(on) update-info(\"search /)fwd ?)bwd; [0-9][0-9]*)goto; r)ead; w)rite; e)dit; |)pipe; !)shell\")\n\ + : mini-leave() update-info(\" \")\n\ + CtrlG: mini-abort() \n\ + Escape: mini-abort() \n\ + Return: mini-commit()"; + +static char miniAcceleratorsTable[] = "#override \n\ + CtrlA: beginning-of-line() \n\ + CtrlB: backward-character() \n\ + CtrlD: delete-next-character() \n\ + CtrlE: end-of-line() \n\ + CtrlF: forward-character() \n\ + CtrlG: mini-abort() \n\ + CtrlK: kill-to-end-of-line() \n\ + Delete: delete-previous-character() \n\ + Escape: mini-abort() \n\ + Return: mini-commit() \n\ + : insert-char()"; + +static XtActionsRec actions[] = { + "help", Help, + + "new-window", NewWindow, + "close-window", CloseWindow, + "close-all", CloseAll, + "iconify-all", IconifyAll, + "deiconify-all", IconifyAll, + "restack", Restack, + + "new-buffer", NewBuffer, + "close-buffer", CloseBuffer, + + "save-and-exit ", SaveAndClose, /* backwards compatability */ + "save-and-close", SaveAndClose, + "save-all", SaveAll, + + "mini-search", miniSearch, + "mini-insert", miniInsert, + "mini-saveas", miniSaveAs, + "mini-load", miniLoad, + "mini-pipe", miniPipe, + "mini-clear", miniClear, + "mini-select", miniSelect, + "mini-abort", miniAbort, + "mini-leave", MiniLeave, + "mini-commit", MiniCommit, + "mini-shell", miniShell, + "mini-stuff", miniStuff, + + "start-macro", startMacro, + "end-macro", endMacro, + "exec-macro", execMacro, + "repeat-macro", repeatMacro, + + "update-info", UpdateInfo, +}; + +AxeEditorClassRec axeEditorClassRec = { + /* Core class part */ + { + /* superclass */ (WidgetClass) &compositeClassRec, + /* class_name */ "AxeEditor", + /* widget_size */ sizeof(AxeEditorRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ XtExposeCompressMultiple, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ Resize, + /* expose */ XtInheritExpose, + /* set_values */ NULL, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback offsets */ NULL, + /* tm_table */ NULL, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ NULL, + /* extension */ NULL, + }, + { + /* composite class fields */ + /* geometry_manager */ GeometryManager, + /* change_managed */ XtInheritChangeManaged, + /* insert_child */ InsertChild, + /* delete_child */ DeleteChild, + /* extension */ NULL + }, + /* AxeEditor class part */ + { + /* extension */ NULL + } +}; + +WidgetClass axeEditorWidgetClass = (WidgetClass) &axeEditorClassRec; + +static void +ClassInitialize() +{ + char *dir; + +/* H. S. Teoh: always use getcwd(); getwd() is unsafe. +#if defined(SYSV) || defined(SVR4) +*/ + extern char *getcwd(); +#define getwd(buf) getcwd(buf,MAXPATHLEN) +/* +#else + extern char *getwd(); +#endif +*/ + + extern char *getenv(); + + EDITORS = NULL; + NUMBEROFEDITORS = 0; + MAXEDITORS = 0; + + CLASS(show_menu) = (Widget) 0; + + CLASS(mini_translations) = XtParseTranslationTable(miniTranslationsTable); + CLASS(mini_accelerators) = XtParseAcceleratorTable(miniAcceleratorsTable); + + if ( (dir = getenv("HOME")) ) + { + CLASS(home_dir) = XtNewString(dir); + } + else + { + CLASS(home_dir) = NULL; + } + CLASS(home_dir_len) = strlen(CLASS(home_dir)); + + CLASS(current_dir) = XtMalloc(MAXPATHLEN); + if (!getwd(CLASS(current_dir))) + { + if (CLASS(home_dir)) + { + strcpy(CLASS(current_dir), CLASS(home_dir)); + } + else + { + CLASS(current_dir)[0] = '\0'; + } + } + + strcat(CLASS(current_dir), "/"); + CLASS(current_dir_len) = strlen(CLASS(current_dir)); + + CLASS(show_menu_callbacks) = 0; + CLASS(show_menu_callback_list) = 0; + + CLASS(default_mini_menu) = 0; + CLASS(mini_menu) = 0; + + CLASS(macro_id) = (XtActionHookId) 0; + CLASS(macro_size) = 0; + CLASS(max_macro_size) = 0; + CLASS(in_macro_string) = False; + CLASS(macro_commands) = (MacroList) 0; + + CLASS(show_work_proc) = False; +} + +static void +PseudoClassInitialize(w) + Widget w; +{ + Display *display; + Window rootWindow; + Widget app; + + if (!CLASS(axeLogo)) + { + display = XtDisplay(w); + rootWindow = XDefaultRootWindow(display); + + CLASS(axeLogo) = + XCreateBitmapFromData(display, rootWindow, (char *) axeLogo_bits, + axeLogo_width, axeLogo_height); + + CLASS(fwdArrow) = + XCreateBitmapFromData(display, rootWindow, (char *) fwdArrow_bits, + fwdArrow_width, fwdArrow_height); + + CLASS(bwdArrow) = + XCreateBitmapFromData(display, rootWindow, (char *) bwdArrow_bits, + bwdArrow_width, bwdArrow_height); + + CLASS(vtCentre) = + XCreateBitmapFromData(display, rootWindow, (char *) vtCentre_bits, + vtCentre_width, vtCentre_height); + + CLASS(hzCentre) = + XCreateBitmapFromData(display, rootWindow, (char *) hzCentre_bits, + hzCentre_width, hzCentre_height); + + CLASS(tickMark) = + XCreateBitmapFromData(display, rootWindow, (char *) tickMark_bits, + tickMark_width, tickMark_height); + + CLASS(modMark) = + XCreateBitmapFromData(display, rootWindow, (char *) modMark_bits, + modMark_width, modMark_height); + + while ((app = XtParent(w))) + { + w = app; + } + CLASS(menu_parent) = w; + } +} + +/* ARGSUSED */ +static void +Initialize(req, new, args, num_args) + Widget req, new; + ArgList args; + Cardinal *num_args; +{ + AxeEditorWidget aew = (AxeEditorWidget) new; + FontListStruct *buttonList = NULL; + XpTableLoc tableLoc; + + int menu; + char menuName[32]; + Widget fileName, infoBar, buttons, miniBuffer; + Widget menuButton, logoButton, miniMenu; + + PseudoClassInitialize(aew); + + NewEditor(aew); + + fileName = PRIVATE(new,file_name) = + XtVaCreateWidget("fileName", labelWidgetClass, new, NULL); + if (!PRIVATE(new,suppressFilename)) + { + XtManageChild(fileName); + } + + infoBar = PRIVATE(new,info_bar) = + XtVaCreateWidget("infoBar", labelWidgetClass, new, + XtNlabel, QVERSION, + NULL); + PRIVATE(new,info_timer) = (XtIntervalId) 0; + if (!PRIVATE(new,suppressInfobar)) + { + XtManageChild(infoBar); + } + + tableLoc = MakeButtonsLayout(new, &buttonList); + buttons = PRIVATE(new,menu_bar) = + XtVaCreateManagedWidget("buttons", xpTableWidgetClass, new, + XtNlayout, tableLoc, + NULL); + XpTableLocFree(tableLoc); + + for (menu = 0; chosenMenus[menu].name; ++menu) + { + if (chosenMenus[menu].chosen) + { + sprintf(menuName, "%sMenu", chosenMenus[menu].name); + menuButton + = XtVaCreateManagedWidget(menuName, + axeMenuButtonWidgetClass, buttons, NULL); + + if (strcmp(menuName, "showMenu") == 0 && !CLASS(show_menu)) + { + CLASS(show_menu) = MakeMenu(menuButton, CLASS(menu_parent), + MakeShowMenu, False); + } + else if (strcmp(menuName, "fontMenu") == 0) + { + (void) MakeMenu(menuButton, new, MakeFontMenu, False); + } + else + { + (void) MakeMenu(menuButton, CLASS(menu_parent), MakeOneMenu, + False); + } + } + } + PRIVATE(new,font_table) = (FontListStruct *) 0; + + logoButton + = XtVaCreateManagedWidget("axeLogo", + axeMenuButtonWidgetClass, buttons, + XtNbitmap, CLASS(axeLogo), + XtNhelp, QVERSION, + NULL); + (void) MakeMenu(logoButton, CLASS(menu_parent), MakeLogoMenu, False); + + if (PRIVATE(new,buttons) || PRIVATE(new,button_list)) + { + MakeButtons(buttons, buttonList); + if (buttonList) + { + FreeFontList(XtDisplay(new), buttonList); + } + } + + PRIVATE(new,ed_deck) = + XtVaCreateManagedWidget("edDeck", axeTextDeckWidgetClass, new, + XtNfile, PRIVATE(new,file), + NULL); + XtAddCallback(PRIVATE(new,ed_deck), XtNchangeCallback, DeckChange, + (XtPointer) new); + XtVaGetValues(AxeTextDeckTop(PRIVATE(new,ed_deck)), + XtNtranslations, &(PRIVATE(new,defaultTextTranslations)), + NULL); + + miniBuffer = PRIVATE(new,mini_buffer) = + XtVaCreateWidget("miniBuffer", asciiTextWidgetClass, new, + XtNaccelerators, CLASS(mini_accelerators), + NULL); + XtOverrideTranslations(PRIVATE(new,mini_buffer), CLASS(mini_translations)); + + miniMenu = PRIVATE(new,mini_button) = + XtVaCreateWidget("miniMenu", axeMenuButtonWidgetClass, new, NULL); + (void) MakeMenu(miniMenu, CLASS(menu_parent), MakeMiniMenu, False); + + if (!PRIVATE(new,suppressMinibuffer)) + { + XtManageChild(miniBuffer); + XtManageChild(miniMenu); + } + PRIVATE(new,accelerateMini) = False; + + PRIVATE(new,confirmer) = + XtVaCreatePopupShell("confirmer", confirmerWidgetClass, new, NULL); + + SetKeyboardFocus(new, AxeTextDeckTop(PRIVATE(new,ed_deck))); + + /* The best we can do to keep Realize happy */ + CalculateSize(aew, &aew->core.width, &aew->core.height); +} + +static void +CalculateSize(aew, width, height) + AxeEditorWidget aew; + Dimension *width, *height; +{ + Cardinal child; + Dimension wide, maxWidth, high, totalHeight = 0; + + for (child = 0; child < aew->composite.num_children; ++child) + { + if (XtIsManaged(aew->composite.children[child])) + { + XtVaGetValues(aew->composite.children[child], + XtNwidth, &wide, + XtNheight, &high, + NULL); + + if (XtIsSubclass(aew->composite.children[child], + axeTextDeckWidgetClass)) + { + maxWidth = wide; + } + + if (XtIsSubclass(aew->composite.children[child], + axeMenuButtonWidgetClass)) + { + continue; + } + + totalHeight += high + PRIVATE(aew,internal_border_width); + } + } + *width = maxWidth; + *height = totalHeight - PRIVATE(aew,internal_border_width);; +} + +static void +Configure(aew, deltaHeight, initiator) + AxeEditorWidget aew; + Dimension deltaHeight; + Widget initiator; +{ + /* + * This routine needs looking at; the addition of the + * minibuffer MenuButton was done in a bit of a hurry. + */ + + Cardinal child; + Widget kid; + Dimension width, height, border; + Position x = -PRIVATE(aew,internal_border_width); + Position y = -PRIVATE(aew,internal_border_width); + Position atx, aty; + + for (child = 0; child < aew->composite.num_children; ++child) + { + kid = aew->composite.children[child]; + if (XtIsManaged(kid)) + { + XtVaGetValues(kid, + XtNheight, &height, + NULL); + + if (XtIsSubclass(kid, axeTextDeckWidgetClass)) + { + height += deltaHeight; + } + + if (kid == initiator) + { + kid->core.y = y; + } + else + { + aty = y; + border = PRIVATE(aew,internal_border_width); + if (XtIsSubclass(kid, asciiTextWidgetClass)) /* minibuffer */ + { + atx = PRIVATE(aew,mini_button)->core.width; + width = aew->core.width - atx + 1; + } + else + { + atx = x; + if (XtIsSubclass(kid, axeMenuButtonWidgetClass)) + { + width = kid->core.width; + aty = y + PRIVATE(aew,internal_border_width); + height = PRIVATE(aew,mini_buffer)->core.height; + border = 0; + } + else + { + width = aew->core.width; + } + } + XtConfigureWidget(kid, atx, aty, width, height, border); + } + if (!XtIsSubclass(kid, asciiTextWidgetClass)) /* order assumed */ + { + y += height + PRIVATE(aew,internal_border_width); + } + } + } +} + +static void +Resize(aew) + AxeEditorWidget aew; +{ + Dimension oldWidth, oldHeight; + + CalculateSize(aew, &oldWidth, &oldHeight); + + Configure(aew, aew->core.height - oldHeight, (Widget) 0); +} + +/* + * This routine shouldn't be necessary, but it is because the size could + * not be calculated in Initialize since the Table widget does not set its + * core width and height fields in its Initialize procedure as it should. + */ +static void +Realize(w, valueMask, attributes) +Widget w; +Mask *valueMask; +XSetWindowAttributes *attributes; +{ + AxeEditorWidget aew = (AxeEditorWidget) w; + Cardinal child; + Dimension width, height; + + (*((CompositeWidgetClass) + (axeEditorWidgetClass->core_class.superclass))->core_class.realize) (w, valueMask, attributes); + + for (child = 0; child < aew->composite.num_children; ++child) + { + if (XtIsManaged(aew->composite.children[child])) + { + XtRealizeWidget(aew->composite.children[child]); + } + } + + CalculateSize(aew, &width, &height); + XtVaSetValues(w, + XtNwidth, width, + XtNheight, height, + NULL); + /* + * This is done here and not in Initialize for the benefit of AxeWindow. + * UpdateTitles calls the change_callbacks list but AxeWindow can't + * add to the list until after it has created its AxeEditor component, + * hence if fileTitle were operative then the title bar would not be + * correct until a change causing an update occurred. + */ + UpdateTitles(aew); +} + +static void +Destroy(w) + Widget w; +{ + int editor; + + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + if (w == EDITORS[editor]) + { + EDITORS[editor] = NULL; + } + } + + if (PRIVATE(w,info_timer)) + { + XtRemoveTimeOut(PRIVATE(w,info_timer)); + } + + if (PRIVATE(w,font_table)) + { + FreeFontList(XtDisplay(w), PRIVATE(w,font_table)); + } +} + +static void +NewEditor(aew) + Widget aew; +{ + int editor; + Boolean spareSlot = False; + WidgetList oldList; + + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + if (!EDITORS[editor]) + { + spareSlot = True; + break; + } + } + + if (!spareSlot) + { + ++NUMBEROFEDITORS; + if (NUMBEROFEDITORS > MAXEDITORS) + { + MAXEDITORS += INCREMENT; + oldList = EDITORS; + EDITORS = (WidgetList) XtRealloc((char *) oldList, + MAXEDITORS * sizeof(Widget)); + } + editor = NUMBEROFEDITORS - 1; + } + + EDITORS[editor] = aew; +} + +/* ARGSUSED */ +static XtGeometryResult +GeometryManager(w, desired, allowed) + Widget w; + XtWidgetGeometry *desired, *allowed; +{ + AxeEditorWidget aew = (AxeEditorWidget) XtParent(w); + Dimension saveWidth, saveHeight, newWidth, newHeight; + XtWidgetGeometry request; + XtGeometryResult result; + +#define REQUESTS(flag) (desired->request_mode & flag) + + if (!XtIsSubclass(w, axeTextDeckWidgetClass)) + { + return XtGeometryNo; + } + + if (REQUESTS(CWWidth)) + { + saveWidth = w->core.width; + w->core.width = desired->width; + } + + if (REQUESTS(CWHeight)) + { + saveHeight = w->core.height; + w->core.height = desired->height; + } + CalculateSize(aew, &newWidth, &newHeight); + + request.request_mode = desired->request_mode; + request.width = newWidth; + request.height = newHeight; + + result = XtMakeGeometryRequest((Widget) aew, &request, + (XtWidgetGeometry *) 0); + + if (REQUESTS(XtCWQueryOnly) || result != XtGeometryYes) + { + if(REQUESTS(CWWidth)) + { + w->core.width = saveWidth; + } + + if (REQUESTS(CWHeight)) + { + w->core.height = saveHeight; + } + + return result; + } + + if (result == XtGeometryYes) + { + Configure(aew, 0, w); + + return XtGeometryYes; + } + + return XtGeometryNo; + +#undef REQUESTS +} + +static void +InsertChild(w) + Widget w; +{ + CompositeWidget parent = (CompositeWidget) XtParent(w); + + /* Silently disallow unknown children; the 6 we know of are fileName */ + /* infoBar, buttons, ed_deck, miniMenu, miniBuffer */ + if (parent->composite.num_children < 6) + { + (*((CompositeWidgetClass) + (axeEditorWidgetClass-> + core_class.superclass))->composite_class.insert_child) (w); + } +} + +static void +DeleteChild(w) + Widget w; +{ + Widget parent = XtParent(w); + + if (w == PRIVATE(parent,ed_deck)) + { + XtDestroyWidget(parent); + } +} + +static void +SetKeyboardFocus(axeEditor, ed) + Widget axeEditor, ed; +{ + if (PRIVATE(axeEditor,focus_to_text)) + { + XtSetKeyboardFocus(PRIVATE(axeEditor,file_name), ed); + XtSetKeyboardFocus(PRIVATE(axeEditor,info_bar), ed); + XtSetKeyboardFocus(PRIVATE(axeEditor,menu_bar), ed); + } +} + +/* ARGSUSED */ +static void +DeckChange(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + Widget axeEditor = (Widget) client_data; + Widget ed = AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)); + + SetKeyboardFocus(axeEditor, ed); + if (PRIVATE(axeEditor,accelerateMini)) + { + MiniUninstallAccelerators(w); + } + UpdateTitles(axeEditor); + + RePopulateShowMenu(XtWidgetToApplicationContext(axeEditor)); +} + +static Boolean +CreatePopupLater(client_data) + XtPointer client_data; +{ + Widget menu = (Widget) client_data; + XtCreatePopupChildProc create; + + XtVaGetValues(menu, + XtNcreatePopupChildProc, &create, + NULL); + + if (create) + { + (*create) (menu); + } + + XtVaSetValues(menu, + XtNcreatePopupChildProc, (XtCreatePopupChildProc) 0, + NULL); + + return True; +} + +static Widget +MenuMade(menuName, menuParent) + String menuName; + Widget menuParent; +{ + int n; + + for (n = 0; n < menuParent->core.num_popups; n++) + { + if (strcmp(XtName(menuParent->core.popup_list[n]), menuName) == 0) + { + return menuParent->core.popup_list[n]; + } + } + return (Widget) 0; +} + +static Widget +MakeMenu(menuButton, menuParent, childProc, always) + Widget menuButton, menuParent; + XtCreatePopupChildProc childProc; + Boolean always; +{ + String menuName; + Widget menu; + + XtVaGetValues(menuButton, + XtNmenuName, &menuName, + NULL); + + if (!(menu = MenuMade(menuName, menuParent))) + { + menu = XtVaCreatePopupShell(menuName, axeSimpleMenuWidgetClass, + menuParent, + NULL); + XtVaSetValues(menu, + XtNcreatePopupChildProc, childProc, + NULL); + + AxeSimpleMenuStorePopperUpper(menu, AxeEditorParentOf(menuButton)); + + /* + * No longer applies to any menu; retained just in case + */ + if (always) + { + XtAppAddWorkProc(XtWidgetToApplicationContext(menu), + CreatePopupLater, + (XtPointer) menu); + } + + return menu; + } + + return (Widget) 0; +} + +static void +MakeEvent(widget, event) + Widget widget; + XEvent *event; +{ + Window root, child; + unsigned int mask; + + XQueryPointer(XtDisplay(widget), XtWindow(widget), &root, &child, + &event->xbutton.x_root, &event->xbutton.y_root, + &event->xbutton.x, &event->xbutton.y, &mask); + + event->xbutton.type = ButtonRelease; +} + +static void +GenericAction(widget, client_data) + Widget widget; + XtPointer client_data; +{ + XEvent event; + String action = (String) client_data, params[1], p, q, proc; + char routine[32], param[128]; + Cardinal num_params; + + if ( (p = index(action, '(')) ) + { + strncpy(routine, action, p - action); + routine[p - action] = '\0'; + p += 1; + q = index(p, ')'); + strncpy(param, p, q - p); + param[q - p] = '\0'; + proc = routine; + params[0] = param; + num_params = strlen(param) == 0 ? 0 : 1; + } + else + { + params[0] = NULL; + proc = action; + num_params = 0; + } + + MakeEvent(widget, &event); + XtCallActionProc(widget, proc, &event, params, num_params); +} + + +/* ARGSUSED */ +static void +DoAction(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + GenericAction(AxeTextDeckTop(PRIVATE(AxeSimpleMenuFetchPopperUpper(XtParent(widget)),ed_deck)), client_data); +} + +static void +AddBitmaps(widget, pixmap) + Widget widget; + Pixmap pixmap; +{ + Pixmap lbitmap, rbitmap; + + XtVaGetValues(widget, + XtNleftBitmap, &lbitmap, + XtNrightBitmap, &rbitmap, + NULL); + + if (!lbitmap) + { + XtVaSetValues(widget, + XtNleftBitmap, pixmap, + NULL); + } + + if (!rbitmap) + { + XtVaSetValues(widget, + XtNrightBitmap, pixmap, + NULL); + } +} + +static void +AddObjectBitmaps(obj, name) + Widget obj; + String name; +{ + Pixmap bitmap; + + if (strcmp(name, "sbtext") == 0) + { + XtVaGetValues(obj, XtNleftBitmap, &bitmap, NULL); + if (!bitmap) + { + XtVaSetValues(obj, + XtNleftBitmap, CLASS(bwdArrow), + NULL); + } + } + else if (strcmp(name, "sftext") == 0) + { + XtVaGetValues(obj, XtNrightBitmap, &bitmap, NULL); + if (!bitmap) + { + XtVaSetValues(obj, + XtNrightBitmap, CLASS(fwdArrow), + NULL); + } + } + else if (strcmp(name, "sbsel") == 0) + { + XtVaGetValues(obj, XtNleftBitmap, &bitmap, NULL); + if (!bitmap) + { + XtVaSetValues(obj, + XtNleftBitmap, CLASS(bwdArrow), + NULL); + } + } + else if (strcmp(name, "sfsel") == 0) + { + XtVaGetValues(obj, XtNrightBitmap, &bitmap, NULL); + if (!bitmap) + { + XtVaSetValues(obj, + XtNrightBitmap, CLASS(fwdArrow), + NULL); + } + } + else if (strcmp(name, "mcentre") == 0) + { + AddBitmaps(obj, CLASS(vtCentre)); + } + else if (strcmp(name, "mhcentr") == 0) + { + AddBitmaps(obj, CLASS(hzCentre)); + } +} + +static void +MakeOneDefaultMenu(menu, menuName) + Widget menu; + String menuName; +{ + Widget obj; + int button; + + for (button = 0; button < XtNumber(buttonActions); ++button) + { + if (!buttonActions[button].action + && strcmp(menuName, buttonActions[button].name) == 0) + { + break; + } + } + + for (button += 1; button < XtNumber(buttonActions); ++button) + { + if (!buttonActions[button].action) + { + break; + } + + obj = XtVaCreateManagedWidget(buttonActions[button].name, + axeSmeBSBObjectClass, menu, NULL); + XtAddCallback(obj, XtNcallback, DoAction, + (XtPointer) buttonActions[button].action); + AddObjectBitmaps(obj, buttonActions[button].name); + } +} + +static void +MakeOneMenu(menu) + Widget menu; +{ + String menuName = XtName(menu); + char resourceName[32]; + String menuList; + XtResource resource; + Cardinal numChildren; + + /* + * We don't know which button is popping up the menu, but we know the + * menu name so we will generate something from that. Thus for menu + * mMove we generate moveMenu and look for a resource moveMenuList. + */ + sprintf(resourceName, "%sMenu", menuName); + resourceName[1] = tolower(resourceName[1]); + + resource.resource_name = &resourceName[1]; + resource.resource_class = "Menu"; + resource.resource_type = XtRString; + resource.resource_size = sizeof(String); + resource.resource_offset = 0; + resource.default_type = XtRString; + resource.default_addr = 0; + + XtVaGetApplicationResources(AxeSimpleMenuFetchPopperUpper(menu), + (XtPointer) &menuList, &resource, 1, NULL); + if (!menuList) + { + MakeOneDefaultMenu(menu, menuName); + } + else + { + FontListStruct *m, *userMenu = ParseFontList(menuList); + int item; + Widget obj; + + for (m = userMenu + 1; m->name; ++m) + { + if (*m->label == '+') + { + MakeOneDefaultMenu(menu, menuName); + continue; + } + + if (*m->label == '|') + { + XtVaCreateManagedWidget("line", smeLineObjectClass, menu, + NULL); + continue; + } + + for (item = 0; item < XtNumber(buttonActions); ++item) + { + if (strcmp(buttonActions[item].name, m->name) == 0) + { + obj = XtVaCreateManagedWidget(buttonActions[item].name, + axeSmeBSBObjectClass, menu, NULL); + XtAddCallback(obj, XtNcallback, DoAction, + (XtPointer) buttonActions[item].action); + AddObjectBitmaps(obj, buttonActions[item].name); + break; + } + } + + } + + XtVaGetValues(menu, XtNnumChildren, &numChildren, NULL); + if (numChildren == 0) + { + char warning[64]; + + sprintf(warning, + "The value of %s is invalid", &resourceName[1]); + XtAppWarning(XtWidgetToApplicationContext(menu), warning); + + /* + * Prevents permature exit if menu popped + */ + XtVaCreateManagedWidget("line", smeLineObjectClass, menu, + NULL); + } + + FreeFontList(XtDisplay(menu), userMenu); + } +} + +/* ARGSUSED */ +static void +Help(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (*num_params) + { + AxeEditorHelpWindow(params[0], CLASS(menu_parent)); + } + else + { + AxeEditorHelpWindow((String) 0, CLASS(menu_parent)); + } +} + +/* ARGSUSED */ +static void +ChooseFont(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + Pixmap leftBitmap; + WidgetList children; + Cardinal numChildren, child, choice; + Widget axeEditor = AxeSimpleMenuFetchPopperUpper(XtParent(widget)); + Widget lastFont; + XFontStruct *fontStruct; + + XtVaGetValues(widget, + XtNleftBitmap, &leftBitmap, + NULL); + + if (leftBitmap) + { + return; + } + + XtVaGetValues(XtParent(widget), + XtNchildren, &children, + XtNnumChildren, &numChildren, + NULL); + + for (child = 0; child < numChildren; ++child) + { + XtVaGetValues(children[child], + XtNleftBitmap, &leftBitmap, + NULL); + + if (leftBitmap) + { + lastFont = children[child]; + } + + if (widget == children[child]) + { + choice = child; + } + } + + if (!(fontStruct = PRIVATE(axeEditor,font_table)[choice].fontStruct)) + { + fontStruct + = PRIVATE(axeEditor,font_table)[choice].fontStruct + = XLoadQueryFont(XtDisplay(axeEditor), + PRIVATE(axeEditor,font_table)[choice].name); + } + + if (fontStruct) + { + XtVaSetValues(lastFont, + XtNleftBitmap, (Pixmap) 0, + NULL); + + XtVaSetValues(widget, + XtNleftBitmap, CLASS(tickMark), + NULL); + + XtVaSetValues(PRIVATE(axeEditor,ed_deck), + XtNfont, fontStruct, + NULL); + } + else + { + UpdateInfoBar(axeEditor, "Invalid font"); + } +} + +static void +FreeFontList(display, list) + Display *display; + FontListStruct *list; +{ + FontListStruct *l; + + for (l = list; l->name; ++l) + { + if (l->name != l->label) + { + XtFree(l->name); + } + XtFree(l->label); + + /* NB We didn't cause creation of the Default entry's XFontStruct */ + if (l != list && l->fontStruct) + { + XFreeFont(display, l->fontStruct); + } + } + XtFree((char *) list); +} + +static FontListStruct* +ParseFontList(fontList) + String fontList; +{ + int n, numberOfFonts, listLen = strlen(fontList); + String i, fontString, parsed, p; + Boolean skipping, quoting; + char quoteChar; + FontListStruct *fontTable; + + for (n = 0, i = fontList, skipping = True, quoting = False; + i < fontList + strlen(fontList); + ++i) + { + if (*i == '"' || *i == '\'') + { + if (quoting && (*i == quoteChar)) + { + quoting = False; + } + else if (!quoting) + { + quoting = True; + quoteChar = *i; + } + } + else if (*i == ' ' || *i == '\t') + { + if (!skipping) + { + ++n; + skipping = !skipping; + } + } + else if (skipping) + { + skipping = !skipping; + } + } + + numberOfFonts = n + 3; /* Default, no trailing space, NULL terminator */ + fontTable + = (FontListStruct *) XtMalloc(numberOfFonts * sizeof(FontListStruct)); + + fontString = (String) XtMalloc(listLen + 2); + strcpy(fontString, fontList); + strcat(fontString, " "); + + fontTable[0].label = XtNewString("Default"); + fontTable[0].name = fontTable[0].label; + parsed = (String) XtMalloc(listLen + 1); + + for (i = fontString, p = parsed, skipping = False, quoting = False, n = 0; + i < fontString + strlen(fontList) + 1; + ++i) + { + if (*i == '"' || *i == '\'') + { + if (quoting && (*i == quoteChar)) + { + quoting = False; + } + else if (!quoting) + { + quoting = True; + quoteChar = *i; + } + } + else if (!quoting && (*i == ' ' || *i == '\t')) + { + if (skipping) + { + *p = '\0'; + if (!fontTable[n].label) + { + fontTable[n].label = parsed; + } + fontTable[n].name = parsed; + fontTable[n].fontStruct = (XFontStruct *) 0; + parsed = (String) XtMalloc(listLen + 1); + p = parsed; + } + skipping = False; + } + else if (!quoting && *i == ':') + { + *p = '\0'; + fontTable[n].label = parsed; + parsed = (String) XtMalloc(listLen + 1); + p = parsed; + } + else + { + *p++ = *i; + if (!skipping) + { + skipping = !skipping; + ++n; + fontTable[n].label = 0; + } + } + } + fontTable[++n].name = (String) 0; + + XtFree(fontString); + XtFree(parsed); + + return fontTable; +} + +static void +MakeFontMenu(menu) + Widget menu; +{ + Widget axeEditor = XtParent(menu); + String fontList; + Widget obj; + FontListStruct *parseFontList, *p; + + XtVaGetValues(XtParent(menu), + XtNfontList, &fontList, + NULL); + + parseFontList = PRIVATE(axeEditor,font_table) = ParseFontList(fontList); + + XtVaGetValues(AxeTextDeckTop(PRIVATE(XtParent(menu),ed_deck)), + XtNfont, &parseFontList[0].fontStruct, + NULL); + + for (p = parseFontList; p->name; ++p) + { + obj = XtVaCreateManagedWidget(p->name, axeSmeBSBObjectClass, menu, + XtNlabel, p->label, + XtNleftBitmap, p == parseFontList ? + CLASS(tickMark) : + (Pixmap) 0, + NULL); + XtAddCallback(obj, XtNcallback, ChooseFont, (XtPointer) 0); + } +} + +/* ARGSUSED */ +static void +NewWindow(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget window + = AxeEditorCreateWindow(widget, CLASS(menu_parent), (String) 0); + + XtPopup(window, XtGrabNone); + + if (*num_params > 0) + { + XtCallActionProc(AxeEditorEdWidget(AxeWindowAxeEditor(window)), + "load-file", + event, (String *) 0, (Cardinal) 0); + } +} + +/* ARGSUSED */ +static void +ForceClose(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + XtDestroyWidget((Widget) client_data); + + RePopulateShowMenu(XtWidgetToApplicationContext(widget)); +} + +static Boolean +WindowClosed(w) + Widget w; +{ + Boolean closed; + + if (w && XtIsSubclass(XtParent(w), axeWindowWidgetClass)) + { + if ( (closed = AxeTextDeckIterate(PRIVATE(w,ed_deck), AxeSafeClose)) ) + { + XtDestroyWidget(w); + } + return closed; + } + else + { + return False; + } +} + +/* ARGSUSED */ +static void +CloseWindow(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorParentOf(widget); + + if (!WindowClosed(axeEditor)) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsaved changes", + "close unsaved", ForceClose, + "unused", NULL, + (XtPointer) axeEditor); + } + { + RePopulateShowMenu(XtWidgetToApplicationContext(widget)); + } +} + +static Boolean +AllWindowsClosed(w) + Widget w; +{ + Boolean result = False; + + if (w && XtIsSubclass(XtParent(w), axeWindowWidgetClass)) + { + result = AxeEditorIterate(AxeSafeClose); + } + return result; +} + +/* ARGSUSED */ +static void +ForceCloseAll(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + AxeEditorIterate(AxeForceClose); + + RePopulateShowMenu(XtWidgetToApplicationContext(widget)); +} + +/* ARGSUSED */ +static void +CloseAll(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor= AxeEditorParentOf(widget); + int editor; + + if (!AllWindowsClosed(axeEditor)) + { + /* NB axeEditor may have been deleted, so find another. */ + /* being_destroyed field is used since only Phase 1 */ + /* of XtDestroyWidget for any windows destroyed will */ + /* have been executed at this juncture. */ + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + axeEditor = EDITORS[editor]; + if (axeEditor && !axeEditor->core.being_destroyed) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsaved changes", + "close unsaved", ForceCloseAll, + "unused", NULL, + (XtPointer) axeEditor); + break; + } + } + } + /* + * This catches the case where the confirmer is necessary but + * the user selects "cancel", but it also means that the menu + * is generated twice if "close unsaved" is chosen - once from + * this call and once from the ForceClassAll callback. + */ + RePopulateShowMenu(XtWidgetToApplicationContext(widget)); +} + +/* ARGSUSED */ +static void +IconifyAll(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Boolean iconifying = (strcmp(params[0], "I") == 0); + Display *display; + Widget shell; + Window window; + int editor; + + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + if (EDITORS[editor]) + { + shell = ShellOf(EDITORS[editor]); + display = XtDisplay(shell); + window = XtWindow(shell); + if (iconifying) + { + XIconifyWindow(display, window, XDefaultScreen(display)); + } + else + { + XMapWindow(display, window); + } + } + } +} + +/* ARGSUSED */ +static void +Restack(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + printf("Restack not implemented\n"); +} + +/* ARGSUSED */ +static void +NewBuffer(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorParentOf(widget), ed; + XFontStruct *font; + char *assocFile, assocDir[MAXPATHLEN]; + + XtVaGetValues(PRIVATE(axeEditor,ed_deck), + XtNfont, &font, + NULL); + + ed = XtVaCreateManagedWidget("ed", axeTextWidgetClass, + PRIVATE(axeEditor,ed_deck), + XtNfont, font, + NULL); + + if ( (assocFile = AxeTextGetAssociatedFile(widget)) ) + { + strcpy(assocDir, assocFile); + assocDir[rindex(assocDir, '/') - assocDir] = '\0'; + XtVaSetValues(ed, XtNassociatedDirectory, assocDir, NULL); + } + + if (*num_params > 0) + { + XtCallActionProc(ed, "load-file", event, (String *) 0, (Cardinal) 0); + } +} + +/* ARGSUSED */ +static void +ForceCloseTopBuffer(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + Widget axeEditor = (Widget) client_data; + + AxeTextDeckCloseTop(PRIVATE(axeEditor,ed_deck)); + + RePopulateShowMenu(XtWidgetToApplicationContext(axeEditor)); +} + +/* ARGSUSED */ +static void +CloseBufferSaved(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + Widget axeEditor = (Widget) client_data; + + if (!AxeTextSaveFile(AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)))) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsavable changes", + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); + } + else + { + ForceCloseTopBuffer((XtPointer) 0, (XtPointer) axeEditor, + (XtPointer) 0); + } +} + +/* ARGSUSED */ +static void +CloseBuffer(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorParentOf(widget); + Widget deck = PRIVATE(axeEditor,ed_deck); + Widget buffer = AxeTextDeckTop(deck); + Cardinal numChildren; + + XtVaGetValues(deck, XtNnumChildren, &numChildren, NULL); + if (numChildren == 1) + { + CloseWindow(widget, event, params, num_params); + + return; + } + + if (AxeTextIsModified(buffer)) + { + if (AxeTextGetAssociatedFile(buffer)) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsaved changes", + "close unsaved", ForceCloseTopBuffer, + "close saved", CloseBufferSaved, + (XtPointer) axeEditor); + + } + else + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsavable changes", + "close unsaved", ForceCloseTopBuffer, + "unused", NULL, + (XtPointer) axeEditor); + } + } + else + { + ForceCloseTopBuffer((XtPointer) 0, (XtPointer) axeEditor, + (XtPointer) 0); + } +} + +static Widget +ShellOf(axeEditor) + Widget axeEditor; +{ + Widget w; + + for (w = XtParent(axeEditor) ;; w = XtParent(w)) + { + if (XtIsShell(w)) + { + break; + } + } + + return w; +} + +/* ARGSUSED */ +static void +RaiseWindow(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + Widget axeEditor = AxeEditorOf((Widget) client_data); + Widget shell = ShellOf(axeEditor); + + AxeTextDeckRaise(PRIVATE(axeEditor,ed_deck), (Widget) client_data); + + XMapRaised(XtDisplay(shell), XtWindow(shell)); +} + +static void +CopyShowMenuChildren(children, numChildren) + WidgetList *children; + Cardinal *numChildren; +{ + WidgetList copyChildren; + Cardinal child; + + XtVaGetValues(CLASS(show_menu), + XtNchildren, ©Children, + XtNnumChildren, numChildren, + NULL); + + *children = (WidgetList) XtMalloc(*numChildren * sizeof(Widget)); + for (child = 0; child < *numChildren; ++child) + { + (*children)[child] = copyChildren[child]; + } +} + +/* ARGSUSED */ +static Boolean +PopulateShowMenu(client_data) + XtPointer client_data; +{ + WidgetList copyChildren; + Cardinal numChildren; + int child, editor, windows, n; + AxeTextDeckList list, lst; + String homeFile; + Pixmap leftBitmap; + Widget obj, line = 0; + AxeEditorWidgetClass wc = (AxeEditorWidgetClass) axeEditorWidgetClass; + + if (!CLASS(show_menu)) + { + return True; + } + + CopyShowMenuChildren(©Children, &numChildren); + + /* + * I'm not sure that I understand this, but if I deleted the old menu + * objects here first, then app crashed with X_ConfigureWindow error, + * although it was fine when this routine was a callback routine that + * was invoked via the triggering of the MenuButton's notify action. + */ + + for (windows = 0, editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + if (EDITORS[editor]) + { + list = AxeTextDeckListOf(PRIVATE(EDITORS[editor],ed_deck)); + for (lst = list; (*lst).file; ++lst) + { + leftBitmap + = AxeTextIsModified((*lst).widget) ? CLASS(modMark) + : (Pixmap) 0; + + homeFile = HomeFile((*lst).file); + obj = XtVaCreateManagedWidget(homeFile, + axeSmeBSBObjectClass, + CLASS(show_menu), + XtNleftBitmap, leftBitmap, + NULL); + XtAddCallback(obj, XtNcallback, RaiseWindow, + (XtPointer) (*lst).widget); + if (homeFile != (*lst).file) + { + XtFree(homeFile); + } + XtFree((char *) (*lst).file); + } + XtFree((char *) list); + + line = XtVaCreateManagedWidget("line", smeLineObjectClass, + CLASS(show_menu), NULL); + ++windows; + } + } + if (line) + { + /* If the menu is non-empty then the last line was one too many */ + XtDestroyWidget(line); + } + else + { + /* Can't have an empty menu so give it a dummy entry */ + XtVaCreateManagedWidget("line", smeLineObjectClass, + CLASS(show_menu), NULL); + } + + /* See comment above */ + for (child = 0; child < numChildren; ++child) + { + XtDestroyWidget(copyChildren[child]); + } + XtFree((char *) copyChildren); + + CLASS(show_work_proc) = False; + + for (n = 0; n < CLASS(show_menu_callbacks); ++n) + { + (*CLASS(show_menu_callback_list)[n].cbr.callback) + (CLASS(show_menu_callback_list)[n].widget, + CLASS(show_menu_callback_list)[n].cbr.closure, + (XtPointer) windows); + } + + return True; +} + +static void +RePopulateShowMenu(app) + XtAppContext app; +{ + if (!CLASS(show_work_proc)) + { + (void) XtAppAddWorkProc(app, PopulateShowMenu, (XtPointer) 0); + + CLASS(show_work_proc) = True; + } +} + +/* ARGSUSED */ +static void +OnShowPopup(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + Widget axeEditor = AxeSimpleMenuFetchPopperUpper(widget); + Widget ed; + WidgetList children; + Cardinal numChildren, child; + XtCallbackList callback; + + if (axeEditor) + { + ed = AxeEditorEdWidget(axeEditor); + } + + XtVaGetValues(CLASS(show_menu), + XtNchildren, &children, + XtNnumChildren, &numChildren, + NULL); + + for (child = 0; child < numChildren; ++child) + { + if (!XtIsSubclass(children[child], axeSmeBSBObjectClass)) + { + continue; + } + + XtVaGetValues(children[child], XtNcallback, &callback, NULL); + XtVaSetValues(children[child], + XtNrightBitmap, + axeEditor ? (((Widget) callback[0].closure == ed) ? + CLASS(tickMark) : (Pixmap) 0) : (Pixmap) 0, + NULL); + } +} + +static void +MakeShowMenu(menu) + Widget menu; +{ + Cardinal numChildren; + + XtAddCallback(menu, XtNpopupCallback, OnShowPopup, (XtPointer) 0); + + XtVaGetValues(menu, XtNnumChildren, &numChildren, NULL); + + if (numChildren == 0) + { + PopulateShowMenu((XtPointer) 0); + } +} + +static Boolean +BuffersSaved(w) + Widget w; +{ + return AxeTextDeckIterate(PRIVATE(w,ed_deck), AxeSave); +} + +/* ARGSUSED */ +static void +SaveAndClose(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorParentOf(widget); + Widget axeText; + int editor; + Cardinal numChildren; + + XtVaGetValues(PRIVATE(axeEditor,ed_deck), + XtNnumChildren, &numChildren, + NULL); + + if (*num_params == 1) + { + if (strcmp(params[0], "window") == 0 + || (strcmp(params[0], "buffer") == 0 && numChildren == 1)) + { + (void) BuffersSaved(axeEditor); + if (!WindowClosed(axeEditor)) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsavable buffers", + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); + } + } + else if (strcmp(params[0], "buffer") == 0) + { + axeText = AxeEditorEdWidget(axeEditor); + if (AxeTextSaveFile(axeText)) + { + XtDestroyWidget(axeText); + } + else + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsavable changes", + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); + } + } + } + else if (*num_params == 0 && !AxeEditorIterate(AxeSaveAndClose)) + { + (void) AxeEditorIterate(AxeSafeClose); + + /* NB axeEditor may have been deleted, so find another. */ + /* being_destroyed field is used since only Phase1 */ + /* of XtDestroyWidget for any windows destroyed will */ + /* have been executed at this juncture. */ + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + axeEditor = EDITORS[editor]; + if (!axeEditor->core.being_destroyed) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsavable buffers", + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); + break; + } + } + } + RePopulateShowMenu(XtWidgetToApplicationContext(widget)); +} + +/* ARGSUSED */ +static void +SaveAll(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorParentOf(widget);; + + if (!AxeEditorIterate(AxeSave)) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsavable buffers", + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); + } + else + { + UpdateInfoBar(axeEditor, "All buffers saved"); + } +} + +static void +MakeLogoMenu(menu) + Widget menu; +{ + XtVaCreateManagedWidget(QVERSION, + axeSmeBSBObjectClass, menu, NULL); + XtVaCreateManagedWidget("by", + axeSmeBSBObjectClass, menu, NULL); + XtVaCreateManagedWidget("Jim Wight", + axeSmeBSBObjectClass, menu, NULL); + XtVaCreateManagedWidget("Department of Computing Science", + axeSmeBSBObjectClass, menu, NULL); + XtVaCreateManagedWidget("University of Newcastle upon Tyne", + axeSmeBSBObjectClass, menu, NULL); + XtVaCreateManagedWidget("", + axeSmeBSBObjectClass, menu, NULL); +} + +static void +MakeMiniSubMenu(menu, menuList) + Widget menu; + FontListStruct *menuList; +{ + char action[80]; + Widget obj; + FontListStruct *p; + + for (p = menuList + 1; p->name; ++p) + { + if (*p->label == '+') + { + if (!CLASS(default_mini_menu)) + { + CLASS(default_mini_menu) = ParseFontList(defaultMiniMenu); + } + MakeMiniSubMenu(menu, CLASS(default_mini_menu)); + continue; + } + + if (*p->label == '|') + { + XtVaCreateManagedWidget("line", smeLineObjectClass, menu, NULL); + continue; + } + + obj = XtVaCreateManagedWidget(p->label, axeSmeBSBObjectClass, menu, + NULL); + + if (strncmp(p->name, "mini-", 5) != 0) + { + sprintf(action, "mini-shell(%s)", p->name); + if (p->name != p->label) + { + XtFree(p->name); + } + p->name = XtNewString(action); + } + XtAddCallback(obj, XtNcallback, DoAction, (XtPointer) p->name); + } +} + +static void +MakeMiniMenu(menu) + Widget menu; +{ + String miniMenuList; + FontListStruct *miniMenu; + static XtResource resource = + {XtNminiMenu, XtCMiniMenu, XtRString, sizeof(String), + (Cardinal) 0, XtRString, defaultMiniMenu}; + + /* + * The miniMenu resource is an application resource, not an AxeEditor + * resource. We do it this way because we can't get a handle onto the + * invoking AxeEditor widget. + */ + XtVaGetApplicationResources(menu, (XtPointer) &miniMenuList, + &resource, 1, + NULL); + + CLASS(mini_menu) = ParseFontList(miniMenuList); + + MakeMiniSubMenu(menu, CLASS(mini_menu)); +} + +/* ARGSUSED */ +static void +ButtonAction(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + GenericAction(AxeEditorEdWidget(AxeEditorParentOf(widget)), client_data); +} + +static void +MakeButtons(parent, buttonList) + Widget parent; + FontListStruct *buttonList; +{ + FontListStruct *p; + Widget butt; + int len, button; + + if (PRIVATE(XtParent(parent),button_list)) + { + for (p = buttonList + 1; p->name; ++p) + { + if (*(p->name) == '-' || *(p->name) == ';') + { + continue; + } + else if (p->name[(len = strlen(p->name)) - 1] == ';') + { + len -= 1; + } + + for (button = 0; button < XtNumber(buttonActions); ++button) + { + if (strncmp(buttonActions[button].name, p->name, len) == 0) + { + butt = XtVaCreateManagedWidget(buttonActions[button].name, + axeCommandWidgetClass, parent, NULL); + + XtAddCallback(butt, XtNcallback, ButtonAction, + (XtPointer) buttonActions[button].action); + break; + } + } + + if (button >= XtNumber(buttonActions)) + { + printf("Invalid button name %s in buttonList\n", p->name); + } + } + } + else + { + for (button = 0; button < XtNumber(buttonActions); ++button) + { + if (buttonActions[button].action) + { + butt = XtVaCreateManagedWidget(buttonActions[button].name, + axeCommandWidgetClass, parent, NULL); + + XtAddCallback(butt, XtNcallback, ButtonAction, + (XtPointer) buttonActions[button].action); + } + } + } +} + +static String +ButtonListLayout(widget, menuButtonsLayout, list) + Widget widget; + char *menuButtonsLayout; + FontListStruct **list; +{ + String buttonLayout = (String) XtMalloc(strlen(menuButtonsLayout) + + strlen(commandButtonsLayout) + 1); + FontListStruct + *buttonList = ParseFontList(PRIVATE(widget,button_list)), *p; + + int col = 0, row = 1, len; + Boolean newRow = False; + char buf[16]; + + strcpy(buttonLayout, menuButtonsLayout); + for (p = buttonList + 1; p->name; ++p) + { + if (*(p->name) == '-' ) + { + ++col; + continue; + } + else if (*(p->name) == ';') + { + ++row; + col = 0; + continue; + } + else if (p->name[(len = strlen(p->name)) - 1] == ';') + { + strncat(buttonLayout, p->name, len - 1); + newRow = True; + } + else + { + strcat(buttonLayout, p->name); + } + sprintf(buf, " %d %d wW;", col, row); + strcat(buttonLayout, buf); + if (newRow) + { + ++row; + col = 0; + newRow = False; + } + else + { + ++col; + } + } + + *list = buttonList; + return buttonLayout; +} + +static XpTableLoc +MakeButtonsLayout(widget, buttonList) + Widget widget; + FontListStruct **buttonList; +{ + String layoutString; + XpTableLoc tableLoc; + Boolean toFree = True; + FontListStruct + *menuList = ParseFontList(PRIVATE(widget,menu_list)), *p; + char menuButtonsLayout[1024]; + char *mbl; + int n, m; + Boolean axeLogoSeen = False, matched; + + menuButtonsLayout[0] = '\0'; + mbl = menuButtonsLayout; + for (n = 0, p = menuList + 1; p->name; ++p, ++n) + { + matched = False; + for (m = 0; chosenMenus[m].name; ++m) + { + if (strcmp(p->name, chosenMenus[m].name) == 0) + { + chosenMenus[m].chosen = True; + matched = True; + sprintf(mbl, "%sMenu %d 0 wW; ", p->name, n); + mbl += strlen(mbl); + break; + } + } + if (!matched && strcmp(p->name, "logo") == 0) + { + axeLogoSeen = True; + sprintf(mbl, "axeLogo %d 0 1 8; ", n); + mbl += strlen(mbl); + } + } + if (!axeLogoSeen) + { + sprintf(mbl, "axeLogo %d 0 1 8; ", n); + } + + if (PRIVATE(widget,button_list)) + { + layoutString = ButtonListLayout(widget, menuButtonsLayout, buttonList); + } + else if (PRIVATE(widget,buttons)) + { + layoutString = (String) XtMalloc(strlen(menuButtonsLayout) + + strlen(commandButtonsLayout) + 1); + strcpy(layoutString, menuButtonsLayout); + strcat(layoutString, commandButtonsLayout); + } + else + { + layoutString = menuButtonsLayout; + toFree = False; + } + + tableLoc = XpTableLocParse(layoutString); + + if (toFree) + { + XtFree(layoutString); + } + FreeFontList(XtDisplay(widget), menuList); + + return tableLoc; +} + +/************************************************************* + * + * utilities + * + *************************************************************/ + +static Widget +AxeEditorOf(widget) + Widget widget; +{ + Widget w; + + for (w = widget; w; w = XtParent(w)) + { + if (XtIsSubclass(w, axeEditorWidgetClass)) + { + return w; + } + } + + return (Widget) 0; +} + +static void +UpdateFileName(aew, file) + Widget aew; + String file; +{ + if (PRIVATE(aew,suppressFilename)) + { + return; + } + + XtVaSetValues(PRIVATE(aew,file_name), XtNlabel, file, NULL); +} + + +static void +UpdateTitles(aew) + Widget aew; +{ + Widget top = AxeTextDeckTop(PRIVATE(aew,ed_deck)); + String file, fileName, homeFile; + Boolean freeFile = False; + + if (!(file = AxeTextGetAssociatedFile(top))) + { + file = XtNewString(noname); + freeFile = True; + } + + homeFile = HomeFile(file); + fileName = XtMalloc(strlen(homeFile) + 2 + 1); + *fileName = '\0'; + if (AxeTextIsModified(top)) + { + strcat(fileName, "* "); + } + strcat(fileName, homeFile); + + UpdateFileName(aew, fileName); + XtCallCallbackList(aew, PRIVATE(aew,change_callbacks), + (XtPointer) fileName); + XtFree(fileName); + if (homeFile != file) + { + XtFree(homeFile); + } + if (freeFile) + { + XtFree(file); + } +} + +/*ARGSUSED*/ +static void +InfoBarTimeout(client_data, id) + XtPointer client_data; + XtIntervalId *id; +{ + Widget axeEditor = (Widget) client_data; + + PRIVATE(axeEditor,info_timer) = (XtIntervalId) 0; + + XtVaSetValues(PRIVATE(axeEditor,info_bar), + XtNlabel, QVERSION, + NULL); +} + +/* ARGSUSED */ +static void +UpdateInfo(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + UpdateInfoBar(AxeEditorOf(w), params[0]); +} + +static void +UpdateInfoBar(w, info) + Widget w; + String info; +{ + if (PRIVATE(w,suppressInfobar)) + { + return; + } + + if (PRIVATE(w,info_timer)) + { + XtRemoveTimeOut(PRIVATE(w,info_timer)); + } + + XtVaSetValues(PRIVATE(w,info_bar), + XtNlabel, info ? info : QVERSION, + NULL); + + if (PRIVATE(w,info_timeout)) + { + PRIVATE(w,info_timer) = + XtAppAddTimeOut(XtWidgetToApplicationContext(w), + (unsigned long) PRIVATE(w,info_timeout) * 1000, + InfoBarTimeout, (XtPointer) w); + } +} + +static Atom +AxeisUserAtom(display) + Display *display; +{ + char propName[1024], *user; + + strcpy(propName, "AXE_AXINFO"); + + if ( (user = getenv("USER")) ) + { + strcat(propName, "_"); + strcat(propName, user); + } + + return XInternAtom(display, propName, False); +} + +/************************************************************* + * + * Minibuffer + * + *************************************************************/ + +/* Caller must free return value */ +static String +CurrentDir(w) + Widget w; +{ + Widget axeEditor = AxeEditorOf(w); + String assocFile, dir, filePart; + + if (assocFile + = AxeTextGetAssociatedFile(AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)))) + { + dir = XtNewString(assocFile); + filePart = rindex(dir, '/'); + if (filePart) + { + *(filePart + 1) = '\0'; + } + return dir; + } + else + { + return XtNewString(CLASS(current_dir)); + } +} + +/* NB Caller must free return value if different from input */ +static String +HomeFile(file) + String file; +{ + String new; + + if (strlen(file) > CLASS(home_dir_len) + && strncmp(file, CLASS(home_dir), CLASS(home_dir_len)) == 0) + { + new = XtMalloc(strlen(file) + 3); + strcpy(new, "~"); + strcat(new, &file[CLASS(home_dir_len)]); + return new; + } + + return file; +} + +static void +MiniDisplayCaret(w, On) + Widget w; + Boolean On; +{ + XtVaSetValues(PRIVATE(AxeEditorOf(w),mini_buffer), + XtNdisplayCaret, On, + NULL); +} + +static void +MiniEnable(w, prompt) + Widget w; + String prompt; +{ + Widget axeEditor = AxeEditorOf(w); + + if (!PRIVATE(axeEditor,suppressMinibuffer)) + { + Widget input = PRIVATE(axeEditor,mini_buffer); + + XtVaSetValues(input, + XtNdisplayCaret, True, + XtNstring, prompt, + NULL); + + XawTextSetInsertionPoint(input, strlen(prompt)); + } +} + +static XawTextPosition +MiniAppend(w, text) + Widget w; + String text; +{ + XawTextBlock textBlock; + XawTextPosition textPos, textRtn; + Widget input = PRIVATE(AxeEditorOf(w),mini_buffer); + + textPos = XawTextGetInsertionPoint(input); + textBlock.firstPos = 0; + textBlock.length = strlen(text); + textBlock.ptr = text; + textBlock.format = FMT8BIT; + if ((textRtn = XawTextReplace(input, textPos, textPos, &textBlock)) + == XawEditDone) + { + XawTextSetInsertionPoint(input, textPos + textBlock.length); + } + + return textRtn; +} + +static void +MiniInstallAccelerators(w) + Widget w; +{ + Widget axeEditor = AxeEditorOf(w); + + if (!PRIVATE(axeEditor,suppressMinibuffer)) + { + XtVaSetValues(w, + XtNdisplayCaret, False, + NULL); + + XtInstallAccelerators(w, PRIVATE(axeEditor,mini_buffer)); + + PRIVATE(axeEditor,accelerateMini) = True; + } +} + +static void +MiniUninstallAccelerators(w) + Widget w; +{ + Widget axeEditor = AxeEditorOf(w); + + if (!PRIVATE(axeEditor,suppressMinibuffer)) + { + XtVaSetValues(AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)), + XtNtranslations, + PRIVATE(axeEditor,defaultTextTranslations), + XtNdisplayCaret, True, + NULL); + + XtVaSetValues(PRIVATE(axeEditor,mini_buffer), + XtNdisplayCaret, False, + NULL); + + PRIVATE(axeEditor,accelerateMini) = False; + } +} + +static void +MiniInitInput(w) + Widget w; +{ + String dir = CurrentDir(w); + String home = HomeFile(dir); + + (void) MiniAppend(w, home); + + if (home != dir) + { + XtFree(home); + } + XtFree(dir); +} + +static String +MiniInput(w, skip) + Widget w; + Boolean skip; +{ + String input, p; + + XtVaGetValues(PRIVATE(AxeEditorOf(w),mini_buffer), + XtNstring, &input, + NULL); + + for (p = input + strlen(input) - 1; p >= input; --p) + { + if (*p != ' ' && *p != '\t') + { + break; + } + else + { + *p = 0; + } + } + + if (skip) + { + for (p = &input[1]; *p == ' '; ++p) {} + return p; + } + else + { + return input; + } +} + +/*ARGSUSED*/ +static void +miniSelect(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + MiniDisplayCaret(w, True); + MiniInstallAccelerators(w); + } +} + +/*ARGSUSED*/ +static void +miniClear(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + MiniEnable(w, ""); + MiniInstallAccelerators(w); + } +} + +/*ARGSUSED*/ +static void +miniSearch(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + if (*num_params > 0 && (strcmp(params[0], "backward") == 0)) + { + MiniEnable(w, "?"); + } + else + { + MiniEnable(w, "/"); + } + MiniInstallAccelerators(w); + } +} + +static void +MiniSearch(w, searchDirection) + Widget w; + XawTextScanDirection searchDirection; +{ + Widget text = AxeTextDeckTop(PRIVATE(AxeEditorOf(w),ed_deck)); + regexp *compexp; + String nomatch, regexpr = MiniInput(w, False); + XawTextPosition nobegin, noend; + Boolean found; + + compexp = 0; + if (compexp = regcomp(®expr[1])) + { + nomatch = 0; + found = AxeiiTextReSearch(text, (searchDirection == XawsdRight), + ®expr[1], compexp, &nomatch, + &nobegin, &noend); + if (!RegError && !found) + { + UpdateInfoBar(AxeEditorOf(w), "Search string not found"); + } + + XtFree(nomatch); + } + + if (RegError) + { + UpdateInfoBar(AxeEditorOf(w), RegError); + XBell(XtDisplay(w), 100); + RegError = 0; + } + + XtFree((char *) compexp); +} + +static void +MiniGoto(w) + Widget w; +{ + AxeTextGotoLine(AxeTextDeckTop(PRIVATE(AxeEditorOf(w),ed_deck)), + atoi(MiniInput(w, False))); +} + +/*ARGSUSED*/ +static void +miniInsert(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + MiniEnable(w, "r "); + MiniInitInput(w); + MiniInstallAccelerators(w); + } +} + +static void +MiniInsert(w) + Widget w; +{ + Widget axeEditor = AxeEditorOf(w); + Widget axe = AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)); + String insertFile = AxeEditorExpandName(MiniInput(w, True)); + Boolean undo; + void (*proc)(); + + XtVaGetValues(axe, XtNundo, &undo, NULL); + + if ( (proc = AxeiiTextUndoPreInsert(axe)) ) + { + (*proc)(axe); + } + + if (!InsertFileNamed(axe, insertFile)) + { + UpdateInfoBar(axeEditor, "Error inserting file"); + XBell(XtDisplay(w), 100); + } + + XtFree(insertFile); +} + +/*ARGSUSED*/ +static void +miniSaveAs(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + MiniEnable(w, "w "); + MiniInitInput(w); + MiniInstallAccelerators(w); + } +} + +static void +MiniSaveAs(w) + Widget w; +{ + Widget axeEditor = AxeEditorOf(w); + String saveAs = AxeEditorExpandName(MiniInput(w, True)); + FileNominatorStruct fnomStruct; + + AxeTextFileToNominatorStruct(saveAs, &fnomStruct); + + if (!fnomStruct.directoryPart) + { + UpdateInfoBar(axeEditor, "Invalid pathname"); + XBell(XtDisplay(w), 100); + } + else if (!fnomStruct.filenamePart) + { + UpdateInfoBar(axeEditor, "Pathname is a directory"); + XBell(XtDisplay(w), 100); + } + else + { + (void) AxeTextSaveAsFile(AxeEditorEdWidget(axeEditor), &fnomStruct); + } + + XtFree(saveAs); + + AxeTextFreeNominatorStruct(&fnomStruct); +} + +/*ARGSUSED*/ +static void +miniLoad(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + MiniEnable(w, "e "); + MiniInitInput(w); + MiniInstallAccelerators(w); + } +} + +/* ARGSUSED */ +static void +MiniForceLoad(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + Widget mini = (Widget) client_data; + Widget axeEditor = AxeEditorOf(mini); + String loadFile; + FileNominatorStruct fnomStruct; + loadFile = AxeEditorExpandName(MiniInput(mini, True)); + + AxeTextFileToNominatorStruct(loadFile, &fnomStruct); + + if (!fnomStruct.directoryPart) + { + UpdateInfoBar(axeEditor, "Invalid pathname"); + XBell(XtDisplay(mini), 100); + } + else if (!fnomStruct.filenamePart) + { + UpdateInfoBar(axeEditor, "Pathname is a directory"); + XBell(XtDisplay(mini), 100); + } + else + { + AxeTextLoadFile(AxeEditorEdWidget(axeEditor), &fnomStruct); + } + + XtFree(loadFile); + + AxeTextFreeNominatorStruct(&fnomStruct); +} + +static void +MiniLoad(w) + Widget w; +{ + Widget axeEditor = AxeEditorOf(w); + + if (AxeTextIsModified(AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)))) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "There are unsaved changes", + "Discard changes", MiniForceLoad, + "unused", NULL, + (XtPointer) w); + } + else + { + MiniForceLoad((XtPointer) 0, (XtPointer) w, (XtPointer) 0); + } +} + +static void +MiniPipeOrShell(w, cmd, params, num_params) + Widget w; + String cmd, *params; + Cardinal *num_params; +{ + int i, len; + char param[80]; + Boolean commit = False; + + if (!PRIVATE(AxeEditorOf(w),suppressMinibuffer)) + { + MiniEnable(w, cmd); + + for (i = 0; i < *num_params; ++i) + { + if (i == (*num_params) - 1 && (len = strlen(params[i])) >= 1 && + params[i][len - 1] == '\n') + { + strcpy(param, params[i]); + param[len - 1] = '\0'; + MiniAppend(w, param); + commit = True; + } + else + { + MiniAppend(w, params[i]); + MiniAppend(w, " "); + } + } + + MiniInstallAccelerators(w); + + if (commit) + { + MiniCommit(w, (XEvent *) 0, (String *) 0, (Cardinal *) 0); + } + } +} + +/*ARGSUSED*/ +static void +miniPipe(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + MiniPipeOrShell(w, "| ", params, num_params); +} + +static void +ClosePipes(output, input, errput) + int *output, *input, *errput; +{ + if (output[0] != -1) close(output[0]); + if (output[1] != -1) close(output[1]); + if (input[0] != -1) close(input[0]); + if (input[1] != -1) close(input[1]); + if (errput[0] != -1) close(errput[0]); + if (errput[1] != -1) close(errput[1]); +} + +static Boolean +ExecSubProcess(widget, command, output, input, errput) + Widget widget; + String command; + int *output, *input, *errput; +{ + output[0] = output[1] = input[0] = input[1] = errput[0] = errput[1] = -1; + + if (pipe(output) == -1 || pipe(input) == -1 || pipe(errput) == -1) + { + ClosePipes(output, input, errput); + return False; + } + + switch(fork()) + { + case -1: + ClosePipes(output, input, errput); + return False; + case 0: /* Child */ + (void) close(XConnectionNumber(XtDisplay(widget))); + if (close(0) == 0 && + dup(output[0]) == 0 && + close(output[0]) == 0 && + close(output[1]) == 0 && + close(1) == 0 && + dup(input[1]) == 1 && + close(input[0]) == 0 && + close(input[1]) == 0 && + close(2) == 0 && + dup(errput[1]) == 2 && + close(errput[0]) == 0 && + close(errput[1]) == 0) + { + char *assocFile, assocDir[MAXPATHLEN]; + + + if ( (assocFile = AxeTextGetAssociatedFile(widget)) ) + { + strcpy(assocDir, assocFile); + assocDir[rindex(assocDir, '/') - assocDir] = '\0'; + + (void) chdir(assocDir); + } + (void) execl("/bin/sh", "sh", "-c", command, (char *) 0); + } + ClosePipes(output, input, errput); + exit(0); + default: /* Parent */ + if (close(output[0]) == -1 || + close(input[1]) == -1 || + close(errput[1]) == -1) + { + ClosePipes(output, input, errput); + return False; + } + } + + return True; +} + +static void +ChildInput(client_data, source, id) + XtPointer client_data; + int *source; + XtInputId *id; +{ + struct childInfo *ci = (struct childInfo*) client_data; + char buffer[1024]; + int nread; + XawTextBlock block; + XawTextPosition pos; + void (*proc)(); + + nread = read(*source, buffer, sizeof(buffer)); + + if (nread == -1) + { + UpdateInfoBar(AxeEditorOf(ci->ed), + "Output from command is possibly incomplete"); + XBell(XtDisplay(ci->ed), 100); + } + + if (nread == 0 || nread == -1) + { + if (!ci->first && !ci->replace) + { + XtVaSetValues(ci->ed, XtNinsertPosition, 0, NULL); + XtPopup(ci->window, XtGrabNone); + } + else if (ci->replace && (ci->selStart != ci->selEnd)) + { + XawTextSetSelection(ci->ed, ci->selStart, + XawTextGetInsertionPoint(ci->ed)); + } + + XtRemoveInput(*id); + close(*source); + XtFree((char *) ci); + wait((int *) 0); + } + else + { + block.firstPos = 0; + block.length = nread; + block.ptr = buffer; + block.format = FMT8BIT; + + if (ci->first) + { + char first[2]; + String f = first, *ff = &f; + + ci->first = False; + if (ci->replace) + { + XawTextBlock notext; + + notext.firstPos = 0; + notext.length = 0; + notext.ptr = 0; + notext.format = FMT8BIT; + XawTextSetInsertionPoint(ci->ed, ci->selStart); + if (ci->selStart != ci->selEnd) + { + if ( (proc = AxeiiTextUndoPreReplace(ci->ed)) ) + { + (*proc)(ci->ed); + } + } + else + { + if ( (proc = AxeiiTextUndoPreInsert(ci->ed)) ) + { + (*proc)(ci->ed); + } + } + (void) XawTextReplace(ci->ed, ci->selStart, ci->selEnd, ¬ext); + /* + * This shouldn't be necessary, but for some reason the + * insertion point is incorrect following the replace. + */ + XawTextSetInsertionPoint(ci->ed, ci->selStart); + } + else + { + ci->window = AxeEditorCreateWindow(ci->ed, CLASS(menu_parent), + (String) 0); + ci->ed = AxeEditorEdWidget(AxeWindowAxeEditor(ci->window)); + XtRealizeWidget(ci->window); + /* + * Silly kludge to get round problem of caret behaving oddly + * if text is inserted into empty widget using XawTextReplace + */ + first[0] = buffer[0]; + first[1] = '\0'; + XtCallActionProc(ci->ed, "insert-string", (XEvent *) 0, + ff, (Cardinal) 1); + + block.firstPos = 1; + block.length = nread - 1; + } + } + + pos = XawTextGetInsertionPoint(ci->ed); + if (XawTextReplace(ci->ed, pos, pos, &block) != XawEditDone) + { + UpdateInfoBar(AxeEditorOf(ci->ed), "Text insertion failure"); + } + else + { + XawTextSetInsertionPoint(ci->ed, pos + block.length); + } + } +} + +static void +MiniPopen(w, replace) + Widget w; + Boolean replace; +{ + + Widget axeEditor = AxeEditorOf(w); + Widget text = AxeTextDeckTop(PRIVATE(axeEditor,ed_deck)); + Widget asciiSrc; + XawTextPosition selStart, selEnd, from; + XawTextBlock textBlock; + Cursor busyCursor = 0, menuCursor, textCursor, miniCursor; + int length, toread, piece; + int tochild[2], fromchild[2], errchild[2]; + struct childInfo *ci, *ce; + + /* + * The selection or the entire buffer is fed to the command in the + * minibuffer. The output from the command replaces the selection or + * is inserted into the buffer if replace is True (| - mini-pipe), + * otherwise it is inserted into a new window (! - mini-shell). Nothing + * happens if there is no standard output from the command. Error output + * is popped up in a separate standard aXe window. + */ + + if (!ExecSubProcess(text, MiniInput(w, True), tochild, fromchild, errchild)) + { + UpdateInfoBar(axeEditor, "Unable to execute command"); + XBell(XtDisplay(w), 100); + return; + } + + asciiSrc = XawTextGetSource(text); + XtVaGetValues(asciiSrc, XtNpieceSize, &piece, NULL); + XawTextGetSelectionPos(text, &selStart, &selEnd); + + if ((length = selEnd - selStart) == 0) + { + if (replace) + { + selStart = XawTextGetInsertionPoint(text); + selEnd = selStart; + } + else + { + selStart = selEnd = 0; + length = piece; + } + } + + XtVaGetValues(PRIVATE(axeEditor,menu_bar), XtNcursor, &menuCursor, NULL); + XtVaGetValues(text, XtNcursor, &textCursor, NULL); + XtVaGetValues(PRIVATE(axeEditor,mini_buffer), XtNcursor, &miniCursor, NULL); + + busyCursor = XCreateFontCursor(XtDisplay(axeEditor), XC_watch); + + XtVaSetValues(PRIVATE(axeEditor,menu_bar), XtNcursor, busyCursor, NULL); + XtVaSetValues(text, XtNcursor, busyCursor, NULL); + XtVaSetValues(PRIVATE(axeEditor,mini_buffer), XtNcursor, busyCursor, NULL); + + XFlush(XtDisplay(axeEditor)); + + ci = XtNew(struct childInfo); + ci->first = True; + ci->replace = replace; + ci->ed = text; + ci->window = 0; + ci->selStart = selStart; + ci->selEnd = selEnd; + (void) XtAppAddInput(XtWidgetToApplicationContext(w), fromchild[0], + (XtPointer) XtInputReadMask, ChildInput, + (XtPointer) ci); + + ce = XtNew(struct childInfo); + ce->first = True; + ce->replace = False; + ce->ed = text; + ce->window = 0; + ce->selStart = 0; /* Not used */ + ce->selEnd = 0; /* Not used */ + (void) XtAppAddInput(XtWidgetToApplicationContext(w), errchild[0], + (XtPointer) XtInputReadMask, ChildInput, + (XtPointer) ce); + + signal(SIGPIPE, SIG_IGN); + textBlock.format = FMT8BIT; + for(toread = length, from = selStart; + toread > 0; + toread = (selEnd != selStart ? toread - textBlock.length : piece), + from = from + textBlock.length) + { + (void) XawTextSourceRead(asciiSrc, from, &textBlock, toread); + if (textBlock.length == 0) + { + break; + } + if (write(tochild[1], textBlock.ptr, textBlock.length) == -1) + { + UpdateInfoBar(axeEditor, "Pipe output error"); + XBell(XtDisplay(w), 100); + break; + } + } + close(tochild[1]); + signal(SIGPIPE, SIG_DFL); + + if (busyCursor) + { + XtVaSetValues(PRIVATE(axeEditor,menu_bar), XtNcursor, menuCursor,NULL); + XtVaSetValues(text, XtNcursor, textCursor, NULL); + XtVaSetValues(PRIVATE(axeEditor,mini_buffer), XtNcursor, miniCursor, NULL); + } +} + +#ifdef EXTENSION +/*ARGSUSED*/ +static int +MiniInterp(w) + Widget w; +{ +#if TCL_MAJOR_VERSION < 7 + return Tcl_Eval(interpreter.interp, MiniInput(w, False), 0, NULL); +#else + return Tcl_Eval(interpreter.interp, MiniInput(w, False)); +#endif +} +#endif + +/*ARGSUSED*/ +static void +miniShell(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + MiniPipeOrShell(w, "! ", params, num_params); +} + +/*ARGSUSED*/ +static void +miniStuff(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + MiniPipeOrShell(w, "", params, num_params); +} + +/*ARGSUSED*/ +static void +miniAbort(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorOf(w); + + if (!PRIVATE(axeEditor,suppressMinibuffer)) + { + UpdateInfoBar(axeEditor, "Minibuffer abort"); + XBell(XtDisplay(w), 100); + + if (PRIVATE(axeEditor,accelerateMini)) + { + MiniUninstallAccelerators(w); + } + } +} + +/*ARGSUSED*/ +static void +TrapWarningMsgss(name, type, class, defaultp, params, num_params) + String name, type, class, defaultp, *params; + Cardinal *num_params; +{ + validAction = False; +} + +/*ARGSUSED*/ +static void +TrapWarnings(message) + String message; +{ + validAction = False; +} + +/*ARGSUSED*/ +static void +MiniCommit(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorOf(w); + String input; + char command; + Boolean done; + + XtVaGetValues(PRIVATE(axeEditor,mini_buffer), + XtNstring, &input, + NULL); + + command = input[0]; + switch (command) + { + case '/': + MiniSearch(w, XawsdRight); + break; + case '?': + MiniSearch(w, XawsdLeft); + break; + case '|': + MiniPopen(w, True); + break; + case '!': + MiniPopen(w, False); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + MiniGoto(w); + break; + case 'r': + case 'R': + case 'w': + case 'W': + case 'e': + case 'E': + done = False; + if (input[1] == ' ') + { + switch (input[0]) + { + case 'r': + case 'R': + MiniInsert(w); + done = True; + break; + case 'w': + case 'W': + MiniSaveAs(w); + done = True; + break; + case 'e': + case 'E': + MiniLoad(w); + done = True; + break; + default: + break; + } + } + if (done) + { + break; + } + else + { + /* Drop-though; not r|w|e; try action or Tcl command */ + } + default: + { + XtAppContext app = XtWidgetToApplicationContext(w); + + XtErrorMsgHandler oldWarningMsgHandler = + XtAppSetWarningMsgHandler(app, TrapWarningMsgss); + XtErrorHandler oldWarningHandler = + XtAppSetWarningHandler(app, TrapWarnings); + + validAction = True; + GenericAction(AxeEditorEdWidget(axeEditor), + (XtPointer) MiniInput(w, False)); + + XtAppSetWarningMsgHandler(app, oldWarningMsgHandler); + XtAppSetWarningHandler(app, oldWarningHandler); + if (validAction) + { + break; + } + } +#ifdef EXTENSION + if (MiniInterp(w) == TCL_OK) + { + break; + } + else + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + interpreter.interp->result, + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); +#else + if (True) + { + ConfirmerRequestConfirmation(PRIVATE(axeEditor,confirmer), + "Invalid command", + "acknowledge", ConfirmerPopdown, + "unused", NULL, + (XtPointer) axeEditor); +#endif + command = '$'; + break; + } + } + + switch (command) + { + case '/': + case '?': + case '$': + break; + default: + if (PRIVATE(axeEditor,accelerateMini)) + { + MiniUninstallAccelerators(w); + } + } +} + +/*ARGSUSED*/ +static void +MiniLeave(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (!PRIVATE(AxeEditorOf(w),accelerateMini)) + { + MiniDisplayCaret(w, False); + } +} + +/************************************************************* + * + * Keyboard Macro + * + *************************************************************/ + +static void +AddToMacro(w, client_data, action_name, event, params, num_params) + Widget w; + XtPointer client_data; + String action_name; + XEvent *event; + String *params; + Cardinal *num_params; +{ + char buffer[MAXSTRLEN + 1]; + int bytes; + + if (w != (Widget) client_data) + { + return; + } + + if (strcmp(action_name, "insert-char") == 0) + { + bytes = XLookupString((XKeyEvent *) event, buffer, MAXSTRLEN, + (KeySym *) 0, (XComposeStatus *) 0); + if (bytes != 0) + { + buffer[bytes] = '\0'; + if (!CLASS(in_macro_string)) + { + CLASS(macro_commands)[CLASS(macro_size)].name + = XrmStringToQuark("insert-string"); + CLASS(macro_commands)[CLASS(macro_size)].numArgs = 1; + CLASS(macro_commands)[CLASS(macro_size)].arg + = (String) XtMalloc(bytes + 1); + strncpy(CLASS(macro_commands)[CLASS(macro_size)].arg, + buffer, bytes + 1); + CLASS(in_macro_string) = True; + } + else + { + CLASS(macro_commands)[CLASS(macro_size)].arg + = (String) XtRealloc(CLASS(macro_commands)[CLASS(macro_size)].arg, + strlen(CLASS(macro_commands)[CLASS(macro_size)].arg) + bytes + 1); + strncat(CLASS(macro_commands)[CLASS(macro_size)].arg, buffer, bytes); + } + } + } + else + { + if (CLASS(in_macro_string)) + { + ++CLASS(macro_size); + CLASS(in_macro_string) = False; + } + CLASS(macro_commands)[CLASS(macro_size)].name + = XrmStringToQuark(action_name); + CLASS(macro_commands)[CLASS(macro_size)].numArgs + = (*num_params) ? 1 : 0; + if (*num_params != 0) + { + CLASS(macro_commands)[CLASS(macro_size)].arg + = XtNewString(params[0]); + } + else + { + CLASS(macro_commands)[CLASS(macro_size)].arg = NULL; + } + ++CLASS(macro_size); + } + + if (CLASS(macro_size) == CLASS(max_macro_size)) + { + CLASS(max_macro_size) += CHUNK; + CLASS(macro_commands) + = (MacroList) XtRealloc((char *) CLASS(macro_commands), + CLASS(max_macro_size) * sizeof(MacroCommand)); + } +} + +/*ARGSUSED*/ +static void +startMacro(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorOf(w); + int m; + + if (!CLASS(macro_id)) + { + CLASS(macro_id) = XtAppAddActionHook(XtWidgetToApplicationContext(w), + AddToMacro, (XtPointer) w); + UpdateInfoBar(axeEditor, "Defining keyboard macro"); + + if (CLASS(macro_size) == 0) + { + CLASS(macro_commands) + = (MacroList) XtMalloc(CHUNK * sizeof(MacroCommand)); + CLASS(max_macro_size) = CHUNK; + } + else + { + for (m = 0; m < CLASS(macro_size); ++m) + { + if (CLASS(macro_commands)[m].numArgs != 0) + { + XtFree(CLASS(macro_commands)[m].arg); + } + } + CLASS(macro_size) = 0; + } + CLASS(in_macro_string) = False; + } + else + { + UpdateInfoBar(axeEditor, "Already defining keyboard macro"); + XBell(XtDisplay(w), 100); + } +} + +/*ARGSUSED*/ +static void +endMacro(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorOf(w); + + if (CLASS(macro_id)) + { + --CLASS(macro_size); /* removes end-macro itself */ + XtRemoveActionHook(CLASS(macro_id)); + CLASS(macro_id) = (XtActionHookId) 0; + UpdateInfoBar(axeEditor, "Keyboard macro defined"); + } + else + { + UpdateInfoBar(axeEditor, "Not defining keyboard macro"); + XBell(XtDisplay(w), 100); + } +} + +static void +ExecMacro(w, event) + Widget w; + XEvent *event; +{ + int c; + + for (c = 0; c < CLASS(macro_size); ++c) + { + XtCallActionProc(w, + XrmQuarkToString(CLASS(macro_commands)[c].name), + event, &CLASS(macro_commands)[c].arg, + CLASS(macro_commands)[c].numArgs); + } +} + +/*ARGSUSED*/ +static void +execMacro(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (CLASS(macro_size) == 0) + { + UpdateInfoBar(AxeEditorOf(w), "No macro defined"); + XBell(XtDisplay(w), 100); + return; + } + + ExecMacro(w, event); +} + +/*ARGSUSED*/ +static void +repeatMacro(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Widget axeEditor = AxeEditorOf(w); + int repeat, repeats, times; + + if (CLASS(macro_size) == 0) + { + UpdateInfoBar(axeEditor, "No macro defined"); + XBell(XtDisplay(w), 100); + return; + } + + if (*num_params > 0) + { + repeats = atoi(params[0]); + } + else + { + if (!PRIVATE(axeEditor,suppressMinibuffer)) + { + repeats = ((times = atoi(MiniInput(w, False))) == 0) ? 1 : times; + } + else + { + repeats = 1; + } + } + + for (repeat = 1; repeat <= repeats; ++repeat) + { + ExecMacro(w, event); + } +} + +/************************************************************* + * + * Semi-public functions + * + *************************************************************/ + +/* + * This routine is made public for the benefit of AxeTextDeck, but it is + * not advertised as such in AxeEditor.h. If there are multiple files it + * is easier to do the expansions after splitting in AxeTextDeck. + * + * NB caller must free returned string + */ +String +AxeEditorExpandName(name) + String name; +{ + String expandedName; + + if (name[0] == '~') + { + expandedName = XtMalloc(CLASS(home_dir_len) + strlen(name) + 1); + strcpy(expandedName, CLASS(home_dir)); + strcat(expandedName, "/"); + strcat(expandedName, &name[2]); + } +#ifdef __apollo + else if (strncmp (name, "`node_data", 10) == 0) + { + expandedName = XtNewString(name); + } +#endif + else if (name[0] == '/') + { + expandedName = XtNewString(name); + } + else + { + expandedName = XtMalloc(CLASS(current_dir_len) + strlen(name) + 1); + strcpy(expandedName, CLASS(current_dir)); + strcat(expandedName, name); + } + + return expandedName; +} + +/************************************************************* + * + * Public functions + * + *************************************************************/ + +int +AxeEditorNextEditor() +{ + int editor; + + /* + AxeWindows are named according to the slot number of the child + AxeEditor. But the AxeWindow has to be created, and hence named, + before the AxeEditor is created. This makes sure a correct slot + number is returned in the first case + */ + XtInitializeWidgetClass(axeEditorWidgetClass); + + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + if (!EDITORS[editor]) + { + break; + } + } + + return editor; +} + +Widget +AxeEditorParentOf(widget) + Widget widget; +{ + Widget axeEditor; + + for (axeEditor = XtParent(widget); + axeEditor; + axeEditor = XtParent(axeEditor)) + { + if (XtIsSubclass(axeEditor, axeEditorWidgetClass)) + { + break; + } + } + return axeEditor; +} + +Widget +AxeEditorFileNameWidget(w) + Widget w; +{ + return (XtIsSubclass(w, axeEditorWidgetClass)) ? PRIVATE(w,file_name) + : (Widget) 0; +} + +Widget +AxeEditorInfoBarWidget(w) + Widget w; +{ + return (XtIsSubclass(w, axeEditorWidgetClass)) ? PRIVATE(w,info_bar) + : (Widget) 0; +} + +Widget +AxeEditorMenuBarWidget(w) + Widget w; +{ + return (XtIsSubclass(w, axeEditorWidgetClass)) ? PRIVATE(w,menu_bar) + : (Widget) 0; +} + +Widget +AxeEditorEdWidget(w) + Widget w; +{ + return (XtIsSubclass(w, axeEditorWidgetClass)) + ? AxeTextDeckTop(PRIVATE(w,ed_deck)) : (Widget) 0; +} + +Widget +AxeEditorMiniBufferWidget(w) + Widget w; +{ + return (XtIsSubclass(w, axeEditorWidgetClass)) ? PRIVATE(w,mini_buffer) + : (Widget) 0; +} + +void +AxeEditorUpdateInfoBar(w, info) + Widget w; + String info; +{ + if (w && XtIsSubclass(w, axeEditorWidgetClass)) + { + UpdateInfoBar(w, info); + } +} + +Boolean +AxeEditorIterate(iterator) + AxeIterationType iterator; +{ + Widget axeEditor; + int editor; + Boolean result = True; + + XtInitializeWidgetClass(axeEditorWidgetClass); + + for (editor = 0; editor < NUMBEROFEDITORS; ++editor) + { + axeEditor = EDITORS[editor]; + + if (!axeEditor) + { + continue; + } + + switch (iterator) + { + case AxeSafeClose: + result &= WindowClosed(axeEditor); + break; + case AxeForceClose: + XtDestroyWidget(axeEditor); + break; + case AxeSave: + result &= BuffersSaved(axeEditor); + break; + case AxeSaveAndClose: + (void) BuffersSaved(axeEditor); + result &= WindowClosed(axeEditor); + break; + default: + ; + } + } + + return result; +} + +Widget +AxeEditorCreateWindow(widget, parent, file) + Widget widget; + Widget parent; + String file; +{ + Widget window, deck; + char name[3], assocDir[MAXPATHLEN], *assocFile; + + RePopulateShowMenu(XtWidgetToApplicationContext(parent)); + + sprintf(name, "%02d", AxeEditorNextEditor()); + window = XtVaCreatePopupShell(name, axeWindowWidgetClass, parent, + XtNfile, file, + NULL); + + if (XtIsSubclass(widget, axeTextWidgetClass)) + { + if ( (assocFile = AxeTextGetAssociatedFile(widget)) ) + { + strcpy(assocDir, assocFile); + assocDir[rindex(assocDir, '/') - assocDir] = '\0'; + } + + deck = PRIVATE(AxeWindowAxeEditor(window),ed_deck); + AxeTextDeckSetAssociatedDirectory (deck, + assocFile ? assocDir : assocFile); + } + + return window; +} + +static XtResource appResource[] = +{ + { "display", "Display", XtRString, sizeof(String), + (Cardinal) 0, XtRImmediate, (XtPointer) 0 + } +}; + +void +AxeEditorHelpWindow(helpName, parent) + String helpName; + Widget parent; +{ + Atom reqAtom = XA_WINDOW, gotAtom; + int gotFormat; + unsigned long gotItems, moreBytes; + unsigned char *propValue; + Display *display = XtDisplay(parent); + Window propWindow; + char command[1024], property; + Boolean startAxinfo = True; + String dpy; + + /* + * Check if axinfo is already running. First look to + * see if expected root window property is present. + */ + if (XGetWindowProperty(display, + XDefaultRootWindow(display), + AxeisUserAtom(display), + 0, 1, + False, + reqAtom, + &gotAtom, + &gotFormat, + &gotItems, + &moreBytes, + &propValue) == Success) + { + /* + * The property does exist. The window that is the value of the + * property should have the AXE_AXINFO_user property attached. + */ + if (gotAtom == reqAtom) + { + propWindow = *((Window *) propValue); + XFree((char *) propValue); + + TrapErrors(display); + + if (XGetWindowProperty(display, + propWindow, + AxeisUserAtom(display), + 0, 0, + False, + XA_STRING, + &gotAtom, + &gotFormat, + &gotItems, + &moreBytes, + &propValue) == Success) + { + if (gotAtom == None) + { + xerror = BadAtom; + } + XFree((char *) propValue); + } + + DontTrapErrors(display); + + /* + * The window id from the root window property seems to be OK. + * So go ahead and notify it by changing its AXE_AXINFO property + * with the tag of the node that is to be displayed. If that + * succeeds then the work is done. + */ + if (xerror == Success) + { + TrapErrors(display); + + XChangeProperty(display, + propWindow, + XInternAtom(display, "AXE_AXINFO", False), + XA_STRING, + 8, + PropModeReplace, + (unsigned char *) helpName, + strlen(helpName)); + + if (xerror == Success) + { + startAxinfo = False; + } + + DontTrapErrors(display); + } + } + } + + if (startAxinfo) + { + XtVaGetApplicationResources(parent, (XtPointer) &dpy, + appResource, (Cardinal) 1, + NULL); + if (dpy) + { + sprintf(command, "axinfo -node %s -display %s &", + (helpName ? helpName : "Top"), dpy); + } + else + { + sprintf(command, + "axinfo -node %s &",(helpName ? helpName : "Top")); + } + system(command); + } +} + +void +AxeEditorAddShowMenuCallback(widget, proc, client_data) + Widget widget; + XtCallbackProc proc; + XtPointer client_data; +{ + AxeEditorWidgetClass wc; + int n; + + XtInitializeWidgetClass(axeEditorWidgetClass); + + wc = (AxeEditorWidgetClass) axeEditorWidgetClass; + n = ++CLASS(show_menu_callbacks); + + CLASS(show_menu_callback_list) = (ShowMenuList) + XtRealloc((char *) CLASS(show_menu_callback_list), + (Cardinal) (n * sizeof(ShowMenuRec))); + + CLASS(show_menu_callback_list)[n - 1].widget = widget; + CLASS(show_menu_callback_list)[n - 1].cbr.callback = proc; + CLASS(show_menu_callback_list)[n - 1].cbr.closure = client_data; +} + +#undef PRIVATE +#undef CLASS + +#undef MAXEDITORS +#undef NUMBEROFEDITORS +#undef EDITORS --- axe-6.1.2.orig/Widgets/AxeTextDeck.c +++ axe-6.1.2/Widgets/AxeTextDeck.c @@ -177,7 +177,11 @@ } else { - expandedName = theFile; + /* H. S. Teoh: don't pass NULL to XtVaCreateManagedWidget; + * for some reason, it gets mangled and AxeText.c:Initialize() + * gets a garbage filename. + */ + expandedName = XtNewString(""); } XtVaCreateManagedWidget("ed", axeTextWidgetClass, new, --- axe-6.1.2.orig/Widgets/AxeWindow.c +++ axe-6.1.2/Widgets/AxeWindow.c @@ -27,6 +27,7 @@ * University of Newcastle upon Tyne, UK */ +#include #include #include #include --- axe-6.1.2.orig/Widgets/AxeiiText.c +++ axe-6.1.2/Widgets/AxeiiText.c @@ -35,7 +35,7 @@ #include #include #include -#include "AxeiiSink.h" +/* #include "AxeiiSink.h" */ #include "AxeiiTextP.h" #include "AxeiiUndo.h" #include "regexp.h" @@ -319,20 +319,25 @@ { XtVaSetValues(new, XtNtextSink, - XtVaCreateWidget("axeiisink", - axeiiSinkObjectClass, + XtVaCreateWidget("asciisink", + asciiSinkObjectClass, new, - XtNcursorBitmap, atw->axeii.caret_bitmap, + XtNcursorName, atw->axeii.caret_bitmap, NULL), NULL); } else if (atw->axeii.block_caret) { XtVaSetValues(new, + XtNtextSink, XtVaCreateWidget("asciisink", + asciiSinkObjectClass, new, + NULL), +/* XtNtextSink, XtVaCreateWidget("axeiisink", axeiiSinkObjectClass, new, XtNblockCursor, True, NULL), + */ NULL); } --- axe-6.1.2.orig/Widgets/CtrlCodeSel.h +++ axe-6.1.2/Widgets/CtrlCodeSel.h @@ -40,7 +40,9 @@ #define XtNbase "base" #define XtCBase "Base" #define XtNenterCallback "enterCallback" +/* H. S. Teoh: redundant re-definition of libXt symbol #define XtNcancelCallback "cancelCallback" +*/ #endif /* _ControlCodeSelector_h */ --- axe-6.1.2.orig/Widgets/FileNom.c +++ axe-6.1.2/Widgets/FileNom.c @@ -392,12 +392,17 @@ String dir; Dimension width, height; +/* H. S. Teoh: don't use getwd(); always use getcwd(). This should be OK + * since we're assuming a libc6+ environment. #if defined(SYSV) || defined(SVR4) +*/ extern char *getcwd(); #define getwd(buf) getcwd(buf,MAXPATHLEN) +/* #else extern char *getwd(); #endif +*/ List(new) = NULL; Nomination(new).directoryPart = NULL; --- axe-6.1.2.orig/Widgets/FileNom.h +++ axe-6.1.2/Widgets/FileNom.h @@ -33,7 +33,9 @@ #define XtNinitialDirectory "initialDirectory" #define XtNselectCallback "selectCallback" #define XtNpathList "pathList" +/* H. S. Teoh: redundant redefinition of libXt symbol #define XtNcancelCallback "cancelCallback" +*/ #define XtNmargin "margin" #define XtNnumberRows "numberRows" #define XtNshowDotFiles "showDotFiles" --- axe-6.1.2.orig/Widgets/Imakefile +++ axe-6.1.2/Widgets/Imakefile @@ -4,7 +4,7 @@ SRCS = ${TABLE_SRCS} ${EXTN_SRCS} \ AxeWindow.c AxeEditor.c AxeMenuBtn.c AxeSimMenu.c \ AxeSmeBSB.c AxeCommand.c AxeTextDeck.c AxeText.c \ - AxeiiText.c AxeiiUndo.c AxeiiSink.c \ + AxeiiText.c AxeiiUndo.c /* AxeiiSink.c */ \ FileNomWin.c FileNom.c ${R5ONLY_SRCS} ${R4ONLY_SRCS} ScrollText.c \ NumericPad.c CtrlCodeSel.c Preference.c Confirmer.c \ ${SCANDIR_SRCS} regexp.c insertfile.c match.c util.c @@ -12,7 +12,7 @@ OBJS = ${TABLE_OBJS} ${EXTN_OBJS} \ AxeWindow.o AxeEditor.o AxeMenuBtn.o AxeSimMenu.o \ AxeSmeBSB.o AxeTextDeck.o AxeCommand.o AxeText.o \ - AxeiiText.o AxeiiUndo.o AxeiiSink.o \ + AxeiiText.o AxeiiUndo.o /* AxeiiSink.o */ \ FileNomWin.o FileNom.o ${R5ONLY_OBJS} ${R4ONLY_OBJS} ScrollText.o \ NumericPad.o CtrlCodeSel.o Preference.o Confirmer.o \ ${SCANDIR_OBJS} regexp.o insertfile.o match.o util.o @@ -23,7 +23,7 @@ * EXTN_INCLUDES to ensure that the local regexp.h is used rather than * the one provided by Tcl, or any other. */ -EXTRA_INCLUDES = ${TABLE_INCLUDES} -I. -I.. ${EXTN_INCLUDES} ${XAW3D_INCLUDES} +EXTRA_INCLUDES = -g3 ${TABLE_INCLUDES} -I. -I.. ${EXTN_INCLUDES} ${XAW3D_INCLUDES} NormalLibraryObjectRule() NormalLibraryTarget(axe,$(OBJS)) --- axe-6.1.2.orig/Widgets/NumericPad.h +++ axe-6.1.2/Widgets/NumericPad.h @@ -47,7 +47,9 @@ #define XtNbase "base" #define XtCBase "Base" #define XtNenterCallback "enterCallback" +/* H. S. Teoh: redundant re-definition of libXt symbol #define XtNcancelCallback "cancelCallback" +*/ extern void NumericPadClear(); --- axe-6.1.2.orig/Widgets/Preference.h +++ axe-6.1.2/Widgets/Preference.h @@ -47,6 +47,8 @@ } PreferenceReturnStruct; #define XtNenterCallback "enterCallback" +/* H. S. Teoh: redundant redefinition of libXt symbol #define XtNcancelCallback "cancelCallback" +*/ #endif /* _Preference_h */ --- axe-6.1.2.orig/Widgets/ScrollText.c +++ axe-6.1.2/Widgets/ScrollText.c @@ -222,6 +222,11 @@ strcmp(action, "beginning-of-line") == 0 || strcmp(action, "end-of-line") == 0) { +/* H. S. Teoh: the new Xaw (XF86 4.0.1+) already has a sensible way to handle + * long inputs; we don't need to use AdjustForChange() any more. + * (Besides, it doesn't work properly with the new Xaw.) + */ +#if 0 /* * Positioning with the mouse results in work_proc being corrupted with * the result that the test fails and scrolling stops happening. I don't @@ -236,9 +241,17 @@ XtAppAddWorkProc(XtWidgetToApplicationContext(widget), AfterAction, (XtPointer) widget); /* } */ +#endif /* 0 */ + } } +/* H. S. Teoh: the new Xaw (XF86 4.0.1+) already has a sensible way to handle + * long inputs; we don't need to use AdjustForChange() any more. + * (Besides, it doesn't work properly with the new Xaw.) + */ +#if 0 + static Boolean AfterAction(client_data) XtPointer client_data; @@ -253,12 +266,21 @@ return True; } +#endif /* 0 */ + /* ARGSUSED */ static void AdjustForChange(widget, client_data, call_data) Widget widget; XtPointer client_data, call_data; { + + /* H. S. Teoh: the new Xaw (XF86 4.0.1+) already has a sensible way to handle + * long inputs; we don't need to use AdjustForChange() any more. + * (Besides, it doesn't work properly with the new Xaw.) + */ +#if 0 + Widget source, sink, text = XtParent(widget), porthole = XtParent(text); Position x, prevx, top; Dimension lm, width, phwidth, fwidth = PRIVATE(porthole,font_width); @@ -297,8 +319,11 @@ /* Stretch widget to eliminate solid block at end of line */ width = ed + fwidth; - + XtVaSetValues(text, XtNx, x, XtNwidth, width, NULL); + +#endif /* 0 */ + } #undef PRIVATE --- axe-6.1.2.orig/Widgets/regexp.c +++ axe-6.1.2/Widgets/regexp.c @@ -28,6 +28,7 @@ * regular-expression syntax might require a total rethink. */ #include +#include #include "regexp.h" #include "regmagic.h" @@ -199,7 +200,6 @@ register char *longest; register int len; int flags; - extern char *malloc(); if (exp == NULL) FAIL("NULL argument"); --- axe-6.1.2.orig/axe.c +++ axe-6.1.2/axe.c @@ -75,6 +75,7 @@ #include #include #include +#include #ifdef EXTENSION #include "Language.h" @@ -397,6 +398,7 @@ String nameList = 0; XrmDatabase db; + XtSetLanguageProc(NULL, NULL, NULL); top = XtVaAppInitialize(&app, "Axe", options, XtNumber(options), #if defined(XtSpecificationRelease) && XtSpecificationRelease > 4 --- axe-6.1.2.orig/axe.c.ORIG +++ axe-6.1.2/axe.c.ORIG @@ -0,0 +1,646 @@ +/* + * Copyright 1992 The University of Newcastle upon Tyne + * + * Permission to use, copy, modify and distribute this software and its + * documentation for any purpose other than its commercial exploitation + * is hereby granted without fee, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of The University of Newcastle upon Tyne not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The University of + * Newcastle upon Tyne makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF NEWCASTLE UPON TYNE DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * NEWCASTLE UPON TYNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Wight (j.k.wight@newcastle.ac.uk) + * Department of Computing Science + * University of Newcastle upon Tyne, UK + */ + +/* + * The aXe Server Mode Implementation + * + * o aXe creates a server window and writes its ID as the value of the + * AXE_SERVER property for the host and user running aXe on the default root + * window, where the server window is the window of a widget that listens for + * AXE_COAXE, AXE_FAXE and AXE_POLEAXE property changes. The AXE_SERVER + * property name for a host and user is AXE_SERVER__ + * + * o A client on some host wishing to be served reads the root window's + * AXE_SERVER__ property and writes the file, or files, to be + * edited and the ID of a window to be notified when editing has been + * completed as the value of the AXE_COAXE, AXE_FAXE or AXE_POLEAXE property + * of the server window. + * + * o The ID of the window to be notified is stored as the value of the + * AXE_COAXE property on the aXe window that is created for the client. A + * client writes the AXE_FAXE property if it does not wait to be notified, in + * which case no property is stored on the aXe window. A client writes the + * AXE_POLEAXE property in order to terminate the server. + * + * o There is no guarantee that the values of the root window's + * AXE_SERVER__ properties will be valid when read - aXe may + * have been terminated without the corresponding property being deleted and + * the window ID may even have been re-allocated in the meantime - so it is + * stamped with the AXE_SERVER__ property to enable a + * validity check to be carried out by the client. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef EXTENSION +#include "Language.h" +#endif + +#include "util.h" + +/* R4 concession */ +#ifndef XPointer +#define XPointer caddr_t +#endif + +#define QUIT "QuitQuitQuitQuitQui" + +typedef struct _ResourceRec +{ + String version; + int windows; + Boolean server; + Boolean fileServer; + String geometry; +} ResourceRec, *ResourceRecPtr; + +static void AxeQuit(), AxeService(); + +static XtActionsRec actions[] = { + "axe-quit", AxeQuit, + "axe-service", AxeService, +}; + +static char translations[] = "\ + : axe-quit() \n\ + AXE_COAXE: axe-service(AXE_COAXE) \n\ + AXE_FAXE: axe-service(AXE_FAXE) \n\ + AXE_POLEAXE:axe-service(AXE_POLEAXE)"; + +/*ARGSUSED*/ +static void +AxeQuit(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (event->xclient.message_type == XA_STRING && + strncmp(event->xclient.data.b, QUIT, 20) == 0) + { + exit(0); + } +} + +/*ARGSUSED*/ +static void +AxeService(widget, event, params, num_params) + Widget widget; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Display *display = XtDisplay(widget); + long propLen = 3; + Atom gotAtom; + int gotFormat; + unsigned long gotItems, moreBytes; + unsigned char *propValue; + char *p; + int windows; + Window wid; + Widget newWindow; + WidgetList axeEditor; + + if (strcmp(params[0], AXE_POLEAXE) == 0) + { + /*AxeExit(); Destroys remaining windows and notifies waiting coaxes */ + /* StopServer(display); Wipes out AXE_SERVER_ property */ + exit(0); + } + + /* + * Do an initial read to get the window ID and calculate out how + * much there is left to be read in rounded up 32-bit chunks + */ + if (XGetWindowProperty(display, + XtWindow(widget), + XInternAtom(display, params[0], False), + 0, propLen, + False, + XA_STRING, + &gotAtom, + &gotFormat, + &gotItems, + &moreBytes, + &propValue) == Success) + { + if (gotAtom == XA_STRING) + { + sscanf((char *) propValue, "%12d", &wid); + propLen = (moreBytes + 4) / 4; + XtFree((char *) propValue); + } + } + + /* Read the remainder - the filename part - of the property */ + if (XGetWindowProperty(display, + XtWindow(widget), + XInternAtom(display, params[0], False), + (long) 3, propLen, + False, + XA_STRING, + &gotAtom, + &gotFormat, + &gotItems, + &moreBytes, + &propValue) == Success) + { + if (gotAtom == XA_STRING) + { + for (p = (char *) propValue, windows = 0; + strlen(p) != 0 || (strlen(p) == 0 && windows == 0); + p += strlen(p) + 1, ++windows) + { + newWindow = AxeEditorCreateWindow(widget, XtParent(widget), p); + + XtRealizeWidget(newWindow); + + if (strcmp(params[0], AXE_COAXE) == 0) + { + XtVaGetValues(newWindow, XtNchildren, &axeEditor, NULL); + XChangeProperty(display, + XtWindow(AxeEditorEdWidget(axeEditor[0])), + XInternAtom(display, params[0], False), + XA_WINDOW, + 32, + PropModeReplace, + (unsigned char *) &wid, + 1); + } + + XtPopup(newWindow, XtGrabNone); + } + } + XtFree((char *) propValue); + } +} + +/* ARGSUSED */ +static void +NewWindow(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XtPopup(AxeEditorCreateWindow((Widget) client_data, (Widget) client_data, + (String) call_data), XtGrabNone); +} + +static void +Select(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + FileNominatorStruct *data = (FileNominatorStruct *) call_data; + char filename[MAXPATHLEN]; + + if (data->directoryPart && data->filenamePart + && (data->filenameStatus & FileNominatorReadable)) + { + strcpy(filename, data->directoryPart); + strcat(filename, data->filenamePart); + + NewWindow(widget, client_data, (XtPointer) filename); + } + else + { + XBell(XtDisplay(widget), 100); + return; + } +} + +/*ARGSUSED*/ +static void +ShowMenuChange(widget, client_data, call_data) + Widget widget; + XtPointer client_data, call_data; +{ + XtVaSetValues(widget, + XtNsensitive, (int) call_data ? True : False, + NULL); +} + +/*ARGSUSED */ +static void +Poleaxe(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + exit(0); +} + +static void +DelayQuit(widget) + Widget widget; +{ + /* + * Send a client message to the server window advising that Quit has been + * invoked. The reason for delaying the Quit like this is so that coaxes + * waiting for notification really get notified. Notification is carried + * in the Destroy method of the AxeText widgets that are closed in the + * Quit callback. As Destroy does not get called until the callback has + * completed we can't call exit as early as the callback. + */ + + XClientMessageEvent clientEvent; + + clientEvent.type = ClientMessage; + clientEvent.display = XtDisplay(widget); + clientEvent.window = XtWindow(widget); + clientEvent.message_type = XA_STRING; + clientEvent.format = 8; + strncpy(clientEvent.data.b, QUIT, 20); + + XSendEvent(XtDisplay(widget), XtWindow(widget), + False, NoEventMask, (XEvent *) &clientEvent); +} + +/* ARGSUSED */ +static void +ReallyQuit(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + AxeEditorIterate(AxeForceClose); + + DelayQuit((Widget) client_data); +} + +/* ARGSUSED */ +static void +Quit(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + static Widget confirmer = (Widget) 0; + + if (!AxeEditorIterate(AxeSafeClose)) + { + if (!confirmer) + { + confirmer + = XtVaCreatePopupShell("confirmer", confirmerWidgetClass, + (Widget) client_data, NULL); + } + + ConfirmerRequestConfirmation(confirmer, + "There are unsaved changes", + "Quit anyway", ReallyQuit, + "unused", NULL, + client_data); + } + else + { + DelayQuit((Widget) client_data); + } +} + +/* ARGSUSED */ +static void +Help(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + AxeEditorHelpWindow("Axeis", (Widget) client_data); +} + +static XrmOptionDescRec options[] = { + {"-buttons", "*buttons", XrmoptionNoArg, (XPointer) "True"}, + {"-blinkPeriod", "*blinkPeriod", XrmoptionSepArg, (XPointer) NULL}, + {"-fileTitle", "*fileTitle", XrmoptionNoArg, (XPointer) "True"}, + {"-infoTimeout", "*infoTimeout", XrmoptionSepArg, (XPointer) NULL}, + {"-miniBuffer", "*suppressMinibuffer", XrmoptionNoArg, + (XPointer) "False"}, + {"-noserver", ".server", XrmoptionNoArg, (XPointer) "False"}, + {"-windows", ".windows", XrmoptionSepArg, (XPointer) NULL}, +}; + +static XtResource resources[] = +{ + { "version", "Version", XtRString, sizeof(String), + XtOffset(ResourceRecPtr, version), XtRImmediate, (XtPointer) 0 + }, + { "geometry", "Geometry", XtRString, sizeof(String), + XtOffset(ResourceRecPtr, geometry), XtRImmediate, (XtPointer) 0 + }, + { "server", "Server", XtRBoolean, sizeof(Boolean), + XtOffset(ResourceRecPtr, server), XtRImmediate, (XtPointer) True + }, + { "fileServer", "Server", XtRBoolean, sizeof(Boolean), + XtOffset(ResourceRecPtr, fileServer), XtRImmediate, (XtPointer) False + }, + { "windows", "Windows", XtRInt, sizeof(int), + XtOffset(ResourceRecPtr, windows), XtRImmediate, (XtPointer) 0 + }, +}; + +main(argc, argv) + int argc; + char **argv; +{ + XtAppContext app; + Widget top, noapps, msg, server, fnom, table, waiter, poleaxe, help; + Widget show = 0; + Window serverWindow; + Display *display; + ResourceRec res; + int parse, x, y; + unsigned int width, height; + char resource[MAXPATHLEN]; + Pixel fg, bg; + int arg, argmost; + Boolean buffering, newWindow; + String nameList = 0; + XrmDatabase db; + + top = XtVaAppInitialize(&app, "Axe", + options, XtNumber(options), +#if defined(XtSpecificationRelease) && XtSpecificationRelease > 4 + &argc, +#else + (Cardinal *) &argc, +#endif + argv, + NULL, NULL); + display = XtDisplay(top); + db = XtDatabase(display); + + XtAppAddActions(app, actions, XtNumber(actions)); + + XtVaGetApplicationResources(top, (XtPointer) &res, + resources, XtNumber(resources), + NULL); + + if (!res.version || strcmp(res.version, QVERSION) != 0) + { + char message[1024]; + + strcpy(message, "This is "); + strcat(message, QVERSION); + strcat(message, ".\n\n"); + strcat(message, "The application defaults file\n"); + strcat(message, "for this release has not been\n"); + strcat(message, "found."); + + if (res.version) + { + strcat(message, "\n\nIt may help to know in solving\n"); + strcat(message, "the problem that the defaults\n"); + strcat(message, "file for "); + strcat(message, res.version); + strcat(message, " was found."); + } + + noapps = XtVaCreateManagedWidget("noapps", formWidgetClass, top, NULL); + + msg = XtVaCreateManagedWidget("msg", labelWidgetClass, noapps, + XtNlabel, message, + NULL); + + poleaxe = XtVaCreateManagedWidget("Quit", commandWidgetClass, noapps, + XtNfromVert, msg, + NULL); + XtAddCallback(poleaxe, XtNcallback, Poleaxe, (XtPointer) 0); + + XtRealizeWidget(top); + XtAppMainLoop(app); + } + + if (res.geometry) + { + parse = XParseGeometry(res.geometry, &x, &y, &width, &height); + if (parse & WidthValue) + { + sprintf(resource, "*AxeText*columns:%d", width); + XrmPutLineResource(&db, resource); + } + if (parse & HeightValue) + { + sprintf(resource, "*AxeText*rows:%d", height); + XrmPutLineResource(&db, resource); + } + } + + if (res.fileServer) + { + server = XtVaCreatePopupShell("fileServer", + fileNominatorWindowWidgetClass, + top, NULL); + + fnom = FileNominatorWindowFileNominatorWidget(server); + XtAddCallback(fnom, XtNselectCallback, Select, (XtPointer) top); + XtAddCallback(fnom, XtNcancelCallback, Quit, (XtPointer) server); + res.server = True; + } + else if (res.server) + { + server = XtVaCreatePopupShell("server", topLevelShellWidgetClass, + top, NULL); + + table = XtVaCreateManagedWidget("table", xpTableWidgetClass, server, + XtNshrinkSimple, False, + NULL); + + waiter = XtVaCreateManagedWidget("waiter", commandWidgetClass, table, + NULL); + XtAddCallback(waiter, XtNcallback, NewWindow, (XtPointer) top); + + XtVaGetValues(waiter, + XtNforeground, &fg, + XtNbackground, &bg, + NULL); + + XtVaSetValues(waiter, + XtNbackgroundPixmap, + XCreatePixmapFromBitmapData(display, XDefaultRootWindow(display), (char *) axeLogo_bits, axeLogo_width, axeLogo_height, fg, bg, XDefaultDepthOfScreen(XtScreen(waiter))), + NULL); + + show = XtVaCreateManagedWidget("show", axeMenuButtonWidgetClass, table, + XtNsensitive, False, + NULL); + AxeEditorAddShowMenuCallback(show, ShowMenuChange, (XtPointer) 0); + + poleaxe = XtVaCreateManagedWidget("poleaxe", commandWidgetClass, table, + NULL); + XtAddCallback(poleaxe, XtNcallback, Quit, (XtPointer) server); + + help + = XtVaCreateManagedWidget("help", commandWidgetClass, table, NULL); + XtAddCallback(help, XtNcallback, Help, (XtPointer) top); + } + + if (res.server) + { + XtOverrideTranslations(server, XtParseTranslationTable(translations)); + + XtRealizeWidget(server); + serverWindow = XtWindow(server); + + TrapErrors(display); + + /* If there is already a server running this one will replace it */ + XChangeProperty(display, + XDefaultRootWindow(display), + HostUserServerAtom(display), + XA_WINDOW, + 32, + PropModeReplace, + (unsigned char *) &serverWindow, + 1); + + if (xerror == Success) + { + XChangeProperty(display, + serverWindow, + HostUserServerAtom(display), + XA_STRING, + 32, + PropModeReplace, + NULL, + 0); + } + + DontTrapErrors(display); + } + else + { + XrmPutLineResource(&db, "*ExitOnCloseLastWindow:True"); + } + +#ifdef EXTENSION + interpreter.Initialize(top); +#endif + + argmost = (res.windows) ? res.windows : (res.server ? 0 : 1); + for (buffering = False, arg = 1; arg < argc; ++arg) + { + if (strncmp(argv[arg], "-buffer", strlen(argv[arg])) == 0) + { + buffering = True; + } + + if (buffering) + { + --argmost; + } + } + + if (argc == 1 && !res.server) + { + for (arg = 1; arg <= argmost; ++arg) + { + NewWindow((XtPointer) 0, (XtPointer) top, (XtPointer) 0); + } + } + else + { + for (arg = argc - 1; arg < argmost; ++arg) + { + NewWindow((XtPointer) 0, (XtPointer) top, (XtPointer) 0); + } + + for (buffering = False, newWindow = True, arg = 1; arg < argc; ++arg) + { + if (strncmp(argv[arg], "-buffer", strlen(argv[arg])) == 0) + { + buffering = True; + newWindow = True; + if (nameList) + { + NewWindow((XtPointer) 0, (XtPointer) top, + (XtPointer) nameList); + XtFree(nameList); + nameList = 0; + } + continue; + } + + if (buffering) + { + if (newWindow) + { + nameList = XtMalloc((unsigned) (strlen(argv[arg]) + 1)); + strcpy(nameList, argv[arg]); + newWindow = False; + } + else + { + int len = strlen(nameList); + + nameList + = XtRealloc(nameList, + (unsigned) (len + 1 + strlen(argv[arg]) + 1)); + nameList[len] = ' '; + strcpy(&nameList[len + 1], argv[arg]); + } + } + else + { + NewWindow((XtPointer) 0, (XtPointer) top, + (XtPointer) argv[arg]); + } + } + if (nameList) + { + NewWindow((XtPointer) 0, (XtPointer) top, (XtPointer) nameList); + XtFree(nameList); + } + } + + if (res.server) + { + int argc; + String *argv; + + XtVaGetValues(top, XtNargc, &argc, XtNargv, &argv, NULL); + XSetCommand(display, XtWindow(server), argv, argc); + + XtPopup(server, XtGrabNone); + } + + XtAppMainLoop(app); +} --- axe-6.1.2.orig/axe.man +++ axe-6.1.2/axe.man @@ -1,4 +1,4 @@ -.TH AXE 1 "January 1994" "aXe Release 6.0" +.TH AXE 1x "January 1994" "aXe Release 6.0" .SH NAME aXe - an X editor .SH SYNOPSIS --- axe-6.1.2.orig/coaxe.c +++ axe-6.1.2/coaxe.c @@ -27,6 +27,7 @@ * University of Newcastle upon Tyne, UK */ +#include #include #include #include @@ -34,11 +35,13 @@ #include extern int errno; #ifndef __BSD_4_4__ +#if !defined(__GLIBC__) || __GLIBC__ < 2 extern char *sys_errlist[]; #endif +#endif #include extern char *getenv(); -extern char *malloc(), *realloc(); +extern void *malloc(), *realloc(); #include "util.h" @@ -114,12 +117,16 @@ Window window; XEvent event; +/* H. S. Teoh: always use getcwd(); getwd() is unsafe #if defined(SYSV) || defined(SVR4) +*/ extern char *getcwd(); #define getwd(a) getcwd(a,MAXPATHLEN) +/* #else extern char *getwd(); #endif +*/ r = (r = rindex(argv[0], '/')) ? ++r : argv[0]; coaxe = strncmp(r, "coaxe", 5) == 0; --- axe-6.1.2.orig/debian/README.Debian +++ axe-6.1.2/debian/README.Debian @@ -0,0 +1,14 @@ +aXe Debian notes ++--------------+ + +axinfo has been patched by the Debian maintainer to be able to read +gzip compressed .info files. + +axinfo accepts only one directory in which to search for info files, +and you won't be able to see the info documentation in other places +without modifying the infoPath resource. For example: + +axinfo -xrm '*infoPath:/usr/info' gdb.info + +Default info search path was set to /usr/share/info, as that is where +most info docs reside today. --- axe-6.1.2.orig/debian/axe.prerm.i386 +++ axe-6.1.2/debian/axe.prerm.i386 @@ -0,0 +1,5 @@ +#!/bin/sh +# dummy empty prerm to ensure smooth upgrades from wheezy +set -e + +#DEBHELPER# --- axe-6.1.2.orig/debian/changelog +++ axe-6.1.2/debian/changelog @@ -0,0 +1,208 @@ +axe (6.1.2-16.2) unstable; urgency=medium + + * Non-maintainer upload. + * [i386] Re-add dummy prerm for smooth upgrades from wheezy. + (Closes: #708487) + + -- Andreas Beckmann Fri, 16 Jan 2015 10:54:04 +0100 + +axe (6.1.2-16.1) unstable; urgency=low + + * Non-maintainer upload. + * Replaced obsolete tcl8.4-dev build dependency by tcl-dev + (Closes: #737185). + * Defined macro USE_INTERP_RESULT to make axe building with Tcl 8.6. + + -- Sergei Golovan Fri, 31 Jan 2014 21:59:09 +0400 + +axe (6.1.2-16) unstable; urgency=low + + * Acknowledge NMU. + * Fix Depends: line (thanks, Benjamin Kerensa!)(Closes: #688612) + * Don't run install-info in postinst (Closes: #708487) + * Get rid of prerm now that we don't need to run install-info. + * debian/menu: Apps -> Applications + * Improve package title + * Update to Standards-Version: 3.9.4 + * debian/rules: add build-arch and build-indep targets + + -- Hwei Sheng Teoh Wed, 31 Jul 2013 12:15:41 -0700 + +axe (6.1.2-15.1) unstable; urgency=low + + [Jari Aalto] + * Non-maintainer upload. + * debian/control + - (Build-Depends): update obsolete xutils to xutils-dev. + Thanks to Ubuntu patch by Alfonso Cepeda Caballos + . http://launchpad.net/bugs/433391 + (important FTBFS; Closes: #549483). + * debian/rules + - (clean): Define CC variable. + - (stamp-build): Define CC variable. + + -- Jari Aalto Sat, 27 Mar 2010 17:40:16 +0200 + +axe (6.1.2-15) unstable; urgency=low + + * Fix Build-Depends: depend on explicit libraries, not obsoleted + xlib-dev (Closes: #346940) + * Update to Standards-Version: 3.6.2.2 + * Update to debhelper compatibility V5 (debian/compat) + - debian/conffiles: removed, since debhelper now automatically finds + conffiles in /etc + - debian/rules: build everything in debian/axe rather than debian/tmp. + - debian/control: depend on debhelper (>=5.0.14) + * axe.c, coaxe.c, Widgets/AxeEditor.c, Widgets/AxeWindow.c, Help/axinfo.c: + add #include to suppress warnings about incompatible + prototypes for exit(). + * Widgets/regexp.c: use instead of incompatible declaration + of malloc(). + + -- Hwei Sheng Teoh Wed, 11 Jan 2006 09:53:11 -0800 + +axe (6.1.2-14) unstable; urgency=low + + * Fix Build-Depends (should depend on libxaw7-dev not libxaw-dev) + * Update policy to 3.6.1 + * Apply patches to make it buildable with gcc-3.4 (Closes: #274204) + Thanks, Kaare Hviid! + * Clean up mess in debian/menu, move binaries to /usr/bin instead of + deprecated /usr/X11R6/bin. + * Move manpages to /usr/share/man. + * Fix manpage .TH headings. + + -- Hwei Sheng Teoh Wed, 1 Oct 2004 09:54:50 -0700 + +axe (6.1.2-13) unstable; urgency=low + + * Axe.tmpl: new include path and library name for tcl8.4 + * debian/control: upgrade to policy 3.5.8; Build-Depends on tcl8.4. + Remove trailing period from short description + * debian/rules: don't set /usr/doc link anymore. + * Recompile using tcl8.4 (Closes: #183800) + + -- Hwei Sheng Teoh Fri, 7 Mar 2003 10:19:30 -0500 + +axe (6.1.2-12) unstable; urgency=low + + * Fixed: no longer recommend xaw-wrappers (doesn't exist anymore) + + -- Hwei Sheng Teoh Fri, 9 Aug 2002 15:35:30 -0400 + +axe (6.1.2-11) unstable; urgency=low + + * Removing dh_installxaw from rules. (Fixes: #120234) + * Fixed /usr/doc, /usr/share/doc symlinking in prerm and postinst. + + -- Hwei Sheng Teoh Sat, 27 Oct 2001 15:07:35 -0400 + +axe (6.1.2-10) unstable; urgency=low + + * Added xutils to build dependency. (Closes: #102243) + * Excluded INSTALL file from binary package. + * Updated to DH_COMPAT=3. + * Updated to Debian policy 3.5.6. + * Symlink manpage for coaxe/faxe to axe (since they are auxilliary + programs described in the same manpage) + * Known problems: control codes insertion still broken for windows + created by the Window-->New menu; works for windows started by the + main aXe widget. (I don't have the time to track this one down; if + anybody can help fix this, please let me know.) + + -- Hwei Sheng Teoh Sun, 26 Aug 2001 17:53:18 -0400 + +axe (6.1.2-9) frozen unstable; urgency=low + + * Rebuilt using 4.0.1 X libs. Now no longer segfaults on startup/opening + a new editing window. (Closes: #76571) + * debian/control: Added missing stuff to Build-depends. + * Excluded AxeiiSink (and related creatures) from the build process: it + appears to be old code adapted from X11R5's AsciiSink code, adding the + ability to change bitmap cursors. Since Xaw 6 and up already have this + feature built-in, AxeiiSink is no longer necessary (and in fact, fails to + compile on Xaw 7). AxeiiText has been updated to use the native Xaw 7 + cursor capabilities directly. + * coaxe.c Widgets/FileNom.c Widgets/AxeEditor.c: Force usage of getcwd() + instead of getwd() as per gcc warning (should be OK since we're assuming + a sane libc environment). + * debian/control: Added debhelper to Build-depends. + * Widgets/AxeTextDeck.c: fixed to not pass NULL to XtVaCreateManagedWidget + when opening new buffer -- it get mangled into a garbage string when in + AxeText.c:Initialize(). + * Widgets/ScrollText.c: fixed problem with reversed user input. Disabled old + code which apparently works around a limitation in R5's (perhaps R4's?) + Xaw; the new Xaw does not have any of those problems. + * Widgets/FileNom.h Widgets/NumericPad.h Widgets/CtrlCodeSel.h + Widgets/Preference.h: removed redundant definitions of XtNcancelCallBack + (it coincides with the libXt definition and does not define a local + symbol). + * Known problems: the control code insertion popup is broken -- doesn't show + any control codes. Hope to fix this in the next upload. + + -- Hwei Sheng Teoh Wed, 8 Nov 2000 11:28:12 -0500 + +axe (6.1.2-8) frozen unstable; urgency=low + + * Fixed maintainer field in debian/control. + + -- Hwei Sheng Teoh Sun, 17 Sep 2000 15:34:20 -0400 + +axe (6.1.2-7) frozen unstable; urgency=low + + * New maintainer. + * Re-compiled using tcl8.2-dev. Seems to work fine so far: please file a bug + if there are problems! + * Removed/disabled poleaxe. Was never working on Debian (segfaults), and + upstream code supporting it seems incomplete. + + -- Hwei Sheng Teoh Tue, 22 Aug 2000 10:03:45 -0400 + +axe (6.1.2-6.4) frozen unstable; urgency=low + + * Non-maintainer upload, approved by the maintainer. + * Updated to Policy 3.x, with debhelper. + * Implemented proper xaw-wrappers support, + closes: #24209, #24750, #27673, #37109, #58379 (and possibly #25304). + * Changed the InfoDir variable to /usr/share/info, otherwise axinfo wasn't + able to read *any* info pages. + * Unconditionalized the gzipped file reading in Help/axinfo.c, to + remove need for passing -DDEBIAN. Also, removed other EXTRA_OPTIONS + as -Wall was ugly and pointless, and -O2 -g was already specified + in the Imakefiles by default. + * Cleaned up the source tree, and improved debian/rules clean rule. + + -- Josip Rodin Fri, 18 Feb 2000 19:58:36 +0100 + +axe (6.1.2-6.3) unstable; urgency=low + + * recompiled to get rid of debstd bug + + -- Michael Meskes Thu, 22 Jan 1998 11:34:22 +0100 + +axe (6.1.2-6.2) unstable; urgency=low + + * added xaw-wrapper file + * changed section entry + * removed superfluous directories + + -- Michael Meskes Mon, 12 Jan 1998 09:56:22 +0100 + +axe (6.1.2-6.1) unstable; urgency=low + + * recompiled with libc6 which fixed: + (#12345) + (#14075) + (#16669) + * moved package to non-free (#14954) + * compile without -rpath + + -- Michael Meskes Thu, 8 Jan 1998 12:01:44 +0100 + +axe (6.1.2-6) unstable; urgency=low + + * repackaged for source format, using deb-make. + + -- joost witteveen Sat, 18 Jan 1997 15:54:52 +0100 + + --- axe-6.1.2.orig/debian/compat +++ axe-6.1.2/debian/compat @@ -0,0 +1 @@ +5 --- axe-6.1.2.orig/debian/control +++ axe-6.1.2/debian/control @@ -0,0 +1,22 @@ +Source: axe +Section: non-free/editors +Priority: optional +Maintainer: Hwei Sheng Teoh +Build-Depends: debhelper (>=5.0.14), tcl-dev, libx11-dev, libxmu-dev, libxt-dev, libsm-dev, libxpm-dev, libice-dev, libxaw7-dev, xutils-dev +Standards-Version: 3.9.4 + +Package: axe +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Text editor for X + aXe is a simple to use text editor for X that represents a significant + improvement over xedit. Also built around the Athena Text Widget it + features, amongst other things, + o multiple windows, buffers + o configurable menus, optional configurable button interface + o provision for defining keyboard macros + o file selection via a browser + o parenthesis matching, regular expression searching + o restricted or unlimited undo + o ability to change font + o both brief and comprehensive (hypertext) on-line help --- axe-6.1.2.orig/debian/copyright +++ axe-6.1.2/debian/copyright @@ -0,0 +1,35 @@ +This is the Debian GNU/Linux prepackaged version of the aXe editor. + +This package was put together by Michael Meskes, and later by the +current maintainer, joost witteveen, . +Original source was found at: + ftp://ftp.x.org/contrib/editors/aXe-6.1.2.tar.Z + +/* + * Copyright 1994 The University of Newcastle upon Tyne + * + * Permission to use, copy, modify and distribute this software and its + * documentation for any purpose other than its commercial exploitation + * is hereby granted without fee, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of The University of Newcastle upon Tyne not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The University of + * Newcastle upon Tyne makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THE UNIVERSITY OF NEWCASTLE UPON TYNE DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF + * NEWCASTLE UPON TYNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Author: Jim Wight (j.k.wight@newcastle.ac.uk) + * Department of Computing Science + * University of Newcastle upon Tyne, UK + */ --- axe-6.1.2.orig/debian/menu +++ axe-6.1.2/debian/menu @@ -0,0 +1,2 @@ +?package(axe): needs="X11" section="Applications/Editors" title="aXe" \ + command="/usr/bin/axe" --- axe-6.1.2.orig/debian/postinst +++ axe-6.1.2/debian/postinst @@ -0,0 +1,3 @@ +#!/bin/sh -e + +#DEBHELPER# --- axe-6.1.2.orig/debian/rules +++ axe-6.1.2/debian/rules @@ -0,0 +1,62 @@ +#!/usr/bin/make -f +# Derived from Ian Jackson's hello example, Christoph Lameter's debmake +# example, and Joey Hess' debhelper example. + +build: build-arch build-indep +build-arch: build-stamp +build-indep: build-stamp + +# Compatibility with ancient build rules +build-stamp: stamp-build + +stamp-build: + dh_testdir + CC=gcc xmkmf -a + $(MAKE) Xaw3d all + touch $@ + +clean: + dh_testdir + dh_testroot + [ -f Makefile ] || (CC=gcc xmkmf && $(MAKE) Makefiles) + $(MAKE) clean + rm -fr X11 Help/X11 + rm -f Widgets/X11/Xaw3d/X11/* + dh_clean stamp-build `find . -type f -name Makefile` + +install: + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs usr/bin + $(MAKE) install install.man DESTDIR=`pwd`/debian/axe + rm -f `pwd`/debian/axe/usr/lib/X11/axe*info* +# cd `pwd`/debian/axe/usr/bin && mv axe axe.real + +binary-indep: +# There are no architecture-independent packages here. + +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs README + dh_installchangelogs + dh_installmenu + dh_installman + ln -s axe.1x `pwd`/debian/axe/usr/share/man/man1/axe.real.1x + ln -s axe.1x `pwd`/debian/axe/usr/share/man/man1/coaxe.1x + ln -s axe.1x `pwd`/debian/axe/usr/share/man/man1/faxe.1x +# dh_undocumented coaxe.1x faxe.1x + dh_installinfo -n Help/axe.info +# dh_installxaw + dh_strip + dh_compress + dh_fixperms + dh_shlibdeps + dh_gencontrol + dh_installdeb + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary binary-arch binary-indep --- axe-6.1.2.orig/debian/substvars +++ axe-6.1.2/debian/substvars @@ -0,0 +1 @@ +shlibs:Depends=libc6 (>= 2.3.5-1), libice6, libsm6, libx11-6, libxaw7 (>> 4.1.0), libxext6, libxmu6, libxp6, libxpm4, libxt6, tcl8.4 (>= 8.4.5) --- axe-6.1.2.orig/debian/xaw +++ axe-6.1.2/debian/xaw @@ -0,0 +1,4 @@ +Program: /usr/X11R6/bin/axe +Incompat: /usr/X11R6/lib/Xaw3d /usr/X11R6/lib/neXtaw /usr/X11R6/lib/Xaw95 +Wrapped: /usr/X11R6/bin/axe.real +Link-name: axe