acfax/ 40755 765 144 0 6616307021 11066 5ustar andreasusersacfax/Imakefile100644 765 144 4041 6550720523 12776 0ustar andreasusers# # Imakefile for: # ACfax - Fax reception with X11-interface for amateur radio # Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # andreas.czechanowski@ins.uni-stuttgart.de # # # set DEFINES according to your conditions : # # USE_XAW3D : define this if you have the Xaw3d-library # SBL_16 : if you have a SoundBlaster 16 which has a software- # controllable mixer device (/dev/mixer) # HAVE_LTOA : define if you have a function ltoa() converting long ints to # strings. A replacement is defined else. # DSP_SELECT : define this if your kernel supports select() on /dev/dsp # (kernels 2.0+ and even 1.3.82 do this !) # DEFINES = -DUSE_XAW3D -DSBL_16 -DDSP_SELECT -O2 -Wall SRCS = acfax.c Canvas.c mod_demod.c sblaster.c fax_funcs.c \ x_image.c widgets.c \ FChooser.c Directory.c DirMgr.c RegExp.c OBJS = acfax.o Canvas.o mod_demod.o sblaster.o fax_funcs.o \ x_image.o widgets.o \ FChooser.o Directory.o DirMgr.o RegExp.o INCLUDES = -I. LOCAL_LIBRARIES = -lXaw3d $(XMULIB) $(XTOOLLIB) $(XLIB) -lm SYS_LIBRARIES = all:: acfax ComplexProgramTarget(acfax) acfax.o: global.h mod_demod.h sblaster.h widgets.h widgets.o: widgets.h fax_funcs.o: fax_funcs.h x_image.h sblaster.h mod_demod.h x_image.o: x_image.h sblaster.o: sblaster.h mod_demod.h mod_demod.o: mod_demod.h acfax/Canvas.c100644 765 144 31017 6550717200 12565 0ustar andreasusers/* * $Header: /home/orchestra5/davy/stuff/misc/xsat/RCS/Canvas.c,v 1.1 92/04/10 14:08:02 davy Exp $ * * Copyright 1992 by David A. Curry * Adapted for use with ACfax by Andreas Czechanowski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose 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. The * author makes no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * Code for the Canvas widget. Based in part on the Template widget from * the X11R5 distribution; I also looked quite a bit at the code from the * "xproof" program to figure out how to set things up. * * David A. Curry * Purdue University * Engineering Computer Network * 1285 Electrical Engineering Building * West Lafayette, IN 47907 * davy@ecn.purdue.edu * * $Log: Canvas.c,v $ * Revision 1.1 92/04/10 14:08:02 davy * Initial revision * */ #include #include #include #include #include #include "CanvasP.h" static void Destroy(); static void Realize(); static void Redisplay(); static void Resize(); static XtGeometryResult QueryGeometry(); static Boolean SetValues(); static XtGeometryResult Geometry_manager(); static void Initialize(); static void Notify(); void canvasIdle(); void canvasBusy(); void canvasClearPicture(); void canvasUpdateArea(); /* * Canvas widget translations */ static char defaultTranslations[] = ": notify()"; /* * Canvas widget actions */ static XtActionsRec actionsList[] = { {"notify", Notify} }; /* * Canvas widget resources. */ /* offset to a canvas-element in the widget-structure */ #define offset(field) XtOffsetOf(CanvasRec,canvas.field) /* offset to a core-element in the widget-stucture */ #define goffset(field) XtOffsetOf(CanvasRec,core.field) static XtResource resources[] = { { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), goffset(background_pixel), XtRString, "white" }, { XtNidleCursor, XtCCursor, XtRCursor, sizeof(Cursor), offset(idle_cursor), XtRString, "left_ptr" }, { XtNbusyCursor, XtCCursor, XtRCursor, sizeof(Cursor), offset(busy_cursor), XtRString, "watch" }, { XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(callbacks), XtRCallback, (XtPointer)NULL}, /* { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), offset(font), XtRString, XtDefaultFont }, */ }; #undef offset #undef goffset CanvasClassRec canvasClassRec = { { /* core fields */ /* superclass */ (WidgetClass) &compositeClassRec, /* class_name */ "Canvas", /* widget_size */ sizeof(CanvasRec), /* class_initialize */ NULL, /* class_part_initialize */ NULL, /* class_inited */ FALSE, /* initialize */ Initialize, /* initialize_hook */ NULL, /* realize */ Realize, /* actions */ actionsList, /* num_actions */ XtNumber(actionsList), /* resources */ resources, /* num_resources */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ Destroy, /* resize */ Resize, /* expose */ Redisplay, /* set_values */ SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ defaultTranslations, /* query_geometry */ QueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, { /* composite fields */ /* geometry_manager */ Geometry_manager, /* change_managed */ XtInheritChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL }, { /* canvas fields */ /* empty */ 0 } }; WidgetClass canvasWidgetClass = (WidgetClass)&canvasClassRec; /* * Initialize a widget instance by allocating graphics contexts. */ static void Initialize(request, new) Widget request, new; { Display *d; XGCValues gcv; CanvasWidget w = (CanvasWidget) new; gcv.function = GXcopy; gcv.plane_mask = AllPlanes; /* the drawGC has function GXcopy as function set, that clears all the previous contents of the drawable used with it. */ w->canvas.copyGC = XtGetGC((Widget) w, GCFunction | GCPlaneMask, &gcv); /* gcv.font = w->canvas.font->fid; */ gcv.function = GXcopy; gcv.plane_mask = AllPlanes; w->canvas.drawGC = XtGetGC((Widget) w, GCFunction | GCPlaneMask, &gcv); /* finally, the clearGC simply allows to clear the drawable by using XFillRectangle. foreground is set equal to background */ gcv.foreground = w->core.background_pixel; w->canvas.clearGC = XtGetGC((Widget) w, GCForeground, &gcv); /* create pixmap, that is copied to the window on exposes or on request by CanvasUpdateArea */ d = XtDisplay(w); w->canvas.pxmw = w->core.width; w->canvas.pxmh = w->core.height; w->canvas.picture = XCreatePixmap(d, DefaultRootWindow(d), w->core.width, w->core.height, DefaultDepth(d, DefaultScreen(d))); } /* * Realize a widget instance. Allocate pixmaps, create the window, etc. */ static void Realize(gw, valueMask, attr) XSetWindowAttributes *attr; XtValueMask *valueMask; Widget gw; { CanvasWidget w = (CanvasWidget) gw; /* look if we have an idle-cursor set in the resources, and if so, tell the window we create about it. */ if ((attr->cursor = w->canvas.idle_cursor) != None) *valueMask |= CWCursor; /* create our window */ XtCreateWindow(gw, InputOutput, (Visual *) CopyFromParent, *valueMask, attr); /* clear the cpixmap */ canvasClearPicture(w); } /* * Destroy a widget instance. */ static void Destroy(gw) Widget gw; { CanvasWidget w = (CanvasWidget) gw; /* release the allocated space for all the GCs... */ XtReleaseGC((Widget) w, w->canvas.drawGC); XtReleaseGC((Widget) w, w->canvas.copyGC); XtReleaseGC((Widget) w, w->canvas.clearGC); /* ...and for the pixmaps */ XFreePixmap(XtDisplay(w), w->canvas.picture); } /* * Widget was resized */ static void Resize(w) Widget w; { CanvasWidget cw = (CanvasWidget) w; fprintf(stderr, "Canvas: Resize called ! wid=%u, height=%u\n", (unsigned)cw->core.width, (unsigned)cw->core.height); } /* * Geometry is queried by parent */ static XtGeometryResult QueryGeometry(w, intended, preferred) Widget w; XtWidgetGeometry *intended, *preferred; { CanvasWidget cw = (CanvasWidget) w; preferred->request_mode = CWWidth | CWHeight; preferred->width = cw->canvas.pxmw; preferred->height = cw->canvas.pxmh; if (preferred->width == w->core.width && preferred->height == w->core.height) return XtGeometryNo; if (((intended->request_mode & (CWWidth|CWHeight)) == (CWWidth|CWHeight)) && intended->width == preferred->width && intended->height == preferred->height) return XtGeometryYes; return XtGeometryAlmost; } /* * Redisplay a widget after an expose event by copying data from the pixmaps. */ static void Redisplay(gw, event, region) Region region; XEvent *event; Widget gw; { CanvasWidget w = (CanvasWidget) gw; XExposeEvent *e = (XExposeEvent *) event; canvasBusy(w); /* copy the bounding box of the exposed area from the pixmaps into the window to redraw the destroyed contents. */ /* underlay the picture at first.... */ XCopyArea(XtDisplay(gw), w->canvas.picture, XtWindow(gw), w->canvas.copyGC, e->x, e->y, (Dimension) e->width, (Dimension) e->height, e->x, e->y); canvasIdle(w); } static void Notify(w,event,params,num_params) Widget w; XEvent *event; String *params; /* unused */ Cardinal *num_params; /* unused */ { static XPoint xp; CanvasWidget cw = (CanvasWidget)w; switch (event->type) { case ButtonPress: xp.x = event->xbutton.x; xp.y = event->xbutton.y; XtCallCallbackList(w, cw->canvas.callbacks, (XtPointer) &xp); break; default: XtCallCallbackList(w, cw->canvas.callbacks, (XtPointer) NULL); break; } } static Boolean SetValues(Widget current, Widget request, Widget new, ArgList args, Cardinal *num_args) { CanvasWidget curcw = (CanvasWidget) current; CanvasWidget reqcw = (CanvasWidget) request; CanvasWidget newcw = (CanvasWidget) new; Pixmap pxm; Display *d; Dimension oldw, oldh, neww, newh; fprintf(stderr, "Canvas: SetValues called\n"); /* if the geometry is changed, we have to create a new pixmap. */ oldw = curcw->canvas.pxmw; oldh = curcw->canvas.pxmh; neww = reqcw->core.width; newh = reqcw->core.height; if ((oldw != neww) || (oldh != newh)) { d = XtDisplay(current); pxm = XCreatePixmap(d, DefaultRootWindow(d), neww, newh, DefaultDepth(d, DefaultScreen(d))); /* we don't need this here because the main-program must redraw the screen anyway if geometry has changed. */ /* XCopyArea(d, curcw->canvas.picture, pxm, curcw->canvas.copyGC, 0, 0, min(neww, oldw), min(newh, oldh), 0, 0); */ /* now free the old pixmap */ XFreePixmap(d, curcw->canvas.picture); /* and set the changed values. */ newcw->canvas.picture = pxm; newcw->canvas.pxmw = neww; newcw->canvas.pxmh = newh; } /* Redisplay needed ? I think not... */ return False; } static XtGeometryResult Geometry_manager(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *new) { /* use the following to allow geometry-changes by the child - ACZ if (request->request_mode & CWX) w->core.x = request->x; if (request->request_mode & CWY) w->core.y = request->y; if (request->request_mode & CWWidth) w->core.width = request->width; if (request->request_mode & CWHeight) w->core.height = request->height; if (request->request_mode & CWBorderWidth) w->core.border_width = request->border_width; return XtGeometryNo; */ fprintf(stderr, "geometry manager called !\n"); return XtGeometryYes; } /* * Draw line segments on the "picture" pixmap of the widget. */ void canvasDrawSegmentsPicture(w, segments, nsegments) XSegment *segments; CanvasWidget w; int nsegments; { XDrawSegments(XtDisplay(w), w->canvas.picture, w->canvas.drawGC, segments, nsegments); } /* * Draw a line on the "picture" pixmap of the widget. */ void canvasDrawLinePicture(w, x1, y1, x2, y2) int x1, y1, x2, y2; CanvasWidget w; { XDrawLine(XtDisplay(w), w->canvas.picture, w->canvas.drawGC, x1, y1, x2, y2); } /* * Draw text on the "picture" pixmap of the widget. */ void canvasDrawTextPicture(w, x, y, str) CanvasWidget w; char *str; int x, y; { XDrawString(XtDisplay(w), w->canvas.picture, w->canvas.drawGC, x, y, str, strlen(str)); } /* * Clear the "picture" pixmap of the widget. */ void canvasClearPicture(w) CanvasWidget w; { XFillRectangle(XtDisplay(w), w->canvas.picture, w->canvas.clearGC, 0, 0, w->core.width, w->core.height); } /* * Update the window of the widget with the "picture" and "scratch" pixmaps. */ void canvasUpdateArea(w, x, y, width, height) CanvasWidget w; unsigned x, y, width, height; { unsigned cw, ch; cw = w->core.width; ch = w->core.height; if (x >= cw) x = cw-1; if (y >= ch) y = ch-1; if (x + width > cw) width = cw - x; if (y + height > ch) height = ch - y; /* copy the picture-pixmap onto the window */ XCopyArea(XtDisplay(w), w->canvas.picture, XtWindow(w), w->canvas.copyGC, x, y, width, height, x, y); } /* * Get one of the GCs of the Widget */ GC canvasGetGC(w, type) CanvasWidget w; unsigned type; { switch(type) { case CanvasDrawGC: return (w->canvas.drawGC); case CanvasCopyGC: return (w->canvas.copyGC); case CanvasClearGC: return (w->canvas.clearGC); default: return (GC)NULL; } } /* * Get one of the Pixmaps of the Widget */ Pixmap canvasGetPixmap(w, type) CanvasWidget w; unsigned type; { switch(type) { case CanvasPicture: return (w->canvas.picture); default: return (Pixmap)NULL; } } /* * Set the cursor to the busy cursor. */ void canvasBusy(w) CanvasWidget w; { XSetWindowAttributes attr; if ((attr.cursor = w->canvas.busy_cursor) != None) { XChangeWindowAttributes(XtDisplay(w), XtWindow(w), CWCursor, &attr); XFlush(XtDisplay(w)); } } /* * Set the cursor to the idle cursor. */ void canvasIdle(w) CanvasWidget w; { XSetWindowAttributes attr; if ((attr.cursor = w->canvas.idle_cursor) != None) { XChangeWindowAttributes(XtDisplay(w), XtWindow(w), CWCursor, &attr); XFlush(XtDisplay(w)); } } acfax/Canvas.h100644 765 144 5177 6550716323 12567 0ustar andreasusers/* * $Header: /home/orchestra5/davy/stuff/misc/xsat/RCS/Canvas.h,v 1.1 92/04/10 14:08:04 davy Exp $ * * Copyright 1992 by David A. Curry * Adapted for use with ACfax by Andreas Czechanowski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose 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. The * author makes no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * Public include file for the canvas widget. Based on the include file for * the Template widget in the X11R5 distribution. * * David A. Curry * Purdue University * Engineering Computer Network * 1285 Electrical Engineering Building * West Lafayette, IN 47907 * davy@ecn.purdue.edu * * $Log: Canvas.h,v $ * Revision 1.1 92/04/10 14:08:04 davy * Initial revision * */ #ifndef _Canvas_h #define _Canvas_h /**************************************************************** * * Canvas widget * ****************************************************************/ /* * Resources: * * Name Class RepType Default Value * ---- ----- ------- ------------- * background Background Pixel XtDefaultBackground * border BorderColor Pixel XtDefaultForeground * borderWidth BorderWidth Dimension 1 * destroyCallback Callback Pointer NULL * height Height Dimension 0 * mappedWhenManaged MappedWhenManaged Boolean True * sensitive Sensitive Boolean True * width Width Dimension 0 * x Position Position 0 * y Position Position 0 */ /* * Canvas-specific resource names. */ #define XtNidleCursor "idleCursor" #define XtNbusyCursor "busyCursor" enum { CanvasDrawGC, CanvasCopyGC, CanvasClearGC }; enum { CanvasPicture }; /* * Declare specific CanvasWidget class and instance datatypes. */ typedef struct _CanvasClassRec* CanvasWidgetClass; typedef struct _CanvasRec* CanvasWidget; /* * Declare the class constant. */ extern WidgetClass canvasWidgetClass; /* * Declare the functions accessable for the user */ extern GC canvasGetGC( #if NeedFunctionPrototypes CanvasWidget, /* w */ unsigned /* type */ #endif ); extern Pixmap canvasGetPixmap( #if NeedFunctionPrototypes CanvasWidget, /* w */ unsigned /* type */ #endif ); extern void canvasUpdateArea( #if NeedFunctionPrototypes CanvasWidget, /* w */ unsigned, unsigned, /* x, y */ unsigned, unsigned /* width, height */ #endif ); #endif /* _Canvas_h */ acfax/CanvasP.h100644 765 144 3672 6550716351 12706 0ustar andreasusers/* * $Header: /home/orchestra5/davy/stuff/misc/xsat/RCS/CanvasP.h,v 1.1 92/04/10 14:08:05 davy Exp $ * * Copyright 1992 by David A. Curry * Adapted for use with ACfax by Andreas Czechanowski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose 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. The * author makes no representations about the suitability of this software for * any purpose. It is provided "as is" without express or implied warranty. * * Private include file for the canvas widget. Based on the include file for * the Template widget in the X11R5 distribution. * * David A. Curry * Purdue University * Engineering Computer Network * 1285 Electrical Engineering Building * West Lafayette, IN 47907 * davy@ecn.purdue.edu * * $Log: CanvasP.h,v $ * Revision 1.1 92/04/10 14:08:05 davy * Initial revision * */ #ifndef _CanvasP_h #define _CanvasP_h #include #include "Canvas.h" typedef struct { int empty; } CanvasClassPart; typedef struct _CanvasClassRec { CoreClassPart core_class; CompositeClassPart composite; CanvasClassPart canvas_class; } CanvasClassRec; extern CanvasClassRec canvasClassRec; typedef struct { Cursor idle_cursor; /* cursor when not drawing */ Cursor busy_cursor; /* cursor when drawing */ XtCallbackList callbacks; /* callbacks for button-press */ GC copyGC; /* GC for copying pixmaps */ GC drawGC; /* GC for drawing on picture */ GC clearGC; /* GC for clearing pixmaps */ Pixmap picture; /* "main" backup-pixmap */ unsigned pxmw; /* width of created pixmap */ unsigned pxmh; /* height of created pixmap */ } CanvasPart; typedef struct _CanvasRec { CorePart core; CompositePart composite; CanvasPart canvas; } CanvasRec; #endif /* _CanvasP_h */ acfax/acfax.c100644 765 144 62526 6606506163 12453 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * acfax.c - the main program */ #include #include #include #include #include #include #ifdef USE_XAW3D #include #include #include #include #include #include #include #include #include #else #include #include #include #include #include #include #include #include #endif #include "Canvas.h" #include "global.h" #include "mod_demod.h" #include "sblaster.h" #include "x_image.h" #include "fax_funcs.h" #include "widgets.h" static char *fallbacks[] = { "*background: grey80", "*foreground: black", "*menuform*filebut.label: file-ops", "*menuform*filebut*file_mw.label: Image-file ops :", "*menuform*filebut*autosave.label: save (auto filename)", "*menuform*filebut*saveas.label: save as...", "*menuform*filebut*close.label: close savefile", "*menuform*filebut*quit.label: quit ACfax", "*optbut.label: Options...", "*modebut.label: Modes...", /* "*msg_shell*msg_ok.label: -OK-", */ "*canvas.width: 1280", "*canvas.height: 1024", "*modemform*modemdesc.background: beige", "*modemform*modemdesc.label: modem settings", "*modemform*modinfo.background: beige", "*modemform*modinfo.label: modem\\ntype", "*modemform*filinfo.background: beige", "*modemform*filinfo.label: filter\\nselect", "*modemform*mflt1.label: narrow filter", "*modemform*mflt2.label: middle filter", "*modemform*mflt3.label: wide filter", "*modemform*fmdevinfo.background: beige", "*modemform*fmdevinfo.label: FM deviation (+/- Hz)", "*modemform*siginfo.background: beige", "*modemform*siginfo.label: Signal", "*faxctrls*runinfo.background: beige", "*faxctrls*runinfo.label: operation\\ncontrol", "*faxctrls*dirinfo.background: beige", "*faxctrls*dirinfo.label: writing\\ndirection", "*faxctrls*polinfo.background: beige", "*faxctrls*polinfo.label: image\\npolarity", "*faxctrls*phsinfo.background: beige", "*faxctrls*phsinfo.label: sync\\npolarity", "*faxctrls*adjinfo.background: beige", "*faxctrls*adjinfo.label: image\\nadjust", "*faxparams*numinfo.background: beige", "*faxparams*numinfo.label: numeric FAX-parameters", "*faxparams*statxt.label: APT start:", "*faxparams*stotxt.label: stop:", "*faxparams*lpmtxt.label: LPM:", "*faxparams*ioctxt.label: IOC:", NULL }; struct prginfo { String callsign; String sizedesc; } prg_info; Display *dpy; /* the X-Display to use */ Screen *scr; /* screen of the display */ Pixmap cpxmap; /* The "backing store" for the canvas-widget */ GC cgc; /* GC for XPutImage from horimage/verimage to cpxmap */ /* XEvent event; for XtAppNextEvent / XtDispatchEvent */ /* unsigned canwid; width of canvas-widget */ /* unsigned canhei; height of canvas-widget */ /* Colormap cmap, rootcmap; colormap we use, and default-colormap */ /* unsigned coltab[256]; mapping table linear grayscale->pixel-value */ /* char cused[256]; table indicating used pixel-values */ int mode_lock = 0; /* locks the operation control callback */ /* int xpos, ypos; position to fill with data */ /* int ixoc; number of pixels of one scan-line / PI */ /* int right2left; boolean indicating reverse line writing direction */ /* int bot2top; boolean indicating reverse line stacking direction */ /* int mod_mode; can be MOD_FM or MOD_AM */ /* int fax_state; one of FAX_APT, FAX_PHAS or FAX_RX */ /* int max_val; maximum level for demodulated output */ /* int aptstart; possible APT start values */ /* int aptstop; possible APT stop values */ int save_width; /* width of scan-line in pixels for saving */ struct fileshell_args save_fsa; /* structure for file-save */ struct fileshell_args load_fsa; /* structure for file-load */ XtAppContext mainapp; Widget toplevel; /* Widget last; / just for convenience.... / Widget form, / where to put it all in / vport, / a viewport to look thru onto the canvas / canvas; / widget holding picture using XImages / */ /* Widget menuform, filebut, / buttons in the top-line : "file" / modebut, / mode-select button / optbut; / option-select button / Widget file_mw, / popup-menu for "file" / file_saveas, / menu-item "save as" / file_close, / menu-item "close savefile" / file_autosave; / menu-item "save (auto filename) / Widget msg_shell, / popup-shell for aux. messages / msg_form, / form widget holding... / msg_text, / displayed text / msg_ok; / additional button (Ok/cancel/confirm/...) / Widget modemform, faxformA, faxformB; Widget modeminfo, mmode, fmdevinfo, fmdevval, fmdevtxt; Widget runinfo, rmstop, rmsyn, rmrun; Widget dirinfo, dirhv, dirlr, dirtb, polinfo, norinv; Widget phsinfo, posneg, statxt, staval, stotxt, stoval; Widget numinfo, lpmtxt, lpmval, ioctxt, iocval; Widget adjinfo, lshift, azimut; */ /* Pixmap px_horiz, px_vert, px_right, px_left, px_top, px_bottom, px_normal, px_invers, px_nphs, px_iphs, px_azimut, px_shift, px_stop, px_syn, px_run, px_mam, px_mfm, px_narrow, px_middle, px_wide; */ #define elofs(element) XtOffsetOf(struct prginfo, element) static XtResource resources[] = { { "callsign", "Callsign", XtRString, sizeof(String), elofs(callsign), XtRImmediate, (XtPointer)"nocall" }, { "size", "Size", XtRString, sizeof(String), elofs(sizedesc), XtRImmediate, (XtPointer)"double" }, }; static XrmOptionDescRec options[] = { { "-callsign", ".callsign", XrmoptionSepArg, (XtPointer)NULL }, { "-size", ".size", XrmoptionSepArg, (XtPointer)NULL }, }; static void usage(char *); /* void create_widgets(void); */ /* void create_pixmaps(Widget); */ void update_pxm(XImage *, int, int, int, int, unsigned, unsigned); void num_input(Widget, XEvent *, String *, Cardinal *); void show_values(void); void op_changed(int); void modmode_cb(Widget, XtPointer, XtPointer); void filtsel_cb(Widget, XtPointer, XtPointer); void stastop_cb(Widget, XtPointer, XtPointer); void dirhv_cb(Widget, XtPointer, XtPointer); void dirlr_cb(Widget, XtPointer, XtPointer); void dirtb_cb(Widget, XtPointer, XtPointer); void norinv_cb(Widget, XtPointer, XtPointer); void posneg_cb(Widget, XtPointer, XtPointer); void lshift_cb(Widget, XtPointer, XtPointer); void lshift_trigger(Widget, XtPointer, XtPointer); void azimut_cb(Widget, XtPointer, XtPointer); void azimut_trigger(Widget, XtPointer, XtPointer); void namesave_cb(Widget, XtPointer, XtPointer); void savefile_act(char *); void autosave_cb(Widget, XtPointer, XtPointer); void closesave_cb(Widget, XtPointer, XtPointer); void quit_cb(Widget, XtPointer, XtPointer); XtTranslations txt_trans; XtActionsRec acts[] = { { "num-in", (XtActionProc)num_input }, }; #ifndef HAVE_LTOA /* simple, fast integer to string conversion */ char *ltoa(int n) { static char res[16]; int i, f[16]; int d, p; d = 0; /* 0 digits */ p = 0; /* 0 chars in string */ /* allow to handle negative numbers */ if (n < 0) { res[p++] = '-'; } /* calculate all the fractional parts */ do { i = n / 10; f[d++] = n % 10; n = i; } while (i != 0); /* concatenate to string in reverse order */ while (d) { res[p++] = f[--d] + '0'; } /* terminate string */ res[p] = '\0'; return res; } #endif static void usage(char *prgname) { fprintf(stderr, "Usage : %s [Options]\n" " Known options are :\n" " -callsign callsign\n" " -width {normal|double}\n", prgname); } /* void create_pixmaps(Widget wid) { #include "bitmaps/horiz.bit" #include "bitmaps/vert.bit" #include "bitmaps/left.bit" #include "bitmaps/right.bit" #include "bitmaps/top.bit" #include "bitmaps/bottom.bit" #include "bitmaps/nphs.bit" #include "bitmaps/iphs.bit" #include "bitmaps/normal.bit" #include "bitmaps/invers.bit" #include "bitmaps/azimut.bit" #include "bitmaps/shift.bit" #include "bitmaps/stop.bit" #include "bitmaps/syn.bit" #include "bitmaps/run.bit" #include "bitmaps/ammod.bit" #include "bitmaps/fmmod.bit" #include "bitmaps/narrow.bit" #include "bitmaps/middle.bit" #include "bitmaps/wide.bit" Window win; win = XtWindow(wid); px_horiz = XCreateBitmapFromData(dpy, win, horiz_bits, horiz_width, horiz_height); px_vert = XCreateBitmapFromData(dpy, win, vert_bits, vert_width, vert_height); px_right = XCreateBitmapFromData(dpy, win, right_bits, right_width, right_height); px_left = XCreateBitmapFromData(dpy, win, left_bits, left_width, left_height); px_top = XCreateBitmapFromData(dpy, win, top_bits, top_width, top_height); px_bottom = XCreateBitmapFromData(dpy, win, bottom_bits, bottom_width, bottom_height); px_nphs = XCreateBitmapFromData(dpy, win, nphs_bits, nphs_width, nphs_height); px_iphs = XCreateBitmapFromData(dpy, win, iphs_bits, iphs_width, iphs_height); px_normal = XCreateBitmapFromData(dpy, win, normal_bits, normal_width, normal_height); px_invers = XCreateBitmapFromData(dpy, win, invers_bits, invers_width, invers_height); px_azimut = XCreateBitmapFromData(dpy, win, azimut_bits, azimut_width, azimut_height); px_shift = XCreateBitmapFromData(dpy, win, shift_bits, shift_width, shift_height); px_stop = XCreateBitmapFromData(dpy, win, stop_bits, stop_width, stop_height); px_syn = XCreateBitmapFromData(dpy, win, syn_bits, syn_width, syn_height); px_run = XCreateBitmapFromData(dpy, win, run_bits, run_width, run_height); px_mam = XCreateBitmapFromData(dpy, win, ammod_bits, ammod_width, ammod_height); px_mfm = XCreateBitmapFromData(dpy, win, fmmod_bits, fmmod_width, fmmod_height); px_narrow = XCreateBitmapFromData(dpy, win, narrow_bits, narrow_width, narrow_height); px_middle = XCreateBitmapFromData(dpy, win, middle_bits, middle_width, middle_height); px_wide = XCreateBitmapFromData(dpy, win, wide_bits, wide_width, wide_height); XtVaSetValues(dirhv, XtNbitmap, px_horiz, NULL); XtVaSetValues(dirlr, XtNbitmap, px_right, NULL); XtVaSetValues(dirtb, XtNbitmap, px_bottom, NULL); XtVaSetValues(norinv, XtNbitmap, px_normal, NULL); XtVaSetValues(posneg, XtNbitmap, px_nphs, NULL); XtVaSetValues(lshift, XtNbitmap, px_shift, NULL); XtVaSetValues(azimut, XtNbitmap, px_azimut, NULL); XtVaSetValues(rmstop, XtNbitmap, px_stop, NULL); XtVaSetValues(rmsyn, XtNbitmap, px_syn, NULL); XtVaSetValues(rmrun, XtNbitmap, px_run, NULL); XtVaSetValues(mmode, XtNbitmap, px_mfm, NULL); XtVaSetValues(mfilter, XtNbitmap, px_middle, NULL); } */ /* copy one of the XImages into the Pixmap of the canvas, and redisplay that portion of the image */ void update_pxm(XImage *img, int xs, int ys, int xd, int yd, unsigned wid, unsigned hei) { XPutImage(dpy, cpxmap, cgc, img, xs, ys, xd, yd, wid, hei); canvasUpdateArea((CanvasWidget)canvas, xd, yd, wid, hei); } /* the following makes the gcc happy not to complain about unused arguments */ /* ARGSUSED */ void num_input(Widget w, XEvent *event, String *par, Cardinal *npar) { int val; String str; char ch[8]; XtVaGetValues(w, XtNstring, &str, NULL); val = atoi(str); if (w == num_s.staval) { if (val > 500) val = 500; if (val < 100) val = 100; aptstart = val; } else if (w == num_s.stoval) { if (val > 500) val = 500; if (val < 100) val = 100; aptstop = val; } else if (w == num_s.lpmval) { setup_fax(val, 0, 0, w, 0, 0, 0, 0); val = lpm; } else if (w == num_s.iocval) { setup_fax(0, val, 0, w, 0, 0, 0, 0); val = ixoc; } else if (w == mod_s.fmdevval) { setup_fax(0, 0, 0, w, 0, 0, val, 0); val = devi; } sprintf(ch, "%d", val); XtVaSetValues(w, XtNstring, ch, NULL); } /* show the numeric fax-parameters and the FM-deviation of the modem */ void show_values(void) { XtVaSetValues(mod_s.fmdevval, XtNstring, ltoa(devi), NULL); XtVaSetValues(num_s.lpmval, XtNstring, ltoa(lpm), NULL); XtVaSetValues(num_s.iocval, XtNstring, ltoa(ixoc), NULL); XtVaSetValues(num_s.staval, XtNstring, ltoa(aptstart), NULL); XtVaSetValues(num_s.stoval, XtNstring, ltoa(aptstop), NULL); } void op_changed(int mode) { mode_lock = 1; switch(mode) { case FAX_APT: XtVaSetValues(run_s.rmstop, XtNstate, True, NULL); break; case FAX_PHAS: XtVaSetValues(run_s.rmsyn, XtNstate, True, NULL); break; case FAX_RX: XtVaSetValues(run_s.rmrun, XtNstate, True, NULL); break; } mode_lock = 0; } void modmode_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; st = (Boolean)((long)call_data); if (st) { setup_fax(0, 0, 0, w, 0, 0, 0, MOD_AM); XtVaSetValues(mod_s.mmode, XtNbitmap, px_mam, NULL); } else { setup_fax(0, 0, 0, w, 0, 0, 0, MOD_FM); XtVaSetValues(mod_s.mmode, XtNbitmap, px_mfm, NULL); } } void filtsel_cb(Widget w, XtPointer client_data, XtPointer call_data) { int selectn; Pixmap pxm; selectn = (int)client_data; switch (selectn) { case FIL_NARR: pxm = px_narrow; break; case FIL_MIDL: pxm = px_middle; break; case FIL_WIDE: pxm = px_wide; break; default: return; } setup_fax(0, 0, 0, w, 0, 0, 0, selectn); XtVaSetValues(mod_s.mfilter, XtNbitmap, pxm, NULL); } void stastop_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; unsigned rd; rd = (unsigned)XawToggleGetCurrent(w); st = (Boolean)((long)call_data); fprintf(stderr, "rd = %u, st = %u\n", rd, (unsigned)st); if (rd == 0) { /* all widgets of the radio-group are unset ? */ /* XtVaSetValues(rmstop, XtNstate, True, NULL); we may call ourself here ! */ return; } if (!st) { return; /* if unset, do not continue */ } if (mode_lock) return; switch(rd) { case FAX_APT: fax_rx_stop(0); break; case FAX_PHAS: fax_rx_phase(0); break; case FAX_RX: fax_rx_start(0); break; } } void syn_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; st = (Boolean)((long)call_data); if (!st) { XtVaSetValues(w, XtNstate, True, NULL); /* we may call ourself here ! */ return; /* if unset, do not continue */ } fax_rx_phase(0); } void run_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; st = (Boolean)((long)call_data); if (!st) { XtVaSetValues(w, XtNstate, True, NULL); /* we may call ourself here ! */ return; /* if unset, do not continue */ } fax_rx_start(0); } void dirhv_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; XtVaGetValues(w, XtNstate, &st, NULL); if (st == True) { setup_fax(0, 0, FAX_VER, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_vert, NULL); } else { setup_fax(0, 0, FAX_HOR, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_horiz, NULL); } } void dirlr_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; XtVaGetValues(w, XtNstate, &st, NULL); if (st == True) { setup_fax(0, 0, FAX_RIG2LEF, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_left, NULL); } else { setup_fax(0, 0, FAX_LEF2RIG, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_right, NULL); } } void dirtb_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; XtVaGetValues(w, XtNstate, &st, NULL); if (st == True) { setup_fax(0, 0, FAX_BOT2TOP, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_top, NULL); } else { setup_fax(0, 0, FAX_TOP2BOT, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_bottom, NULL); } } void norinv_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; XtVaGetValues(w, XtNstate, &st, NULL); if (st == True) { setup_fax(0, 0, FAX_CINV, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_invers, NULL); } else { setup_fax(0, 0, FAX_CNOR, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_normal, NULL); } } void posneg_cb(Widget w, XtPointer client_data, XtPointer call_data) { Boolean st; XtVaGetValues(w, XtNstate, &st, NULL); if (st == True) { setup_fax(0, 0, FAX_PWHT, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_iphs, NULL); } else { setup_fax(0, 0, FAX_PBLK, w, 0, 0, 0, 0); XtVaSetValues(w, XtNbitmap, px_nphs, NULL); } } void text_cb(Widget w, XtPointer client_data, XtPointer call_data) { String s; XtVaGetValues(w, XtNstring, &s, NULL); fprintf(stderr, "text_cb: string = %s\n", s); } void show_coords(Widget w, XtPointer client_data, XtPointer call_data) { XPoint *xp; if (call_data) { xp = (XPoint *) call_data; printf("coords = %d, %d\n", xp->x, xp->y); } } void lshift_cb(Widget w, XtPointer client_data, XtPointer call_data) { XtVaSetValues(adj_s.lshift, XtNsensitive, False, NULL); XtVaSetValues(adj_s.azimut, XtNsensitive, False, NULL); XtVaSetValues(info_s.text, XtNlabel, "move mointer to sync position\n" "and press left mouse button.", NULL); XtVaSetValues(info_s.butn, XtNlabel, "Cancel", NULL); XawFormDoLayout(info_s.form, True); XtAddCallback(canvas, XtNcallback, lshift_trigger, (XtPointer) 1); XtAddCallback(info_s.butn, XtNcallback, lshift_trigger, (XtPointer) 0); XtPopup(info_s.shell, XtGrabNone); } void lshift_trigger(Widget w, XtPointer client_data, XtPointer call_data) { XPoint *xp; if ((unsigned)client_data == 1) { if (call_data) { xp = (XPoint *) call_data; shift_fax_coords(xp->x, xp->y); } } XtRemoveAllCallbacks(canvas, XtNcallback); XtVaSetValues(adj_s.lshift, XtNsensitive, True, NULL); XtVaSetValues(adj_s.azimut, XtNsensitive, True, NULL); XtPopdown(info_s.shell); } void azimut_cb(Widget w, XtPointer client_data, XtPointer call_data) { char message[256]; Boolean vertmode; /* do not allow any further keypress on this button */ XtVaSetValues(adj_s.azimut, XtNsensitive, False, NULL); XtVaSetValues(adj_s.lshift, XtNsensitive, False, NULL); XtVaGetValues(dir_s.dirhv, XtNstate, &vertmode, NULL); sprintf(message, "move mointer to the first point\n" "on a line that should be %s\n" "and press left mouse button.", (vertmode) ? "horizontal" : "vertical"); XtVaSetValues(info_s.text, XtNlabel, message, NULL); XtVaSetValues(info_s.butn, XtNlabel, "Cancel", NULL); XawFormDoLayout(info_s.form, True); XtAddCallback(canvas, XtNcallback, azimut_trigger, (XtPointer) 1); XtAddCallback(info_s.butn, XtNcallback, azimut_trigger, (XtPointer) 0); XtPopup(info_s.shell, XtGrabNone); } void azimut_trigger(Widget w, XtPointer client_data, XtPointer call_data) { XPoint *xp; static int xa, ya; if ((unsigned)client_data == 1) { /* first point, get position into xa, ya */ if (call_data) { xp = (XPoint *) call_data; xa = xp->x; ya = xp->y; XtVaSetValues(info_s.text, XtNlabel, "now move pointer to the second point\n" "on that line and press left mouse button.", NULL); XtVaSetValues(info_s.butn, XtNlabel, "Cancel", NULL); /* XawFormDoLayout(info_s.form, True); */ XtRemoveAllCallbacks(canvas, XtNcallback); XtAddCallback(canvas, XtNcallback, azimut_trigger, (XtPointer) 2); return; } } else if ((unsigned)client_data == 2) { /* second point, remove the menu from the screen */ XtRemoveAllCallbacks(canvas, XtNcallback); if (call_data) { xp = (XPoint *) call_data; correct_fax_azimut(xp->x - xa, xp->y - ya); } } /* remove callbacks from canvas, re-activate azimut and lshift buttons, pop down the shell */ XtRemoveAllCallbacks(canvas, XtNcallback); XtVaSetValues(adj_s.azimut, XtNsensitive, True, NULL); XtVaSetValues(adj_s.lshift, XtNsensitive, True, NULL); XtPopdown(info_s.shell); } void namesave_cb(Widget w, XtPointer client_data, XtPointer call_data) { query_filename(&save_fsa); } void savefile_act(char *name) { int ret; ret = save_faxfile(name, save_width); switch(ret) { case SAVE_BUSY: simple_info("Save-file already open !\nClose this file first"); break; case SAVE_NPERM: simple_info("Cannot open save-file ?!"); break; case SAVE_OK: break; } } void autosave_cb(Widget w, XtPointer client_data, XtPointer call_data) { int ret; ret = save_faxfile(NULL, save_width); switch(ret) { case SAVE_BUSY: simple_info("Save-file already open !\nClose this file first"); break; case SAVE_NPERM: simple_info("Cannot open save-file ?!"); break; case SAVE_OK: break; } } void closesave_cb(Widget w, XtPointer client_data, XtPointer call_data) { close_faxsave(); } void quit_cb(Widget w, XtPointer client_data, XtPointer call_data) { exit(0); } void main(int argc, char **argv) { int i; Pixel respix[20]; unsigned nrespix; Dimension wid, hei; toplevel = XtAppInitialize(&mainapp, "ACfax", options, XtNumber(options), &argc, argv, fallbacks, NULL, 0); /* no arguments-list, 0 arguments */ XtGetApplicationResources(toplevel, (XtPointer)&prg_info, resources, XtNumber(resources), NULL, 0); dpy = XtDisplay(toplevel); scr = XtScreen(toplevel); XtAppAddActions(mainapp, acts, XtNumber(acts)); txt_trans = XtParseTranslationTable("#override \ Return: num-in()\n\ Linefeed: num-in()\n\ CtrlM: num-in()\n\ CtrlJ: num-in()\n"); /* cmap = DefaultColormap(dpy, scr); */ /* create widgets */ XtVaSetValues(toplevel, XtNtitle, "ACfax display", NULL); create_widgets(toplevel); XtRealizeWidget(toplevel); XtPopup(fax_shell, XtGrabNone); create_pixmaps(fax_form); fprintf(stderr,"allocing cmap\n"); fflush(stderr); for (i=0; i<20; i++) respix[i] = 0; respix[0] = BlackPixelOfScreen(scr); respix[1] = WhitePixelOfScreen(scr); XtVaGetValues(fax_form, XtNforeground, &respix[2], XtNbackground, &respix[3], #ifdef USE_XAW3D XtNtopShadowPixel, &respix[4], XtNbottomShadowPixel, &respix[5], #endif NULL); XtVaGetValues(mod_s.modemdesc, XtNbackground, &respix[6], NULL); for (i=0; i<13; i++) respix[i+7] = i; nrespix = 20; alloc_cmap(toplevel, respix, nrespix); update_area = update_pxm; mode_notify = op_changed; /* that's a hard one, but should set up all things right.... */ XtVaGetValues(canvas, XtNwidth, &wid, XtNheight, &hei, NULL); setup_fax(120, 288, (FAX_CNOR | FAX_CUNFL | FAX_CROT0 | FAX_LEF2RIG | FAX_TOP2BOT | FAX_HOR | FAX_PBLK | FAX_GRAY), toplevel, (unsigned)wid, (unsigned)hei, 500, (MOD_FM | FIL_MIDL)); aptstart = 300; aptstop = 450; show_values(); #if 0 for (i=0; i<10; i++) printf("level = %d\n", signal_level()); #endif receive_on(); fprintf(stderr,"filling cmap\n"); fflush(stderr); /* make the colormap active for our shells */ XtVaSetValues(toplevel, XtNcolormap, icmap, NULL); XtVaSetValues(fax_shell, XtNcolormap, icmap, NULL); XtVaSetValues(info_s.shell, XtNcolormap, icmap, NULL); /* get the pixmap where we have to draw in, and its GC */ cpxmap = canvasGetPixmap ((CanvasWidget)canvas, CanvasPicture); cgc = canvasGetGC ((CanvasWidget)canvas, CanvasDrawGC); fprintf(stderr,"initializing interface for FM reception...\n"); fflush(stderr); /* comp_val = max_val >> 1; aptncmax = smpl_sec / 100; ixoc = 576; aptstart = 300; aptstop = 450; bot2top = 0; right2left = 0; core_start = core_dta; smpl_line = (2000 << 16) + 34800; */ save_fsa.dir_io = malloc(256); *save_fsa.dir_io = '\0'; save_fsa.title = "Save file"; save_fsa.file_act = savefile_act; save_width = 1024; /* XtAddCallback(canvas, XtNcallback, show_coords, (XtPointer) NULL); */ XtAddCallback(dir_s.dirhv, XtNcallback, dirhv_cb, (XtPointer) NULL); XtAddCallback(dir_s.dirlr, XtNcallback, dirlr_cb, (XtPointer) NULL); XtAddCallback(dir_s.dirtb, XtNcallback, dirtb_cb, (XtPointer) NULL); XtAddCallback(pol_s.norinv, XtNcallback, norinv_cb, (XtPointer) NULL); XtAddCallback(pol_s.posneg, XtNcallback, posneg_cb, (XtPointer) NULL); XtAddCallback(run_s.rmstop, XtNcallback, stastop_cb, (XtPointer) NULL); XtAddCallback(run_s.rmsyn, XtNcallback, stastop_cb, (XtPointer) NULL); XtAddCallback(run_s.rmrun, XtNcallback, stastop_cb, (XtPointer) NULL); XtAddCallback(adj_s.lshift, XtNcallback, lshift_cb, (XtPointer) NULL); XtAddCallback(adj_s.azimut, XtNcallback, azimut_cb, (XtPointer) NULL); XtAddCallback(mod_s.mmode, XtNcallback, modmode_cb, (XtPointer) NULL); XtAddCallback(file_m.autosave, XtNcallback, autosave_cb, (XtPointer) NULL); XtAddCallback(file_m.saveas, XtNcallback, namesave_cb, (XtPointer) NULL); XtAddCallback(file_m.close, XtNcallback, closesave_cb, (XtPointer) NULL); XtAddCallback(file_m.quit, XtNcallback, quit_cb, (XtPointer) NULL); XtAddCallback(mod_s.mflt1, XtNcallback, filtsel_cb, (XtPointer)FIL_NARR); XtAddCallback(mod_s.mflt2, XtNcallback, filtsel_cb, (XtPointer)FIL_MIDL); XtAddCallback(mod_s.mflt3, XtNcallback, filtsel_cb, (XtPointer)FIL_WIDE); /* XtAddCallback(opt_start, XtNcallback, start_callback, (XtPointer) NULL); XtAddCallback(opt_stop, XtNcallback, stop_callback, (XtPointer) NULL); */ XtAppMainLoop(mainapp); } acfax/global.h100644 765 144 3703 6550716615 12611 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * global.h - header file for acfax.c */ #include #include #include #include #include /* this file contains some definitions and constants : */ #define C_WIDTH 800 #define C_HEIGHT 600 /* X11-related external variables */ extern Display *dpy; /* the X-Display to use */ extern Screen *scr; /* screen of the display */ extern Visual *cvisual; /* The visual to use */ extern Pixmap cpxmap; /* pixmap of the canvas widget */ extern GC cgc; /* GC for XPutImage to cpxmap */ extern XEvent event; /* for XtAppNextEvent / XtDispatchEvent */ extern Colormap cmap, rootcmap; /* colormap we use, and default-colormap */ extern Widget canvas; extern XtAppContext mainapp; /* extern XtIntervalId chstime; extern XImage *horimag, *verimag; / intermediate-storages / extern unsigned coltab[256]; / mapping table linear grayscale->pixel-value / extern unsigned canwid, canhei; / width/height of canvas widget / extern int xpos, ypos, imline; extern char *core_dta, *core_start, *core_wptr, *core_maxptr; */ acfax/fax_funcs.c100644 765 144 133660 6610157035 13356 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* fax_funcs.c - all fax-specific functions should be placed here. * This file depends on neary everything; It calls the hardware- * specific setup, the filter setup, and needs some X11- * variables for writing into the canvas. */ #include #include #include #include #include #include "x_image.h" #include #include "sblaster.h" #include "mod_demod.h" #include "widgets.h" #include "fax_funcs.h" /* some variables that are allowed to be global */ int lpm; /* lines per minute */ int ixoc; /* number of pixels of one scan-line / PI */ int devi; /* deviation in Hz (+/- of middle) */ int mod_mode; /* can be MOD_FM or MOD_AM */ int aptstart; /* possible APT start values */ int aptstop; /* possible APT stop values */ int aptdur; /* apt duration in millisecs (for transmitting) */ int vertical; /* vertical or horizontal line direction */ int right2left; /* boolean indicating reverse line writing direction */ int bot2top; /* boolean indicating reverse line stacking direction */ int invphase; /* polarity of phase-in-signal to use */ int invimage; /* inverse colormap usage */ /* and the private variables */ int fax_inited = 0; /* if fax_init was called */ unsigned canwid; /* width of the Pixmap to draw in */ unsigned canhei; /* height of the Pixmap */ int sxpos, sypos; /* current coordinates of received/xmitted data */ int pixpos, linepos; /* current coordinates of received/xmitted data */ int imline; /* currently processed line of XImage */ void (*update_area)(XImage *, int, int, int, int, unsigned, unsigned); /* called to copy XImage to Pixmap and update the window-area required */ void (*mode_notify)(int); /* notifies main program of changes of fax_state */ int mcolor; /* color-mode selected */ int dmaxval; /* number of usable grayscale-values - 1 */ int compval; /* comparator value for APT-counter */ int flip; /* flipping of green and blue parts of the colormap */ int rotate; /* rotation of the colormap */ int fax_state; /* one of FAX_APT, FAX_PHAS or FAX_RX */ char *core_dta; /* storage for raw demodulated data (accumulating) */ char *core_start; /* start of core for image-processing */ char *core_wptr; /* pointer to next written element in core_dta */ char *core_maxptr; /* pointer beyond the last element in core_dta */ void (*disp_func)(int); /* pointer to function displaying the data-stream */ int (*save_func)(int, int); /* pointer to function saving image to file */ void (*fax_tx_func)(int); /* pointer to function transmitting image */ int disp_locked; /* flag indicating that disp_func should not be called from fax_rx_backgnd */ int save_locked; /* same as above for save_func */ void (*apt_notify)(int); /* pointer to function evaluating APT frequency */ unsigned smplf; /* number of samples per second << 16 */ unsigned smpl_line; /* number of samples per line << 16 */ unsigned hsmpl_sec; /* half the number of samples per second */ int aptncmax; /* maximum "empty" points in an APT-line */ int phstate = 0; /* state (0=waiting, 1=active) of phase-finder */ int phlines; /* number of recognized phase-lines */ unsigned hsmpl_line; /* half the number of samples per line */ int phposa[24]; /* phase position A (middle of line) */ int phposb[24]; /* phase position B (edges of line) */ int phsdir[24]; /* phase direction (beginning or end of line) */ int phaseavg; /* average phase position calculated */ char *demod_ptr; /* pointer to raw demodulated data */ int demod_cnt; /* number of decoded points per call */ char *mod_ptr; /* pointer to raw data being modulated */ char *mod_end; /* pointer to first byte behind end of modulator-space */ FILE *fsfile; /* file pointer of current save-file */ char faxsavename[256]; /* current name of save-file */ char *saveline; /* storage for 1 image-line in save_func */ XtAppContext mainapp; /* main app.context (needed for interv.timer) */ XtIntervalId chstime; /* for the repetitive called background function */ XtInputId dspxid = 0; /* for the background function when using select() */ XEvent event; /* event needed to form the XtAppMainLoop */ unsigned twidth; /* width of transmitted image */ unsigned theight; /* height of transmitted image */ int tx_phlines; /* number of phase-in lines to be transmitted */ char *timg_ptr; /* array holding image to be transmitted (pixel oriented) */ FILE *ftfile; /* pointer to file-struct for transmission */ /* * init_fax initializes the "core"-space where the raw decoded data resides. * This practice is not very nice to memory-limited systems, but has the * advantage of being able to back up from nearly any setup-error (including * wrong lpm, IOC, direction and color-mode but excluding tuning-errors) */ void init_fax(void) { if (fax_inited) return; fprintf(stderr, "initializing FAX procedures and alloc'ing core-space\n"); lpm = 120; ixoc = 288; devi = 400; mod_mode = MOD_FM | FIL_MIDL; dmaxval = 63; compval = dmaxval >> 1; core_dta = malloc(CORESIZE); core_start = core_dta; core_wptr = core_dta; core_maxptr = core_dta + COREMAX; interface_init(&demod_ptr, &demod_cnt); setup_mode(mod_mode, dmaxval, devi, &smplf); hsmpl_sec = smplf >> 17; aptncmax = hsmpl_sec / 25; mod_end = demod_ptr + demod_cnt; mod_ptr = demod_ptr; fprintf(stderr, "smplf = %08x (16.16), demod_cnt = %d\n", smplf, demod_cnt); disp_func = decode_fax_gray; fax_tx_func = transmit_fax_gray; save_func = save_fax_gray; fsfile = NULL; saveline = NULL; apt_notify = apt_control; chstime = (XtIntervalId) 0; timg_ptr = NULL; ftfile = NULL; fax_inited = 1; } /* exit_fax frees the core_dta space, so that other program-parts may allocate memory without having a dead-space overhead. */ void exit_fax(void) { if (!fax_inited) return; free(core_dta); fax_inited = 0; } /* * setup_fax sets up all the variables for FAX-reception and transmission. * s_lpm : lines per minute (no change if set to 0) * s_ixoc: IOC to use (pixels per line = PI * IOC) (no change if set to 0) * mode : fax-specific mode setings such as writing direction and order, * phase-in polarity and grayscale or color-mode * s_devi: deviation to use for FM (no change if set to 0) * s_modem : (de-)modulator-specific settings as filter to use, AM or FM */ void setup_fax(int s_lpm, int s_ixoc, unsigned mode, Widget toplevel, unsigned width, unsigned height, int s_devi, unsigned s_modem) { unsigned id; unsigned filter, mmode; void (*old_func)(int); /* be sure initialisation is done */ init_fax(); mainapp = XtWidgetToApplicationContext(toplevel); /* if size is given or has changed, re-create X-images */ if ((width) || (height)) { if (width) canwid = width; if (height) canhei = height; create_images(toplevel, canwid, canhei); } /* check if the (de-)modulator needs readjustment */ filter = s_modem & FIL_MASK; mmode = s_modem & MOD_BITS; if ((filter) || (mmode) || (s_devi)) { fprintf(stderr, "setting filter & mmode = 0x%04x\n", (filter | mmode)); if (s_devi) { if (s_devi < 100) s_devi = 100; if (s_devi > 1200) s_devi = 1200; devi = s_devi; } setup_mode((filter | mmode), dmaxval, s_devi, &smplf); hsmpl_sec = smplf >> 17; aptncmax = hsmpl_sec / 25; if (filter) { mod_mode = (~FIL_MASK & mod_mode) | filter; } if (mmode) { mod_mode = (~MOD_BITS & mod_mode) | mmode; } } if (s_lpm) { if (s_lpm < 60) s_lpm = 60; if (s_lpm > 500) s_lpm = 500; lpm = s_lpm; fprintf(stderr, "changing lpm to %d\n", lpm); } if (s_ixoc) { if (s_ixoc < 60) s_ixoc = 60; if (s_ixoc > 600) s_ixoc = 600; ixoc = s_ixoc; fprintf(stderr, "changing ioc to %d\n", ixoc); } if ((id = mode & FAX_POL)) { if (id == FAX_CNOR) { invimage = 0; } else { invimage = 1; } fprintf(stderr, "setting invimage mode to %d\n", invimage); } if ((id = mode & FAX_CFLS)) { if (id == FAX_CUNFL) { flip = 0; } else { flip = 1; } fprintf(stderr, "setting color-flip to %d\n", flip); } if ((id = mode & FAX_CROTS)) { switch(id) { case FAX_CROT0: rotate = 0; break; case FAX_CROT1: rotate = 1; break; case FAX_CROT2: rotate = 2; break; } fprintf(stderr, "setting color-rotation to %d\n", rotate); } if ((id = mode & FAX_DIR)) { if (id & FAX_TOP2BOT) bot2top = 0; else if (id & FAX_BOT2TOP) bot2top = 1; if (id & FAX_LEF2RIG) right2left = 0; else if (id & FAX_RIG2LEF) right2left = 1; fprintf(stderr, "changing direction to h=%d, v=%d\n", right2left, bot2top); } if ((id = mode & FAX_ROT)) { if (id == FAX_HOR) { vertical = 0; } else { vertical = 1; } fprintf(stderr, "selecting %s direction\n", (vertical) ? "vertical" : "horizontal"); } if ((id = mode & FAX_PHS)) { if (id == FAX_PWHT) { invphase = 1; } else { invphase = 0; } fprintf(stderr, "phase inversion mode = %d\n", invphase); } if ((id = mode & FAX_CMODE)) { switch (id) { case FAX_GRAY: mcolor = 0; break; case FAX_COLOR: mcolor = 1; break; } fprintf(stderr, "receive mode is %s\n", (mcolor) ? "color" : "grayscale"); } /* now, all modifications to variables are done. some recomputations are to be done dependant on what has changed... */ if (mode & FAX_CMODS) if (mcolor) { fill_cmap_col(invimage, flip, rotate); } else { fill_cmap_gray(invimage); } if ((mode & (FAX_DIR | FAX_ROT | FAX_CMODE | FAX_CMODS)) || (s_ixoc) || (s_lpm) || (width) || (height) || (s_modem & MOD_BITS)) { if (mcolor) { disp_func = decode_fax_gray; save_func = save_fax_gray; } else { disp_func = decode_fax_gray; save_func = save_fax_gray; } /* recomputations are done in disp_func() */ fprintf(stderr, "initializing disp_func\n"); disp_func(D_CPINIT | D_WDINIT | D_LDINIT); /* now call function to re-create picture */ #if stillneeded /* the disp_func should lock itself */ old_func = disp_func; disp_func = NULL; fprintf(stderr, "calling disp_func to re-display image\n"); old_func(D_ALLOWX); disp_func = old_func; #else fprintf(stderr, "calling disp_func to re-display image\n"); disp_func(D_ALLOWX); #endif } if ((mmode) && (dspxid != 0)) { /* re-initiate data reception, because changing the modulation mode * (and thus changing the sample rate) requires the data stream to * stop. [Later, this should be RX or TX depending on what we do] */ fax_rx_backgnd((XtPointer) NULL, &dspfd, (XtInputId *) NULL); } } /* enable FAX reception: set auto-initializing background function */ void receive_on(void) { #ifndef DSP_SELECT if (chstime != (XtIntervalId) 0) return; #endif fax_state = FAX_APT; mode_notify(fax_state); #ifdef DSP_SELECT dspxid = XtAppAddInput(mainapp, dspfd, (XtPointer) XtInputReadMask, fax_rx_backgnd, (XtPointer) NULL); fprintf(stderr, "dspxid from XtAppAddInput is %ld\n", dspxid); /* initiate the reading of data. Once started, it is called by * XtAppMainLoop() which uses select() to listen on dspfd. */ fax_rx_backgnd((XtPointer) NULL, &dspfd, &dspxid); #else chstime = XtAppAddTimeOut(mainapp, 250, fax_rx_backgnd, (XtPointer) NULL); #endif } void receive_off(void) { #ifdef DSP_SELECT XtRemoveInput(dspxid); dspxid = (XtInputId) 0; #else XtRemoveTimeOut(chstime); #endif interface_stop(); chstime = (XtIntervalId) 0; } #ifdef DSP_SELECT /* this is the reception routine triggered upon input from DSP device */ void fax_rx_backgnd(XtPointer client_data, int *source, XtInputId *xid) #else /* this is the reception routine which calls itself after 250ms */ void fax_rx_backgnd(XtPointer client_data, XtIntervalId *xid) #endif { int space; /* if (init_rx) { init_rx = 0; core_wptr = core_dta; } */ /* fprintf(stderr, "receiving data\n"); */ /* get the input samples and demodulate the input data stream */ do_receive(); /* update the signal-level scrollbar display */ set_sigdisplay((double)rx_level / 255.0); /* always watch for APT frequencies */ /* fprintf(stderr, "decoding APT\n"); */ decode_apt(0); /* if we are in the phasing state, compute the phase-position */ if (fax_state == FAX_PHAS) sync_phase(0); /* copy the data into the core_dta array and advance the write-pointer */ if (fax_state == FAX_RX) { space = core_maxptr - core_wptr; if (space > demod_cnt) space = demod_cnt; memcpy(core_wptr, demod_ptr, space); core_wptr += space; } #ifdef DSP_SELECT /* we don't need to retrigger ourself - do nothing */ #else /* add a new timeout to call this function again */ /* printf("adding new timeout\n"); */ chstime = XtAppAddTimeOut(mainapp, 250, fax_rx_backgnd, (XtPointer) NULL); #endif /* if disp_func is set, call that function (e.g. main FAX decoder loop) */ if ((disp_func) && !(disp_locked)) { /* fprintf(stderr, "calling disp_func\n"); */ disp_func(0); } /* if save_func is set (saving of received image enabled), call function */ if ((save_func) && !(save_locked)) { /* fprintf(stderr, "calling save_func\n"); */ save_func(F_DOSAVE, 0); } } /* * grayscale FAX decoding main routine. * init is used to control the behavior and initialize some internal * variables. It is bit-wise coded as follows : * D_CPINIT : initialize read-pointer to start of core-buffer * D_WDINIT : initialize x-position to the start-value * D_LDINIT : initialize y-position to the start-value * D_ALLOWX : periodically call XtAppProcessEvent during processing * (requires that this function is NOT called from fax_rx_backgnd !) */ void decode_fax_gray(int init) { XtInputMask msk; #ifdef FAST8BIT static char *imptr; static char *imptinit; static int impinc; #endif /* pointer to sample-point for current pixel and current start-of-line */ static char *core_line, *core_pix; /* sample-values per line or per pixel-value, 16bit int, 16bit frac */ static unsigned inc_pix, inc_line; /* current index to pixel or line in sample-array, 16bit int, 16bit frac */ static unsigned idx_pix, idx_line, idx_p0; /* increment between actual and previous pixel/line position */ static unsigned ipix, iline; /* pixel-in-line-position start/increment/end */ static int pixinit, pixinc, pixend; /* line-in-image-position start/increment/end, max. line of XImage */ static int lineinit, lineinc, lineend, imgmax; static int (*put_pix)(struct _XImage *, int, int, unsigned long); if (init & D_INITS) { /* smpl_line is the number of core_dta points per line << 16 */ smpl_line = 60.0 / lpm * smplf; if (vertical) { inc_pix = smpl_line / canhei; inc_line = (int)(ixoc * PI * 65536.0 / canhei); imgmax = DEFWIDTH; put_pix = verimag->f.put_pixel; } else { inc_pix = smpl_line / canwid; inc_line = (int)(ixoc * PI * 65536.0 / canwid); imgmax = DEFHEIGHT; put_pix = horimag->f.put_pixel; } if (!(vertical) && (right2left)) { pixinit = canwid - 1; pixinc = -1; pixend = -1; #ifdef FAST8BIT imptinit = horimag->data + canwid - 1; impinc = -1; #endif } else if ((vertical) && (bot2top)) { pixinit = canhei - 1; pixinc = -1; pixend = -1; #ifdef FAST8BIT imptinit = verimag->data + (canhei - 1) * verimag->bytes_per_line; impinc = -verimag->bytes_per_line; #endif } else { pixinit = 0; pixinc = 1; pixend = (vertical) ? canhei : canwid; #ifdef FAST8BIT imptinit = (vertical) ? verimag->data : horimag->data; impinc = (vertical) ? verimag->bytes_per_line : 1; #endif } /* initialize the line-advance variables and pointers */ if (!(vertical) && (bot2top)) { lineinit = canhei - DEFHEIGHT; lineinc = -1; lineend = -1; } else if ((vertical) && (right2left)) { lineinit = canwid - DEFWIDTH; lineinc = -1; lineend = -1; } else { lineinit = 0; lineinc = 1; lineend = (vertical) ? canwid : canhei; } if (init & D_WDINIT) { pixpos = pixinit; } if (init & D_LDINIT) { linepos = lineinit; if ((!(vertical) && (bot2top)) || ((vertical) && (right2left))) imline = imgmax - 1; else imline = 0; } #ifdef FAST8BIT if ((init & D_LDINIT) || (init & D_WDINIT)) { imptr = imptinit + impinc * pixpos; if (vertical) imptr += imline; else imptr += horimag->bytes_per_line * imline; } #endif if (init & D_CPINIT) { /* initialize the fractional index pointers */ idx_pix = idx_line = idx_p0 = 0; core_pix = core_line = core_start; ipix = iline = 0; } fprintf(stderr,"initialisation done :\n" "pixinit = %d, pixinc = %d, pixend = %d\n" "lineinit = %d, lineinc = %d, lineend = %d\n" "imline = %d, imgmax = %d\n", pixinit, pixinc, pixend, lineinit, lineinc, lineend, imline, imgmax); disp_locked = 0; return; } if (init & D_ALLOWX) { printf("redrawing from %d, %d, corepos = %d\n", pixpos, linepos, core_pix - core_dta); } disp_locked = 1; do { /* if it is better to wait for more data, cancel function and wait until it is called next time */ if (core_pix >= core_wptr) break; /* enter a new brightness-value (0..63) into core_dta */ #ifdef FAST8BIT *imptr = coltab[*(unsigned char *)core_pix]; imptr += impinc; #else if (vertical) put_pix(verimag, imline, pixpos, coltab[*(unsigned char *)core_pix]); else put_pix(horimag, pixpos, imline, coltab[*(unsigned char *)core_pix]); #endif /* shift the x-position, and if we have reached the end... */ pixpos += pixinc; if (pixpos == pixend) { /* re-start from left border */ pixpos = pixinit; /* now we have one more complete line, copy it from core_dta to the horimag (an Ximage). Use fast methode by advancing pointers */ /* check if we wave filled up all lines of horimag, or if we just have got as many lines that we can complete the picture. */ imline += lineinc; if ((imline == imgmax) || (imline < 0) || (linepos + imline == lineend)) { while ((init & D_ALLOWX) && ((msk = XtAppPending(mainapp)))) { XtAppProcessEvent(mainapp, msk); } if (vertical) if (right2left) { update_area(verimag, 0, 0, linepos, 0, (DEFWIDTH-1) - imline, canhei); } else { update_area(verimag, 0, 0, linepos, 0, imline, canhei); } else if (bot2top) { update_area(horimag, 0, 0, 0, linepos, canwid, (DEFHEIGHT-1) - imline); } else { update_area(horimag, 0, 0, 0, linepos, canwid, imline); } if (((vertical) && (right2left)) || (!(vertical) && (bot2top))) { imline = imgmax - 1; linepos -= imgmax; if (linepos < 0) linepos = lineinit; } else { imline = 0; linepos += imgmax; if (linepos >= lineend) linepos = 0; } } #ifdef FAST8BIT if (vertical) imptr = imptinit + imline; else imptr = imptinit + horimag->bytes_per_line * imline; #endif idx_line += inc_line; iline = (idx_line >> 16) & 0xffff; idx_line &= 0xffff; core_line += iline * ((smpl_line >> 16) & 0xffff); /* we must also initialize the pixel-counters here ! */ idx_p0 += iline * (smpl_line & 0xffff); core_line += (idx_p0 >> 16) & 0xffff; core_pix = core_line; idx_p0 &= 0xffff; idx_pix = idx_p0; ipix = 0; /* jump over the stuff below... */ continue; } /* shift the sample-point (16 bits integer, 16 bits fractional part) */ idx_pix += inc_pix; ipix = (idx_pix >> 16) & 0xffff; core_pix += ipix; idx_pix &= 0xffff; } while (1); if (init & D_FLUSHIMG) { if (vertical) if (right2left) { update_area(verimag, 0, 0, linepos, 0, (DEFWIDTH-1) - imline, canhei); } else { update_area(verimag, 0, 0, linepos, 0, imline, canhei); } else if (bot2top) { update_area(horimag, 0, 0, 0, linepos, canwid, (DEFHEIGHT-1) - imline); } else { update_area(horimag, 0, 0, 0, linepos, canwid, imline); } } disp_locked = 0; } /* * this function should be used by the main program to initiate saving * of an image. If name is not given, it is constructed of date and time. */ int save_faxfile(char *name, int width) { time_t tp; char date[16]; /* string to build date for automatic savefile-name */ /* check if save-file is already open */ if (fsfile) return SAVE_BUSY; /* if no name is given, generate autosave-filename from date and time */ if (name) { strcpy(faxsavename, name); } else { time(&tp); strftime(date, 14, "%m.%d-%H:%M", localtime(&tp)); sprintf(faxsavename, "%s/faxsave_%s.pgm", FAX_SAVEDIR, date); } return save_func(F_OPEN, width); } /* properly close the save-file */ void close_faxsave(void) { if (!(fsfile)) return; save_func(F_GETDIM, 0); save_func(F_DOSAVE, 0); save_func(F_CLOSE, 0); } /* * fax-image saving function, writes grayscale ppm-images (pgm). * The image cannot be rotated, only flipped in writing-direction. * init defines the action to be done : * F_DOSAVE : save image if file is opened, close when completed * F_OPEN : open file, faxsavename contains the name and width the width * of the image. If width is not given, the best resolution is taken * (width = PI * IOC) * F_CLOSE : close file and adjust data in header to actual values * F_GETDIM : get dimensions and parameters of image into internal variables * the filename must previously be put into faxsavename. */ int save_fax_gray(int init, int width) { XtInputMask msk; /* width and height of saved image */ static unsigned swidth, sheight; static char *ldptr, *ldpinit, *ldpend; static int ldpinc; /* end of picture in core-space */ static char *save_wptr = NULL; /* pointer to sample-point for current pixel and current start-of-line */ static char *core_line, *core_pix; /* sample-values per line or per pixel-value, 16bit int, 16bit frac */ static unsigned inc_pix, inc_line; /* current index to pixel or line in sample-array, 16bit int, 16bit frac */ static unsigned idx_pix, idx_line, idx_p0; /* increment between actual and previous pixel/line position */ static unsigned ipix, iline; /* pixel-in-line-position start/increment/end */ /* static int pixinit, pixinc, pixend; */ /* line-in-image-position start/increment/end, max. line of XImage */ /* static int lineinit, lineinc, lineend, imgmax; */ /* whether the writing-direction must be reversed */ static int flip; int pos; if (init == F_OPEN) { /* close "old" file first */ if (fsfile) save_fax_gray(F_CLOSE, 0); if (width > 0) swidth = width; else swidth = (ixoc * PI) + 0.5; fsfile = fopen(faxsavename, "wb"); if (!(fsfile)) { return SAVE_NPERM; } fprintf(stderr, "save file \"%s\", %d pix/line\n", faxsavename, swidth); fputs("P5\nxxxxx\nyyyyy\n63\n", fsfile); /* allocate space for the one line */ saveline = malloc(swidth + 4); /* do not initialize too much here, the user may change parameters of the picture while receiving... */ save_wptr = NULL; return SAVE_OK; } else if (init == F_CLOSE) { if (!(fsfile)) return SAVE_OK; /* no save-file open, doesn't matter */ fprintf(stderr,"closing savefile\n"); pos = ftell(fsfile); sheight = sypos; rewind(fsfile); fprintf(fsfile, "P5\n%05u\n%05u\n", swidth, sheight); fseek(fsfile, pos, SEEK_SET); fclose(fsfile); fsfile = NULL; if (saveline) free(saveline); save_wptr = NULL; return SAVE_OK; } else if (init == F_GETDIM) { if (!(fsfile)) return SAVE_NFILE; /* no save-file open, can't get dimensions */ /* now initialize all the variables... */ fprintf(stderr, "getting image settings..."); inc_pix = smpl_line / swidth; inc_line = (int)(ixoc * PI * 65536.0 / swidth); idx_pix = idx_line = idx_p0 = 0; core_pix = core_line = core_start; save_wptr = core_wptr; ipix = iline = 0; flip = (vertical) ? 1 : 0; if (bot2top) flip ^= 1; if (right2left) flip ^= 1; if (flip) { ldpinit = saveline + (swidth - 1); ldpinc = -1; ldpend = saveline - 1; } else { ldpinit = saveline; ldpinc = 1; ldpend = saveline + swidth; } ldptr = ldpinit; sypos = 0; sheight = 0; return SAVE_OK; } /* no open save-file, or variables not initialized, so return */ if (!(fsfile) || !(save_wptr)) return SAVE_NFILE; save_locked = 1; fprintf(stderr,"saving image..."); while (core_pix < save_wptr) { if (invimage) *ldptr = dmaxval - *(unsigned char *)core_pix; else *ldptr = *(unsigned char *)core_pix; ldptr += ldpinc; if (ldptr == ldpend) { ldptr = ldpinit; sypos++; fwrite(saveline, swidth, 1, fsfile); while ((msk = XtAppPending(mainapp))) { XtAppProcessEvent(mainapp, msk); } idx_line += inc_line; iline = (idx_line >> 16) & 0xffff; idx_line &= 0xffff; core_line += iline * ((smpl_line >> 16) & 0xffff); /* we must also initialize the pixel-counters here ! */ idx_p0 += iline * (smpl_line & 0xffff); core_line += (idx_p0 >> 16) & 0xffff; core_pix = core_line; idx_p0 &= 0xffff; idx_pix = idx_p0; ipix = 0; /* jump over the stuff below... */ continue; } idx_pix += inc_pix; ipix = (idx_pix >> 16) & 0xffff; core_pix += ipix; idx_pix &= 0xffff; } fprintf(stderr,"done.\n"); save_locked = 0; return SAVE_OK; } /* called when save-function has terminated writing */ void faxsave_complete(int init) { /* this makes save_func call itself recursively, but should not hurt */ save_func(F_CLOSE, 0); } /* * wait for a phasing signal, keep track of the phase-pulses, and preset * core_start on end of the phase_signal. This is done by correlating the * digitized gray-values (reduced to 1 or 0) with two sawtooth-signals, * each with a periode of one scan line, and one of them shifted by a * half scan-line against the other. This lets us find the position of * the phase-pulse relative to our scan-line. Lines are recognized as * phase-in-lines when they contain at most 3/32 and at least 1/32 of values * that are above (or below for inverse phase) the middle of the gray-scale. */ void sync_phase(int init) { /* run counters, count pixels per line (16bit int, 16bit frac) */ static int phsarc, phsbrc; /* accumulators for the integration */ static int phsaacc = 0, phsbacc = 0; /* these are counted up until limit to form the sawtooth-signal */ static int phsainc, phsbinc; /* number of sample-points processed */ static int npoints = 0; /* number of points having the right level (black) for a sync pulse */ static int nphpts = 0; /* minimum/maximum number of black points per line that must be present */ static int minphpts, maxphpts; static char done = 0; char *dtaptr; int pcnt; int i,j; dtaptr = demod_ptr; pcnt = demod_cnt; if (init) { phstate = 0; hsmpl_line = smpl_line >> 17; phsaacc = phsbacc = 0; phsarc = smpl_line; phsbrc = smpl_line >> 1; phsainc = - hsmpl_line; phsbinc = 0; minphpts = (smpl_line >> 16) >> 5; maxphpts = minphpts * 3; nphpts = 0; phlines = 0; done = 0; core_wptr = core_dta; core_start = core_dta; fprintf(stderr, "initialized sync-phase-detector\n"); return; } while (pcnt > 0) { if ((!(invphase) && *dtaptr > compval) || ((invphase) && *dtaptr < compval)) { phsaacc += phsainc; phsbacc += phsbinc; nphpts++; } phsainc++; phsbinc++; npoints++; dtaptr++; pcnt--; phsarc -= 65536; if (phsarc <= 0) { done = 1; /* this indicates the end-of-line */ phsarc += smpl_line; phsainc = - hsmpl_line; } phsbrc -= 65536; if (phsbrc <= 0) { phsbrc += smpl_line; phsbinc = - hsmpl_line; } if (done) { #if (DEBUG & DBG_SYN) fprintf(stderr, "got line with %d of %d points phase-value\n", nphpts, npoints); #endif /* check if it was probably a phase-in line */ if (nphpts < maxphpts && nphpts > minphpts) { if (phlines < 24) { /* use the accumulator with the lower absolute-value */ if (abs(phsaacc) < abs(phsbacc)) { i = phsaacc / nphpts; #if (DEBUG & DBG_SYN) fprintf(stderr, "sync line %d: A=%d\n", phlines, i); #endif phposa[phlines] = i; if (i < 0) phsdir[phlines] = 1; /* left half */ else phsdir[phlines] = 0; /* right half */ } else { i = phsbacc / nphpts; #if (DEBUG & DBG_SYN) fprintf(stderr, "sync line %d: B=%d\n", phlines, i); #endif phposb[phlines] = i; if (i < 0) phsdir[phlines] = 2; /* right half */ else phsdir[phlines] = 3; /* left half */ } if (phstate == 0) { /* first sync line */ phstate = 1; } else if (phstate == 1) { /* any sync line */ } phlines++; } else { /* phlines >= 24 */ /* ignore any further sync-lines... */ } } else { /* no sync line, we are still waiting for one or they have passed */ if (phstate == 0) { /* no sync line yet - just wait ?! */ } else if (phstate == 1) { /* now begin to compute the ultimate sync-position */ j = 0; /* count the lines in the left half */ for (i=0; i (phlines >> 1)) { /* more points in the left half */ #if (DEBUG & DBG_SYN) fprintf(stderr, "calculating for left half...\n"); #endif for (i=0; i> 16); i = demod_cnt - pcnt + phaseavg; if (i > j) i -= j; /* start decoding at the beginning of the core */ core_wptr = core_dta; core_start = core_dta + i; /* now enter the real reception mode. When returning into the fax_rx_backgnd, fax_state is set to FAX_RX so that the data we just processed can also be used for the picture. */ fax_rx_start(1); /* no more data to process */ return; } } /* if (sync_line_detected) */ /* re-initialize the both accumulators and sample-point counters */ phsaacc = 0; phsbacc = 0; npoints = 0; nphpts = 0; done = 0; } /* if (done) */ } /* while (pcnt > 0) */ } /* * calculate the APT frequency by counting low->high->low transitions. * not very nice, but it works :-S . This funcion always computes the * APT for 0.5 seconds, independant from demod_cnt, which can be very * high on systems that use a large block-size for the audio-devide. * After each calculation, apt_notify() is called with the frequency as * argument. */ void decode_apt(int dummy) { /* how many transitions (half-waves) we have counted */ static int apthws = 0; /* how many consecutive points were on one side of the comparator-value */ static int aptncact = 0; /* the phase (black or white) we processed last time */ static int phs = 0; static int npoints = 0; char *dtaptr; int pcnt; dtaptr = demod_ptr; pcnt = demod_cnt; /* If we have to start with the "black" phase, do it before the main-loop starts. This prevents us from ugly goto's (shudder) */ if (phs) { while (pcnt) { pcnt--; if (++npoints >= hsmpl_sec) { apt_notify(apthws); apthws = 0; npoints = 0; } if (*(unsigned char *)dtaptr++ <= compval) { if (aptncact > aptncmax) apthws = 0; else apthws++; break; } aptncact++; } } while (pcnt > 0) { aptncact = 0; while (pcnt) { pcnt--; if (++npoints >= hsmpl_sec) { #if (DEBUG & DBG_APT) fprintf(stderr,"APT freq. pos = %d\n", apthws); #endif apt_notify(apthws); apthws = 0; npoints = 0; } if (*(unsigned char *)dtaptr++ > compval) { if (aptncact > aptncmax) apthws = 0; else apthws++; break; } aptncact++; } aptncact = 0; while (pcnt) { pcnt--; if (++npoints >= hsmpl_sec) { #if (DEBUG & DBG_APT) fprintf(stderr,"APT freq. neg = %d\n", apthws); #endif apt_notify(apthws); apthws = 0; npoints = 0; } if (*(unsigned char *)dtaptr++ <= compval) { if (aptncact > aptncmax) apthws = 0; else apthws++; break; } aptncact++; } } /* now mark the phase for the next call... */ if (*(unsigned char *)(dtaptr-1) <= compval) phs = 0; else phs = 1; } void apt_control(int aptfrq) { static int cnt; /* fprintf(stderr, "apt_control: %d\n", aptfrq); */ switch (fax_state) { /* wait for one of the valid APT frequencies */ case FAX_APT: if (abs(aptfrq - aptstart) < 2) { if (++cnt >= 2) fax_rx_phase(1); } else { cnt = 0; } break; /* here, a new start or a stop (interrupt) may occur */ case FAX_PHAS: case FAX_RX: if (abs(aptfrq - aptstop) < 2) { if (++cnt >= 2) fax_rx_stop(1); } else { cnt = 0; } break; } } void fax_rx_start(int internal) { fprintf(stderr,"starting fax reception\n"); /* if we come from phasing, initialize disp_func */ if (fax_state == FAX_PHAS) disp_func(D_CPINIT | D_WDINIT | D_LDINIT); fax_state = FAX_RX; if (internal) mode_notify(fax_state); } void fax_rx_phase(int internal) { fprintf(stderr,"entering phase-in mode\n"); sync_phase(1); fax_state = FAX_PHAS; if (internal) mode_notify(fax_state); } void fax_rx_stop(int internal) { fprintf(stderr,"stopping fax reception\n"); fax_state = FAX_APT; /* flush rest of image (in horimag/verimag) */ disp_func(D_FLUSHIMG); /* get current image-parameters for saving */ save_func(F_GETDIM, 0); save_func(F_DOSAVE, 0); save_func(F_CLOSE, 0); if (internal) mode_notify(fax_state); } /* * this function is called by the callback-function of the Canvas-widget * to move the picture in writing-direction, when phasing in has failed * or was missed. px and py contain the coordinates of the button-press. */ void shift_fax_coords(unsigned px, unsigned py) { void (*old_func)(); unsigned tmp_pos; fprintf(stderr, "coords = %d, %d\n", px, py); old_func = disp_func; disp_func = NULL; if (vertical) { if (bot2top) tmp_pos = smpl_line / canhei * (canhei - py); else tmp_pos = smpl_line / canhei * py; } else { if (right2left) tmp_pos = smpl_line / canwid * (canwid - px); else tmp_pos = smpl_line / canwid * px; } core_start += (tmp_pos >> 16); tmp_pos = (smpl_line >> 16); if (core_start - core_dta > tmp_pos) core_start -= tmp_pos; old_func (D_CPINIT | D_WDINIT | D_LDINIT); old_func (D_ALLOWX); disp_func = old_func; } /* * this function is called by the callback-function of the Canvas-widget * to re-adjust the sampling frequency to correct the line-shifting * caused by slightly deadjusted samling frequency. */ void correct_fax_azimut(int dx, int dy) { void (*old_func)(); int flip; int df; fprintf(stderr, "coords = %d, %d\n", dx, dy); flip = 0; if (right2left) flip ^= 1; if (bot2top) flip ^= 1; if (vertical) { df = (smplf * (double)dy) / (dx * PI * ixoc); } else { df = (smplf * (double)dx) / (dy * PI * ixoc); } if (flip) df = -df; smplf += df; fprintf(stderr, "delta freq.=%2.3f smplf=%4.3f\n", (double)df / 65536.0, (double)smplf / 65536.0); tune_frequency(smplf); old_func = disp_func; disp_func = NULL; old_func (D_CPINIT | D_WDINIT | D_LDINIT); old_func (D_ALLOWX); disp_func = old_func; } /*----------------------- FAX transmission --------------------------*/ void fax_tx_stop(int internal) { fprintf(stderr,"stopping FAX-transmission\n"); if (internal) mode_notify(fax_state); } void fax_tx_start(int internal) { fprintf(stderr,"transmitting image\n"); fax_state = FATX_TX; fax_tx_func(D_WDINIT | D_LDINIT); if (internal) mode_notify(fax_state); } void fax_tx_apta(int internal) { fprintf(stderr,"transmitting APT-start\n"); transmit_apt(APTX_ISTART); fax_state = FATX_APTA; if (internal) mode_notify(fax_state); } void fax_tx_aptb(int internal) { fprintf(stderr,"transmitting APT-stop\n"); transmit_apt(APTX_ISTOP); fax_state = FATX_APTB; if (internal) mode_notify(fax_state); } void fax_tx_phase(int internal) { fprintf(stderr,"entering TX-phase-in mode\n"); transmit_phase(1); fax_state = FATX_PHAS; if (internal) mode_notify(fax_state); } int load_txfile(char *name) { char line[80]; char lctab[256]; char *pline, *sp; int ncols; int color; char *cp; int i,j; if (timg_ptr) free(timg_ptr); if ((ftfile = fopen(name, "rb")) == NULL) { perror("open_txfile"); return -1; } if (fgets(line, 79, ftfile) == NULL) { perror("read_format"); return -1; } if (!strcmp(line, "P5\n")) color = 0; else if (!strcmp(line, "P6\n")) color = 1; else return -2; /* unrecognized format */ if (color) return -3; /* not yet supported */ do { if (fgets(line, 79, ftfile) == NULL) { perror("read_header"); return -1; } } while (*line == '#'); twidth = atoi(line); if (fgets(line, 79, ftfile) == NULL) { perror("read_header"); return -1; } theight = atoi(line); if (fgets(line, 79, ftfile) == NULL) { perror("read_header"); return -1; } timg_ptr = malloc(twidth*theight); pline = malloc(twidth); if (!(timg_ptr) || !(pline)) { if (timg_ptr) free(timg_ptr); if (pline) free(pline); perror("alloc_txmem"); return -4; } ncols = atoi(line) + 1; if (ncols > 256) return -3; for (i=0; if.put_pixel; bytes_per_pixel = twidth; bytes_per_line = 1; } else { inc_pix = smpl_line / twidth; inc_line = (int)(ixoc * PI * 65536.0 / twidth); imgmax = DEFHEIGHT; put_pix = horimag->f.put_pixel; bytes_per_pixel = 1; bytes_per_line = twidth; } if (!(vertical) && (right2left)) { pixinit = twidth - 1; pixinc = -1; pixend = -1; bytes_per_pixel = -bytes_per_pixel; } else if ((vertical) && (bot2top)) { pixinit = theight - 1; pixinc = -1; pixend = -1; bytes_per_pixel = -bytes_per_pixel; } else { pixinit = 0; pixinc = 1; pixend = (vertical) ? theight : twidth; } /* initialize the line-advance variables and pointers */ if (!(vertical) && (bot2top)) { lineinit = theight - 1; lineinc = -1; lineend = -1; bytes_per_line = -bytes_per_line; } else if ((vertical) && (right2left)) { lineinit = twidth - 1; lineinc = -1; lineend = -1; bytes_per_line = -bytes_per_line; } else { lineinit = 0; lineinc = 1; lineend = (vertical) ? twidth : theight; } } if (init) { timg_line = timg_ptr; /* twidth, theight, timg_ptr */ if (vertical) { inc_pix = 65536.0 * theight * lpm / ((60.0/65536.0) * smplf); inc_line = 65536.0 * theight / (PI * ixoc); } else { inc_pix = 65536.0 * twidth * lpm / ((60.0/65536.0) * smplf); inc_line = 65536.0 * twidth / (PI * ixoc); } if (right2left) { pixinc = -1; timg_line += (twidth - 1); } else { pixinc = 1; } if (bot2top) { pixinc = -twidth; timg_line += (theight - 1) * twidth; } else { pixinc = twidth; } timg_pix = timg_line; inc_p0 = 0; return; } while (mod_ptr < mod_end) { *mod_ptr++ = *timg_pix; pixpos += pixinc; if (pixpos == pixend) { pixpos = pixinit; linepos += lineinc; if (linepos == lineend) { /* we have transmitted the entire picture ! */ break; } idx_line += inc_line; iline = (idx_line >> 16) & 0xffff; idx_line &= 0xffff; timg_pix += bytes_per_pixel; timg_pix += iline * twidth; /* twidth == bytes_per_line */ continue; /* jump over stuff below */ } idx_pix += inc_pix; ipix = (idx_pix >> 16) & 0xffff; idx_pix &= 0xffff; timg_pix += ipix * bytes_per_pixel; } fax_tx_aptb(1); } /* * transmit an APT-tone. This function returns if either the pointer to * decptr reaches the end of the buffer or the duration is reached. * init can have the following values : * APTX_ISTART: initialize for aptstart-frequency * APTX_ISTOP: initialize for apt stop-frequency * 0: start/continue transmission */ void transmit_apt(int init) { XtInputMask msk; static int acc = 0; static int ap_inc; static int dur; if (init == APTX_ISTART) { ap_inc = 4.294967296e6 * aptstart / (double) smplf; dur = (smplf >> 16) * aptdur / 1000; return; } else if (init == APTX_ISTOP) { ap_inc = 4.294967296e6 * aptstop / (double) smplf; dur = (smplf >> 16) * aptdur / 1000; return; } while ((dur > 0) && (mod_ptr < mod_end)) { acc += ap_inc; if (acc & 0x8000) *mod_ptr = dmaxval; else *mod_ptr = 0; mod_ptr++; dur--; } if (mod_ptr >= mod_end) mod_ptr = demod_ptr; if (dur <= 0) { if (fax_state == FATX_APTA) fax_tx_phase(1); else fax_tx_stop(1); } } /* * transmit the phase-in signal for the image, which consists of 95% black * and 5% white (or inverted if invphase is set). These 5% have to appear * as one half to both the left and right margin of the image. The phase * where we start is not important, but where we stop and give control * to the function transmitting the contents of the loaded image. * tx_phlines determines the number of lines for phasing, after which * a line with 100% white is intersected to start the receiver. * if init is set, variables are initialized and the function returns. */ void transmit_phase(int init) { static int inc_pix; static int idx_pix; static int idx_min, idx_max; static int txlines; if (init) { inc_pix = lpm * (double) smplf / 60; idx_min = 1638; idx_max = 63807; idx_pix = 0x8000; txlines = tx_phlines + 1; return; } while ((txlines >= 0) && (mod_ptr < mod_end)) { idx_pix += inc_pix; if (idx_pix > 63807 || idx_pix < 1638) *mod_ptr = (invphase ? 0 : dmaxval); else *mod_ptr = (invphase ? dmaxval : 0); mod_ptr++; if (idx_pix > 0xffff) txlines--; idx_pix &= 0xffff; } if (mod_ptr >= mod_end) mod_ptr = demod_ptr; if (txlines <= 0) fax_tx_start(1); } acfax/fax_funcs.h100644 765 144 12675 6605446700 13351 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * fax_funcs.h : function declarations and external variable declarations * for all fax-related computing */ /* This is the size of the internal raw image storage. Adjust it so that the largest picture to expect can fit into memory (4000 * time_in_sec) */ #define CORESIZE (4560 << 10) #define COREMAX (CORESIZE - 1) /* set this to pre-define a directory for saving fax-pictures */ #define FAX_SAVEDIR "." /* #define FAX_SAVEDIR "/usr/local/faxsave" */ /* define this if you run on 8-bit X-displays only, it can speed up the image-redrawing by replacing XPutPixel by direct access to memory : */ /* #define FAST8BIT */ /* debugging flags */ #define DEBUG 0 #define DBG_APT 2 #define DBG_SYN 4 /* decoding function: initialisation types (see fax_funcs.c) */ #define D_CPINIT 0x00000001 #define D_WDINIT 0x00000002 #define D_LDINIT 0x00000004 #define D_INITS 0x00000007 #define D_ALLOWX 0x00000008 #define D_FLUSHIMG 0x00000010 /* inverting of color- or grayscale-map, color-flip and rotation possibilities */ #define FAX_CNOR 0x00000001 #define FAX_CINV 0x00000002 #define FAX_POL 0x00000003 #define FAX_CUNFL 0x00000004 #define FAX_CFLIP 0x00000008 #define FAX_CFLS 0x0000000c #define FAX_CROT0 0x00000010 #define FAX_CROT1 0x00000020 #define FAX_CROT2 0x00000030 #define FAX_CROTS 0x00000030 #define FAX_CMODS (FAX_CROTS | FAX_CFLS | FAX_POL) /* writing directions for the FAX transmission and reception */ #define FAX_DIR 0x00000f00 #define FAX_TOP2BOT 0x00000100 #define FAX_BOT2TOP 0x00000200 #define FAX_LEF2RIG 0x00000400 #define FAX_RIG2LEF 0x00000800 /* direction order / line direction */ #define FAX_ROT 0x00003000 #define FAX_HOR 0x00001000 #define FAX_VER 0x00002000 /* phase-signal polarity */ #define FAX_PHS 0x0000c000 #define FAX_PWHT 0x00004000 #define FAX_PBLK 0x00008000 /* color mode definitions */ #define FAX_CMODE 0x000f0000 #define FAX_GRAY 0x00010000 #define FAX_COLOR 0x00020000 /* fax receiver/transmitter status flag */ #define FAX_APT 1 #define FAX_PHAS 2 #define FAX_RX 3 #define FATX_APTA 16 #define FATX_PHAS 17 #define FATX_TX 18 #define FATX_APTB 19 /* fax file-save opearations */ #define F_DOSAVE 0 /* save image with captured parameters & close */ #define F_OPEN 1 /* open new savefile, write header */ #define F_CLOSE 2 /* close savefile, correct header */ #define F_GETDIM 3 /* capture current parameters for saving */ /* fax file-save return values */ #define SAVE_OK 0 #define SAVE_NPERM 1 #define SAVE_BUSY 2 #define SAVE_NFILE 3 /* fax apt-transmit initialisation commands */ #define APTX_ISTART 1 #define APTX_ISTOP 2 struct fax_savestruct { char *name; int width; int height; }; /* * NOTE : these variables are made global for read-only purposes ! * to change any of these, use setup_fax(). */ extern int lpm; /* current lines-per-minute */ extern int ixoc; /* current index-of-cooperation */ extern int devi; /* current selected deviation (for FM) */ extern int mod_mode; /* current filter and mod.mode (see mod_demod.h) */ extern int vertical; /* writing direction order vertical first */ extern int right2left; /* writing direction horizontal */ extern int bot2top; /* writing direction vertical */ extern int invphase; /* inverse phase detection */ extern int invimage; /* inverse image display */ /* * these may be changed directly : */ extern int aptstart; /* current APT start frequency */ extern int aptstop; /* current APT stop frequency */ extern void (*update_area)(XImage *, int, int, int, int, unsigned, unsigned); extern void (*mode_notify)(int); extern FILE *fsfile; void init_fax(void); void exit_fax(void); void setup_fax(int, int, unsigned, Widget, unsigned, unsigned, int, unsigned); void receive_on(void); void receive_off(void); #ifdef DSP_SELECT void fax_rx_backgnd(XtPointer, int *, XtInputId *); #else void fax_rx_backgnd(XtPointer, XtIntervalId *); #endif void decode_fax_gray(int); int save_faxfile(char *, int); void close_faxsave(void); int save_fax_gray(int, int); void faxsave_complete(int); void sync_phase(int); void decode_apt(int); void apt_control(int); void fax_rx_start(int); void fax_rx_phase(int); void fax_rx_stop(int); void shift_fax_coords(unsigned, unsigned); void correct_fax_azimut(int, int); void fax_tx_stop(int); void fax_tx_start(int); void fax_tx_apta(int); void fax_tx_aptb(int); void fax_tx_phase(int); int load_txfile(char *name); #ifdef DSP_SELECT void fax_tx_backgnd(XtPointer client_data, int *, XtInputId *xid); #else void fax_tx_backgnd(XtPointer client_data, XtIntervalId *xid); #endif void transmit_fax_gray(int init); void transmit_apt(int init); void transmit_phase(int init); acfax/sblaster.c100644 765 144 16467 6605505240 13205 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * sblaster.c - this file should contain all hardware-dependent functions * on top of mod_demod.c for the SoundBlaster under linux. */ #include #include #include #include #include #include "mod_demod.h" #include "sblaster.h" #include static int afd, mfd; static int blsize; static int decsize; static int amode; static int aspeed; static int afilter; static int adevi; static int amaxval; int rx_level; int dspfd; char *smplptr; char *decptr; /* this constants should go to a configuration file in future.... */ unsigned fm_smplf = (unsigned)(FM_SMPLF * 65536); unsigned am_smplf = (unsigned)(AM_SMPLF * 65536); static void set_speed(int); /* initialize the interface: open it, set it to mono, 8bits per sample, * and allocate space for the input- and output-buffers of the modem- * routines. return a pointer to the decoded data and the number of * values per call to do_receive. */ void interface_init(char **dta_return, int *cnt_return) { int speed = 8000; int bits = 8; int stereo = 0; int linevol = 80; int mastervol = 55; #ifdef SBL_16 int recsrc = SOUND_MASK_LINE; #endif static int inited = 0; /* already initialized ? return values although... */ if (inited) { *dta_return = decptr; *cnt_return = decsize; return; } fprintf(stderr, "opening and initializing sound-interface\n"); if ((afd = open(DSPDEV, O_RDWR, 0666)) < 0) { perror("open_dsp"); exit(1); } dspfd = afd; #ifdef SBL_16 if ((mfd = open(MIXDEV, O_RDWR, 0666)) < 0) { perror("open_mixer"); exit(1); } linevol &= 0xff; linevol += linevol << 8; mastervol &= 0xff; mastervol += mastervol << 8; if ((ioctl(mfd, SOUND_MIXER_WRITE_LINE, &linevol) < 0) || (ioctl(mfd, SOUND_MIXER_WRITE_VOLUME, &mastervol) < 0) || (ioctl(mfd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0)) { perror("mixer_ioctl"); exit(1); } close (mfd); #endif if ((ioctl(afd, SNDCTL_DSP_SPEED, &speed) < 0) || (ioctl(afd, SNDCTL_DSP_SAMPLESIZE, &bits) < 0) || (ioctl(afd, SNDCTL_DSP_STEREO, &stereo) < 0) || (ioctl(afd, SNDCTL_DSP_GETBLKSIZE, &blsize) < 0)) { perror("dsp_ioctl"); exit(1); } decsize = blsize / 2; /* set up defaults for the modem */ amode = MOD_FM; afilter = FIL_MIDL; adevi = 400; set_modem_param (afilter, amaxval, adevi); if (!(decptr = malloc((decsize))) || !(smplptr = malloc(blsize))) { perror("setup_buffers"); exit(1); } printf("block size is %d bytes\n", blsize); *dta_return = decptr; *cnt_return = decsize; inited = -1; } /* stop the interface, don't let it overrun by no more reading/writing */ void interface_stop(void) { if (ioctl(afd, SNDCTL_DSP_RESET, NULL) < 0) { perror("interface_stop: cannot reset pcm"); } } /* set up the desired mode, the decoded value range and the deviation for * FM. Return the number of demodulated sample-points per second (for APT) */ void setup_mode(int mode, int maxval, int devi, unsigned *smplf) { char *dummy1; int dummy2; int id; /* be sure interface is initialized */ interface_init(&dummy1, &dummy2); if ((id = (mode & MOD_BITS))) { switch (id) { case MOD_FM: set_speed(8000); break; case MOD_AM: set_speed(9600); break; } amode = id; fprintf(stderr, "setting demodulator mode to 0x%04x\n", amode); } /* range checking for afilter, adevi and amaxval is done in mod_demod.c */ if ((id = mode & FIL_MASK)) { afilter = id; fprintf(stderr, "setting filter selection to 0x%04x\n", afilter); } if (devi) { adevi = devi; fprintf(stderr, "setting deviation to %d\n", adevi); } if (maxval) { amaxval = maxval; fprintf(stderr, "setting max.demod.value to %d\n", amaxval); } if ((mode & FIL_MASK) | (devi) | (maxval)) { set_modem_param (afilter, amaxval, adevi); } /* return the number of samples per second (16 bits int, 16 bits frac) */ if (smplf) { switch(amode) { case MOD_AM: *smplf = am_smplf; break; case MOD_FM: *smplf = fm_smplf; break; } } } /* receive the signal, demodulate it, ant put the demodulated values * into an array starting at decptr with decsize bytes. (1 byte / value) */ void do_receive(void) { int cnt; int hi, lo; int i, sample; cnt = read(afd, smplptr, blsize); if (cnt <= 0) { perror("do_receive"); exit(1); } fputc('<', stderr); switch(amode) { case MOD_AM: am_demod(smplptr, cnt, decptr); break; case MOD_FM: fm_demod(smplptr, cnt, decptr); break; default: return; } /* determine the signal level and put it into rx_level (0..255) */ lo = 255; hi = 0; for (i = 0; i < blsize / 4; i++) { sample = smplptr[i] & 0xff; if (sample > hi) hi = sample; if (sample < lo) lo = sample; } rx_level = hi - lo; } /* modulate the sample-values from decptr into smplptr, and transmit them * over the interface. The number of input-values is always decsize. */ void do_transmit(void) { int cnt; switch(amode) { case MOD_FM: fm_modulate(decptr, decsize, smplptr); case MOD_AM: am_modulate(decptr, decsize, smplptr); default: return; } cnt = write(afd, smplptr, blsize); if (cnt <= 0) { perror("do_transmit"); exit(1); } fputc('>', stderr); } /* check for signal level, return a value between 0 and 256 */ int signal_level(void) { char buf[512]; int i, p, lo, hi; if (read(afd, buf, 512) != 512) { perror("signal_level: cannot get samples"); } if (ioctl(afd, SNDCTL_DSP_SYNC, NULL) < 0) { perror("signal_level: cannot reset pcm"); } lo = 255; hi = 0; for (i=0; i<512; i++) { p = buf[i]&0xff; if (p > hi) hi = p; if (p < lo) lo = p; } return (hi-lo); } /* just assign new value to either the AM or FM sample-frequency, and hold values permanently until next change */ void tune_frequency(unsigned freq) { switch(amode) { case MOD_FM: fm_smplf = freq; case MOD_AM: am_smplf = freq; default: return; } } /* set a new sample-rate for the DSP-device. We need to restart input in order to do so, because Linux does not update the SB-registers when sending the command, but only on start of input/output */ static void set_speed(int speed) { if (ioctl(afd, SNDCTL_DSP_SPEED, &speed) < 0) { perror("set_speed: cannot set new sample-rate"); } fprintf(stderr,"speed set to %d\n", speed); if (ioctl(afd, SNDCTL_DSP_SYNC, NULL) < 0) { perror("set_speed: cannot reset pcm"); } aspeed = speed; } acfax/sblaster.h100644 765 144 3235 6605505306 13162 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * sblaster.h - header file for sblaster.c, that handles the dsp-interface * for Linux. */ #define DSPDEV "/dev/dsp" #define MIXDEV "/dev/mixer" /* adjust the values below to your SoundBlaster to obtain fax-pictures without azimut-errors. Adjustment can also be done in the program, and you can enter the calculated frequency here. Accuracy should be about +/- 0.01 Hz */ #define FM_SMPLF 4000.976 #define AM_SMPLF 4801.109 void interface_init(char **, int*); void interface_stop(void); void setup_mode(int, int, int, unsigned *); void do_receive(void); void do_transmit(void); int signal_level(void); void tune_frequency(unsigned); extern int dspfd; /* file descriptor of /dev/dsp, used for select() */ extern int rx_level; /* audio frequency input level, from 0 to 255 */ acfax/mod_demod.c100644 765 144 34633 6550717402 13314 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * mod_demod.c - FM and AM modulator/demodulator for ACfax */ #include #include #include #include #include "mod_demod.h" SHORT int firwide[] = { 6, 20, 7, -42, -74, -12, 159, 353, 440 }; SHORT int firmiddle[] = { 0, -18, -38, -39, 0, 83, 191, 284, 320 }; SHORT int firnarrow[] = { -7, -18, -15, 11, 56, 116, 177, 223, 240 }; /* these some more coefficient tables were for testing only. */ /* int firwide[] = { 12, 24, 7, -42, -74, -12, 159, 353, 440 }; */ /* int firnarrow[] = { -16, -21, -15, 11, 56, 116, 177, 223, 240 }; */ /* int fircheap[] = { 0, 0, 0, 0, 0, 0, 36, 99, 128 }; */ /* int firtoobig[] = { -14, -12, 18, 40, -1, -80, -71, 114, 381, 510 } */ /* int firnotbad[] = { 11, 16, 1, -29, -44, -3, 98, 208, 256 }; */ static SHORT int *fcoeff = firmiddle; static int *sqrt_lo; /* square-root lookup-table for AM demodulator */ static int *sqrt_hi; /* (splitted in 2 parts) */ static int *sintab; /* sine wave table for FM modulator */ static int *asntab; /* arcsin-table for FM-demodulator */ static int *fmphsinc; /* phase-increment-table for FM modulator */ static char *amreal; /* amplitude tables for AM modulator */ static int compval; /* comparator value for APT detecion */ /* void main(int argc, char **argv) { char indata[2048]; int outdata[1024]; int q; modem_init(); set_modem_param (FIL_MIDL, 255, 400); while ((q = fread(indata, 1, 2048, stdin)) > 0) { q &= 0xfffe; fm_demod(indata, q, outdata); } } */ /* Initialize the modulator/demodulator functions. This function allocates space for the arrays and lookup-tables */ void modem_init(void) { int i; static int inited = 0; if (inited) return; sqrt_lo = (int *)malloc(2048*sizeof(int)); sqrt_hi = (int *)malloc(2048*sizeof(int)); if (!(sqrt_lo) || !(sqrt_hi)) { perror("modem_init:sqrt_*"); exit(1); } amreal = (char *)malloc(258); if (!(amreal)) { perror("modem_init:am{real|imag}"); exit(1); } sintab = (int *)malloc(1024*sizeof(int)); if (!(sintab)) { perror("modem_init:sintab"); exit(1); } asntab = (int *)malloc(512*sizeof(int)); if (!(asntab)) { perror("modem_init:asntab"); exit(1); } fmphsinc = (int *)malloc(258*sizeof(int)); for (i=0; i<1024; i++) sintab[i] = 127.5 + 127*sin(i*PI/512.0); inited = -1; } /* set up a lookup-table for the given deviation which gives values from 0 to maxval with clipping beyond the edges for reception, initialize a lookup-table for FM transmission. */ void set_modem_param(int filter, int maxval, int devi) { int phmax; int i; /* initialize decoder first, if not already done */ modem_init(); /* do some range-checking */ if (devi < 100) devi = 100; if (devi > 1200) devi = 1200; if (maxval < 1) maxval = 1; if (maxval > 255) maxval = 255; phmax = 255.9 * sin(devi * PI / 4000.0) + 0.5; for (i=0; i<512; i++) { if (i <= 256-phmax) asntab[i] = 0; else if (i >= 256+phmax) asntab[i] = maxval; else asntab[i] = maxval * 2000 / devi * asin((i-256.0)/256.5) / PI + maxval/ 2; } for (i=0; i<2048; i++) { sqrt_lo[i] = (sqrt(i) * maxval / 256.0) + 0.5; sqrt_hi[i] = (sqrt(32*i) * maxval / 256.0) + 0.5; } for (i=0; i<=maxval; i++) fmphsinc[i] = devi / 2000.0 * 65536; for (i=0; i<= maxval; i++) amreal[i] = 127.5 + 127.5*i/maxval; compval = maxval >> 1; switch (filter) { case FIL_NARR: fcoeff = firnarrow; fprintf(stderr, "selecting narrow filter\n"); break; case FIL_MIDL: fcoeff = firmiddle; fprintf(stderr, "selecting middle filter\n"); break; case FIL_WIDE: fcoeff = firwide; fprintf(stderr, "selecting wide filter\n"); break; } } /* Demodulate the samples taken with 8kHz to a frequency sampled with 4kHz. This is done with a delay-demodulator : +----------+ +-------+ +----+ +---+ +->|*sin(2kHz)|->|FIR-LPF|--*->|z^-1|->|mul|--+ | +----------+ +-------+ | +----+ +---+ | | *-->-- / | AM^2 | | \ / |+ | | +---------+ \ / +---+ +---+ --+ AM^2<--|amp^2 det| X |add|->|div|-- | +---------+ / \ +---+ +---+ | | / \ |- | *-->-- \ | | +----------+ +-------+ | +----+ +---+ | +->|*cos(2kHz)|->|FIR-LPF|--*->|z^-1|->|mul|--+ +----------+ +-------+ +----+ +---+ The cosine-signal is simply a sequence of 1,0,-1,0 , and the sine- signal is a sequence of 0,1,0,-1 values because the frequency of these is exactly a fouth of the sample-rate. The values multiplied by zero need not be evaluated by the FIR-filter, what reduces the calculation-effort to one half. Taps of the FIR-chain which are to be multiplied with the same coefficient (possible due to the symmetry of the pulse-response) are first added or subtracted, so again reducing the number of multiplications to one half. NOTE: incnt must be a multiple of 2 to operate properly ! output range is determined by asntab, which is set up by set_modem_param. This table also performs the arcsin-correction and clips values that are beyond the given deviation. */ void fm_demod(char *smplin, int incnt, char *decout) { static SHORT int firbuf[32]; /* buffer holding the input-values */ /* static int inptr = 0; / pointer for data-entry into firbuf */ /* static int rdptr = 0; / pointer for data-output from firbuf */ static int neg = 0; /* flag changing every 2 sample-points */ static int px, py, qx, qy; /* the filtered output-results */ static int pamp, qamp, pfrq, qfrq; /* static int n = 0; int smplptr = 0; */ while (incnt >= 2) { /* shift buffer "left" by 2 : copy firbuf[2..17] to firbuf[0..15] */ memcpy(firbuf, firbuf+2, (16*sizeof(int))); /* enter 2 new samle-points into buffer */ firbuf[16] = *(unsigned char *)smplin++ - 128; firbuf[17] = *(unsigned char *)smplin++ - 128; incnt -= 2; /* do the first quarter : multiply with +0-0+0-0+0-0+0-0+ for px and 0-0+0-0+0-0+0-0+0 for py. 2 sample-periodes later, multiply with 0-0+0 for px and -0+0- for py, what is done using the neg variable as flag. In this case, the result for frequency is negated (amplitude is always positive) */ px = (firbuf[0] + firbuf[16]) * fcoeff[0]; px -= (firbuf[2] + firbuf[14]) * fcoeff[2]; px += (firbuf[4] + firbuf[12]) * fcoeff[4]; px -= (firbuf[6] + firbuf[10]) * fcoeff[6]; px += (firbuf[8]) * fcoeff[8]; px >>= 2; py = (firbuf[15] - firbuf[1]) * fcoeff[1]; py += (firbuf[3] - firbuf[13]) * fcoeff[3]; py += (firbuf[11] - firbuf[5]) * fcoeff[5]; py += (firbuf[7] - firbuf[9]) * fcoeff[7]; py >>= 2; /* dfft->src[smplptr].r = (neg) ? -px : px; dfft->src[smplptr].i = 0; smplptr++; */ /* rdptr = (rdptr+1) & 31; */ pamp = ((px*px + py*py) >> 8) + 1; pfrq = (px*qy - py*qx) / (pamp + qamp); /* do the second quarter : multiply with 0-0+0-0+0-0+0-0+0 for px, -0+0-0+0-0+0-0+0- for py */ qx = (firbuf[15+1] - firbuf[1+1]) * fcoeff[1]; qx += (firbuf[3+1] - firbuf[13+1]) * fcoeff[3]; qx += (firbuf[11+1] - firbuf[5+1]) * fcoeff[5]; qx += (firbuf[7+1] - firbuf[9+1]) * fcoeff[7]; qx >>= 2; qy = -(firbuf[0+1] + firbuf[16+1]) * fcoeff[0]; qy += (firbuf[2+1] + firbuf[14+1]) * fcoeff[2]; qy -= (firbuf[4+1] + firbuf[12+1]) * fcoeff[4]; qy += (firbuf[6+1] + firbuf[10+1]) * fcoeff[6]; qy -= (firbuf[8+1]) * fcoeff[8]; qy >>= 2; /* dfft->src[smplptr].r = (neg) ? -qx : qx; dfft->src[smplptr].i = 0; smplptr++; */ /* rdptr = (rdptr+1) & 31; */ qamp = ((qx*qx + qy*qy) >> 8) + 1; qfrq = (px*qy - py*qx) / (qamp + pamp); /* asntab gives values from minval to maxval for given deviation */ *decout = (unsigned char)asntab[(pfrq+qfrq+256) & 511]; /* printf("%3d %5d %5d\n", n, (px*qy)/1024, (py*qx)/1024); printf("%3d %5d %5d\n", n, *decout, pamp+qamp); n++; */ decout++; neg = ~neg; } /* do_dfft(dfft); for (smplptr=0; smplptr<1024; smplptr++) { dx = dfft->dest[smplptr].r; dy = dfft->dest[smplptr].i; printf("%4.1f %3.1f\n", smplptr * 3.906, 20*log10(sqrt(dx*dx + dy*dy))); } */ } /* Demodulate the samples taken with 9.6kHz to an amplitude sampled with 4.8kHz. This done with a synchronous demodulator : +------------+ +-------+ +------+ +->|*sin(2.4kHz)|->|FIR-LPF|->|square|-+ | +------------+ +-------+ +------+ | | | | | | +-----+ +-------+ --+ |adder|->|sq.root|-- | +-----+ +-------+ | | | | | +------------+ +-------+ +------+ | +->|*cos(2.4kHz)|->|FIR-LPF|->|square|-+ +------------+ +-------+ +------+ The cosine-signal is simply a sequence of 1,0,-1,0 , and the sine- signal is a sequence of 0,1,0,-1 values because the frequency of these is exactly a fouth of the sample-rate. The values multiplied by zero need not be evaluated by the FIR-filter, what reduces the calculation-effort to one half. NOTE: incnt must be a multiple of 2 to operate properly ! output range is determined by sqrt_lo and sqrt_hi, which are set up by set_modem_param. */ void am_demod(char *smplin, int incnt, char *decout) { static SHORT int firbuf[32]; /* buffer holding the input-values */ /* static int inptr = 0; / pointer for data-entry into firbuf */ /* static int rdptr = 0; / pointer for data-output from firbuf */ static int neg = 0; /* flag changing every 2 sample-points */ static int px, py, qx, qy; /* the filtered output-results */ static int pamp, qamp; /* static int n = 0; int smplptr = 0; */ while (incnt >= 2) { /* shift buffer "left" by 2 : copy firbuf[2..17] to firbuf[0..15] */ memcpy(firbuf, firbuf+2, (16*sizeof(int))); /* enter 2 new samle-points into buffer */ firbuf[16] = *(unsigned char *)smplin++ - 128; firbuf[17] = *(unsigned char *)smplin++ - 128; incnt -= 2; /* do the first quarter : multiply with +0-0+0-0+0-0+0-0+ for px and 0-0+0-0+0-0+0-0+0 for py. 2 sample-periodes later, multiply with 0-0+0 for px and -0+0- for py, what is done using the neg variable as flag. In this case, the result for frequency is negated (amplitude is always positive) */ px = (firbuf[0] + firbuf[16]) * fcoeff[0]; px -= (firbuf[2] + firbuf[14]) * fcoeff[2]; px += (firbuf[4] + firbuf[12]) * fcoeff[4]; px -= (firbuf[6] + firbuf[10]) * fcoeff[6]; px += firbuf[8] * fcoeff[8]; px >>= 2; py = (firbuf[15] - firbuf[1]) * fcoeff[1]; py += (firbuf[3] - firbuf[13]) * fcoeff[3]; py += (firbuf[11] - firbuf[5]) * fcoeff[5]; py += (firbuf[7] - firbuf[9]) * fcoeff[7]; py >>= 2; /* dfft->src[smplptr].r = (neg) ? -px : px; dfft->src[smplptr].i = 0; smplptr++; */ /* rdptr = (rdptr+1) & 31; */ pamp = (px*px + py*py); /* do the second quarter : multiply with 0-0+0-0+0-0+0-0+0 for px, -0+0-0+0-0+0-0+0- for py */ qx = (firbuf[15+1] - firbuf[1+1]) * fcoeff[1]; qx += (firbuf[3+1] - firbuf[13+1]) * fcoeff[3]; qx += (firbuf[11+1] - firbuf[5+1]) * fcoeff[5]; qx += (firbuf[7+1] - firbuf[9+1]) * fcoeff[7]; qx >>= 2; qy = -(firbuf[0+1] + firbuf[16+1]) * fcoeff[0]; qy += (firbuf[2+1] + firbuf[14+1]) * fcoeff[2]; qy -= (firbuf[4+1] + firbuf[12+1]) * fcoeff[4]; qy += (firbuf[6+1] + firbuf[10+1]) * fcoeff[6]; qy -= firbuf[8+1] * fcoeff[8]; qy >>= 2; /* dfft->src[smplptr].r = (neg) ? -qx : qx; dfft->src[smplptr].i = 0; smplptr++; */ /* rdptr = (rdptr+1) & 31; */ qamp = (qx*qx + qy*qy + pamp) / 6400; if (qamp >= 65535) *decout = sqrt_hi[2047]; else if (qamp >= 2047) *decout = (unsigned char)sqrt_hi[qamp >> 5]; else *decout = (unsigned char)sqrt_lo[qamp]; /* printf("%3d %5d %5d\n", n, (px*px)/1024, (py*py)/1024); printf("%3d %5d %5d\n", n, *decout, qamp); n++; */ decout++; neg = ~neg; } } /* Encode a frequency sampled at 4kHz to an AF-signal sampled at 8kHz. This is done by shifting the phase by the appropriate value for each sample. */ void fm_modulate(char *codin, int incnt, char *smplout) { static int phs = 0; while (incnt-- > 0) { phs += 0x10000 + fmphsinc[*(unsigned char *)codin++]; phs &= 0x3ffff; *smplout++ = (char)sintab[phs >> 8]; phs += 0x10000 + fmphsinc[*(unsigned char *)codin++]; phs &= 0x3ffff; *smplout++ = (char)sintab[phs >> 8]; } } /* Encode an amplitude sampled at 4.8kHz to an AF-signal sampled at 9.6kHz. This is done by multiplying the amplitude-values with a sampled sine- function represented by a 0,1,0,-1 sequence. */ void am_modulate(char *codin, int incnt, char *smplout) { static int neg = 0; while (incnt-- > 0) { if (neg) { *smplout++ = amreal[*(unsigned char *)codin++]; *smplout++ = 128; /*amimag[*codin++]*/ } else { *smplout++ = amreal[*(unsigned char *)codin++] ^ 0xff; *smplout++ = 128; /*amimag[*codin++] ^ 0xff*/ } neg = ~neg; } } acfax/mod_demod.h100644 765 144 3031 6550716676 13301 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * mod_demod.h - header file for the AM/FM modulator and demodulator * contained in mod_demod.c */ #define MOD_BITS 0x000000f0 #define MOD_FM 0x00000010 #define MOD_AM 0x00000020 #define FIL_MASK 0x00000007 #define FIL_NARR 0x00000001 #define FIL_MIDL 0x00000002 #define FIL_WIDE 0x00000003 /* defining SHORT as short may increase performance on some machines... */ #define SHORT extern SHORT int firwide[], firmiddle[], firnarrow[]; void modem_init(void); void set_modem_param(int, int, int); void fm_demod(char *, int, char *); void am_demod(char *, int, char *); void fm_modulate(char *, int , char *); void am_modulate(char *, int , char *); acfax/x_image.c100644 765 144 24120 6610161234 12755 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * x_image.c - XImage and colormap allocation functions */ #include #include /* #include #include #include */ #include "x_image.h" unsigned long coltab[256]; /* mapping table grayscale->pixel-value */ char cused[256]; /* table indicating used pixel-values */ Display *dpy = NULL; /* X-display used */ Screen *scrn = NULL; /* Screen of display */ Visual *visl = NULL; /* Visual of screen to use */ int depth = -1; /* depth of screen (# of planes) */ Colormap icmap; /* the colormap to use */ XImage *horimag = NULL; /* intermediate-storage for horizontal scan */ XImage *verimag = NULL; /* intermediate-storage for vertical scan */ XVisualInfo visinfo; /* Visual-info-structure (from Xutil.h) */ unsigned long r_mask; /* bit mask bits (truecolor) for red */ unsigned long g_mask; /* bit mask bits (truecolor) for green */ unsigned long b_mask; /* bit mask bits (truecolor) for blue */ int r_shift; /* position of LSB in r_mask */ int g_shift; /* position of LSB in g_mask */ int b_shift; /* position of LSB in b_mask */ int r_bits; /* count of significant bits in r_mask */ int g_bits; /* count of significant bits in g_mask */ int b_bits; /* count of significant bits in b_mask */ /* * get some global X11-variables and resources from the passed Widget */ void get_globals(Widget toplevel) { if (!dpy) dpy = XtDisplay(toplevel); if (!scrn) scrn = XtScreen(toplevel); if (depth < 0) depth = DefaultDepthOfScreen(scrn); if (!visl) { visl = DefaultVisualOfScreen(scrn); #if 0 if (!(XMatchVisualInfo(dpy, XScreenNumberOfScreen(scrn), depth, PseudoColor, &visinfo))) { fprintf(stderr, "cannot get PseudoColor-visual with depth %d !\n", depth); exit(1); } visl = visinfo.visual; #endif } } /* * create two XImages as "transportation storage" between the raw-resulution * picture and the canvas-widget's pixmap (one horizontal stripe with * DEFHEIGHT lines, and one vertical stripe with DEFWIDTH columns). * If called more than once, the old * XImages are Destroyes and new ones are created with the given size. */ void create_images(Widget toplevel, Dimension wid, Dimension hei) { get_globals(toplevel); fprintf(stderr, "creating XImage for %d x %d pixels\n", wid, hei); /* delete old images and their data (when image is resized) */ if (horimag) XDestroyImage(horimag); if (verimag) XDestroyImage(verimag); horimag = XCreateImage(dpy, visl, depth, ZPixmap, 0, NULL, wid, DEFHEIGHT, 32, 0); verimag = XCreateImage(dpy, visl, depth, ZPixmap, 0, NULL, DEFWIDTH, hei, 32, 0); if (!(horimag) || !(verimag)) { fprintf(stderr,"cannot allocate Ximages !\n"); exit(1); } /* allocate data for the XImages (not done by XCreateImage !) */ horimag->data = (char *)XtMalloc(DEFHEIGHT * horimag->bytes_per_line); verimag->data = (char *)XtMalloc(hei * verimag->bytes_per_line); if (!(horimag->data) || !(verimag->data)) { fprintf(stderr,"cannot allocate space for Ximage !\n"); exit(1); } } /* * free the space allocated by the two XImages */ void destroy_images(void) { if (horimag) XDestroyImage(horimag); if (verimag) XDestroyImage(verimag); } /* * allocate a new colormap. This is needed for PseudoColor visuals * of depth 8. For truecolor displays, nothing is to be done here. */ void alloc_cmap(Widget toplevel, Pixel *respix, unsigned nrespix) { Colormap rootcmap; XColor col; static int cmap_created = 0; int i; XVisualInfo vTemplate; XVisualInfo *visuals; int nvisuals; unsigned long tmpmask; get_globals(toplevel); switch(visl->class) { case PseudoColor: case StaticColor: rootcmap = DefaultColormapOfScreen(scrn); if (!(cmap_created)) icmap = XCreateColormap(dpy, XtWindow(toplevel), visl, AllocAll); cmap_created = 1; /* XAllocColorCells(dpy, icmap, True, planes, 0, pixels, 216); */ /* copy the first 16 colors from the root-colormap, and also copy the colors needed for our widgets */ for (i=0; i<(1 << depth); i++) cused[i] = 0; for (i=0; i ((1 << depth) - 1)) respix[i] = 0; col.pixel = respix[i]; cused[respix[i]] = 1; XQueryColor(dpy, rootcmap, &col); XStoreColor(dpy, icmap, &col); } /* now, we can use the rest of the colors for the grayscale or 6x6x6 colormap, but this is done in fill_cmap_col and fill_cmap_gray */ break; case TrueColor: case DirectColor: /* we want a visual with the depth of our screen : */ vTemplate.screen = XScreenNumberOfScreen(scrn); vTemplate.depth = DefaultDepth(dpy, vTemplate.screen); nvisuals = 0; visuals = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask, &vTemplate, &nvisuals); if (nvisuals < 1) { fprintf(stderr, "cannot find visual matching default depth %d\n", vTemplate.depth); exit(1); } /* copy first visual info to own location */ visinfo = visuals[0]; /* discard the array from XGetVisualInfo() */ XFree(visuals); /* determine the bit positions and count of significant bits * for red, green and blue, store it in *_shift and *_bits */ r_mask = visinfo.red_mask; g_mask = visinfo.green_mask; b_mask = visinfo.blue_mask; if (r_mask == 0 || g_mask == 0 || b_mask == 0) { fprintf(stderr, "one of the color masks is zero : %08lx %08lx %08lx\n", r_mask, g_mask, b_mask); exit(1); } /* determine number of bits and position of mask for every color */ r_shift = g_shift = b_shift = 0; r_bits = g_bits = b_bits = 0; tmpmask = r_mask; while ((tmpmask & 1) == 0) { tmpmask >>= 1; r_shift++; } while ((tmpmask & 1) == 1) { tmpmask >>= 1; r_bits++; } tmpmask = g_mask; while ((tmpmask & 1) == 0) { tmpmask >>= 1; g_shift++; } while ((tmpmask & 1) == 1) { tmpmask >>= 1; g_bits++; } tmpmask = b_mask; while ((tmpmask & 1) == 0) { tmpmask >>= 1; b_shift++; } while ((tmpmask & 1) == 1) { tmpmask >>= 1; b_bits++; } break; case StaticGray: fprintf (stderr, "Cannot handle StaticGray visual - abort\n"); exit(1); /*NOTREACHED*/ case GrayScale: fprintf (stderr, "Cannot handle GrayScale visual - abort\n"); exit(1); /*NOTREACHED*/ default: fprintf (stderr, "unknown visual type %x - abort\n", visl->class); exit(1); /*NOTREACHED*/ } } /* * fill the colormap with a 6x6x6 color-cube. * when flip is set, the green and blue indexing is exchanged, and rotate * defines the order in which the colors are indexed. * The array coltab is filled with a lookup-table color_value -> pixel_index. */ void fill_cmap_col(int invert, int flip, int rotate) { int cm[3]; unsigned ixr, ixg, ixb; XColor col; int i = 0; fprintf(stderr, "filling colormap with 6x6x6 cube\n"); col.flags = DoRed | DoGreen | DoBlue; switch(rotate) { case 1: ixr = 1; ixg = (flip) ? 0 : 2; ixb = (flip) ? 2 : 0; break; case 2: ixr = 2; ixg = (flip) ? 1 : 0; ixb = (flip) ? 0 : 1; break; case 0: default: ixr = 0; ixg = (flip) ? 2 : 1; ixb = (flip) ? 1 : 2; break; } for (cm[0]=0; cm[0]<6; cm[0]++) for (cm[1]=0; cm[1]<6; cm[1]++) for (cm[2]=0; cm[2]<6; cm[2]++) { while ((cused[i]) && i < 256) i++; if (i == 256) { fprintf(stderr,"cannot assign all required colors !\n"); break; } col.pixel = i; if (invert) { col.red = 65535 - 9362 * (cm[ixr] + 1); col.green = 65535 - 9362 * (cm[ixg] + 1); col.blue = 65535 - 9362 * (cm[ixb] + 1); } else { col.red = 9362 * (cm[ixr] + 1); col.green = 9362 * (cm[ixg] + 1); col.blue = 9362 * (cm[ixb] + 1); } XStoreColor(dpy, icmap, &col); coltab[cm[0]+6*cm[1]+36*cm[2]] = i; i++; } } /* * fill the colormap with a grayscale of 64 steps (should be good enough). * The array coltab is filled with a lookup-table gray_value -> pixel_index. */ void fill_cmap_gray(int invert) { int g, yv; XColor col; int i = 0; unsigned long cval; fprintf(stderr, "filling colormap with grayscale\n"); switch (visl->class) { case StaticColor: case PseudoColor: col.flags = DoRed | DoGreen | DoBlue; for (g=0; g<64; g++) { while ((cused[i]) && i < 256) i++; if (i == 256) { fprintf(stderr,"cannot assign all required grayscales !\n"); break; } col.pixel = i; yv = (invert) ? 63 - g : g; col.red = col.green = col.blue = 1040.2 * yv; XStoreColor(dpy, icmap, &col); coltab[g] = i; i++; } break; case TrueColor: case DirectColor: /* allocate a translation table grayscale -> truecolor_value */ for (g=0; g<64; g++) { yv = (invert) ? 63 - g : g; cval = (((1 << r_bits) - 1) * yv / 63) << r_shift; cval += (((1 << g_bits) - 1) * yv / 63) << g_shift; cval += (((1 << b_bits) - 1) * yv / 63) << b_shift; coltab[g] = cval; } break; } } acfax/x_image.h100644 765 144 3255 6610161271 12751 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * x_image.h - header file for the XImage and colormap handler x_image.c */ #include #include #include /* some constants for the transportation-images */ #define DEFHEIGHT 16 #define DEFWIDTH 16 /* these are made global : */ extern XImage *horimag; /* intermediate-storage for horizontal scan */ extern XImage *verimag; /* intermediate-storage for vertical scan */ extern Colormap icmap; /* the colormap to use */ extern unsigned long coltab[256]; /* mapping table grayscale->pixel-value */ void create_images(Widget toplevel, Dimension wid, Dimension hei); void destroy_images(void); void alloc_cmap(Widget toplevel, Pixel *respix, unsigned nrespix); void fill_cmap_col(int invert, int flip, int rotate); void fill_cmap_gray(int invert); acfax/widgets.c100644 765 144 64744 6610161340 13030 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * widgets.c - prepare, create and configure all these widgets we need */ #include #include #include #include #include #include #ifdef USE_XAW3D /* #include */ #include #include #include #include #include #include #include #include #include #else #include #include #include #include #include #include #include #include #include #endif #include "FChooser.h" #include "Canvas.h" #include "fax_funcs.h" #include "global.h" #include "widgets.h" /* extern XtAppContext mainapp; */ /* Widget toplevel; */ Widget last; /* just for convenience.... */ struct modem_ws mod_s; struct runctl_ws run_s; struct dirctl_ws dir_s; struct polctl_ws pol_s; struct adjctl_ws adj_s; struct numval_ws num_s; struct file_menu file_m; struct info_popup info_s; struct file_browser fileb_s; Widget fax_shell, fax_form, disp_form, /* form for the image-display */ vport, /* a viewport to look thru onto the canvas */ canvas; /* widget holding picture using XImages */ Pixmap px_horiz, px_vert, px_right, px_left, px_top, px_bottom, px_normal, px_invers, px_nphs, px_iphs, px_azimut, px_shift, px_stop, px_syn, px_run, px_mam, px_mfm, px_narrow, px_middle, px_wide; XtTranslations txt_trans; /* translations for numeric entries */ XtTranslations name_trans; /* translations for name-entry */ static void fchs_cb(Widget, XtPointer, XtPointer); static void file_ok_cb(Widget, XtPointer, XtPointer); static void file_cancel_cb(Widget, XtPointer, XtPointer); static void end_simple_info(Widget, XtPointer, XtPointer); /* * all the following widget-creation functions return their "top-level" * widget (a form-widget) so that these blocks can be arranged in a * frame (also a form-widget) using the XtNfromVert and XtNfromHoriz * parameters. */ /* create the modem-control-widgets */ Widget cr_modemform(Widget parent) { int iwd; mod_s.form = XtVaCreateManagedWidget("modemform", formWidgetClass, parent, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, /* XtNfromVert, menuform, */ /* XtNfromHoriz, filebut, */ NULL); XtVaGetValues(mod_s.form, XtNdefaultDistance, &iwd, NULL); /* the modem control widgets */ mod_s.modemdesc = XtVaCreateManagedWidget("modemdesc", labelWidgetClass, mod_s.form, XtNwidth, (6*32+5*iwd), XtNborderWidth, 0, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); last = mod_s.modemdesc; mod_s.modinfo = XtVaCreateManagedWidget("modinfo", labelWidgetClass, mod_s.form, XtNwidth, (2*32+iwd), XtNheight, 32, XtNborderWidth, 0, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); mod_s.mmode = XtVaCreateManagedWidget("mmode", toggleWidgetClass, mod_s.form, XtNwidth, 32, XtNheight, 32, XtNlabel, "", XtNfromVert, last, XtNfromHoriz, mod_s.modinfo, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); mod_s.filinfo = XtVaCreateManagedWidget("filinfo", labelWidgetClass, mod_s.form, XtNwidth, (2*32+iwd), XtNheight, 32, XtNborderWidth, 0, XtNfromVert, last, XtNfromHoriz, mod_s.mmode, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); mod_s.mfilter = XtVaCreateManagedWidget("mfilter", menuButtonWidgetClass, mod_s.form, XtNwidth, 32, XtNheight, 32, XtNlabel, "", XtNfromVert, last, XtNfromHoriz, mod_s.filinfo, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNmenuName, "filtermenu", NULL); mod_s.mflpd = XtVaCreatePopupShell("filtermenu", simpleMenuWidgetClass, mod_s.mfilter, NULL); mod_s.mflt1 = XtVaCreateManagedWidget("mflt1", smeBSBObjectClass, mod_s.mflpd, NULL); mod_s.mflt2 = XtVaCreateManagedWidget("mflt2", smeBSBObjectClass, mod_s.mflpd, NULL); mod_s.mflt3 = XtVaCreateManagedWidget("mflt3", smeBSBObjectClass, mod_s.mflpd, NULL); last = mod_s.modinfo; mod_s.fmdevinfo = XtVaCreateManagedWidget("fmdevinfo", labelWidgetClass, mod_s.form, XtNborderWidth, 0, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); mod_s.fmdevval = XtVaCreateManagedWidget("fmdevval", asciiTextWidgetClass, mod_s.form, XtNlength, 4, XtNwidth, 44, XtNstring, "", XtNeditType, XawtextEdit, XtNtranslations, txt_trans, XtNfromHoriz, mod_s.fmdevinfo, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); last = mod_s.fmdevinfo; mod_s.siginfo = XtVaCreateManagedWidget("siginfo", labelWidgetClass, mod_s.form, XtNborderWidth, 0, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); mod_s.sigbar = XtVaCreateManagedWidget("sigbar", scrollbarWidgetClass, mod_s.form, XtNwidth, 160, XtNheight, 16, XtNsensitive, True, XtNorientation, XtorientHorizontal, XtNminimumThumb, 2, XtNfromHoriz, mod_s.siginfo, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); return mod_s.form; } /* create the run-control widgets (stop, sync, run) */ Widget cr_faxctrls(Widget parent) { Widget n_form; int iwd; n_form = XtVaCreateManagedWidget("faxctrls", formWidgetClass, parent, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, /* XtNfromVert, menuform, */ /* XtNfromHoriz, modemform, */ NULL); XtVaGetValues(n_form, XtNdefaultDistance, &iwd, NULL); /* the run-control widgets (stop, sync, run) */ run_s.form = XtVaCreateManagedWidget("runctlform", formWidgetClass, n_form, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNborderWidth, 0, NULL); run_s.runinfo = XtVaCreateManagedWidget("runinfo", labelWidgetClass, run_s.form, XtNwidth, (3*32+2*iwd), XtNheight, 32, XtNborderWidth, 0, /* XtNshadowWidth, 2, */ XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); last = run_s.runinfo; run_s.rmstop = XtVaCreateManagedWidget("rmstop", toggleWidgetClass, run_s.form, XtNwidth, 32, XtNheight, 32, XtNradioData, FAX_APT, XtNlabel, "", XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); run_s.rmsyn = XtVaCreateManagedWidget("rmsyn", toggleWidgetClass, run_s.form, XtNwidth, 32, XtNheight, 32, XtNradioGroup, run_s.rmstop, XtNradioData, FAX_PHAS, XtNlabel, "", XtNfromHoriz, run_s.rmstop, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); run_s.rmrun = XtVaCreateManagedWidget("rmrun", toggleWidgetClass, run_s.form, XtNwidth, 32, XtNheight, 32, XtNradioGroup, run_s.rmstop, XtNradioData, FAX_RX, XtNlabel, "", XtNfromHoriz, run_s.rmsyn, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); /* the direction control widgets (with description) */ dir_s.form = XtVaCreateManagedWidget("dirctlform", formWidgetClass, n_form, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNfromHoriz, run_s.form, XtNborderWidth, 0, NULL); dir_s.dirinfo = XtVaCreateManagedWidget("dirinfo", labelWidgetClass, dir_s.form, XtNwidth, (3*32+2*iwd), XtNheight, 32, XtNborderWidth, 0, /* XtNshadowWidth, 2, */ /* XtNfromHoriz, last, */ XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); last = dir_s.dirinfo; dir_s.dirhv = XtVaCreateManagedWidget("dirhv", toggleWidgetClass, dir_s.form, XtNwidth, 32, XtNheight, 32, XtNlabel, "", /* XtNfromHoriz, runinfo, */ XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); dir_s.dirlr = XtVaCreateManagedWidget("dirlr", toggleWidgetClass, dir_s.form, XtNwidth, 32, XtNheight, 32, XtNlabel, "", XtNfromHoriz, dir_s.dirhv, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); dir_s.dirtb = XtVaCreateManagedWidget("dirtb", toggleWidgetClass, dir_s.form, XtNwidth, 32, XtNheight, 32, XtNlabel, "", XtNfromHoriz, dir_s.dirlr, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); /* the polarity switch (normal or inverse) */ pol_s.form = XtVaCreateManagedWidget("polartyform", formWidgetClass, n_form, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNfromHoriz, dir_s.form, XtNborderWidth, 0, NULL); pol_s.polinfo = XtVaCreateManagedWidget("polinfo", labelWidgetClass, pol_s.form, XtNwidth, (2*32+iwd), XtNheight, 32, XtNborderWidth, 0, /* XtNshadowWidth, 2, */ /* XtNfromHoriz, last, */ XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); pol_s.norinv = XtVaCreateManagedWidget("norinv", toggleWidgetClass, pol_s.form, XtNwidth, 32, XtNheight, 32, XtNlabel, "normal", /* XtNfromHoriz, dirtb, */ XtNfromHoriz, pol_s.polinfo, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); /* the phase-in-polarity control */ pol_s.phsinfo = XtVaCreateManagedWidget("phsinfo", labelWidgetClass, pol_s.form, XtNwidth, (2*32+iwd), XtNheight, 32, XtNborderWidth, 0, /* XtNshadowWidth, 2, */ XtNfromVert, pol_s.polinfo, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); pol_s.posneg = XtVaCreateManagedWidget("posneg", toggleWidgetClass, pol_s.form, XtNwidth, 32, XtNheight, 32, XtNfromHoriz, pol_s.phsinfo, XtNfromVert, pol_s.norinv, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); /* the re-adjustment buttons (line shifting and frequency-correction) */ adj_s.form = XtVaCreateManagedWidget("adj_sform", formWidgetClass, n_form, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNfromHoriz, pol_s.form, XtNborderWidth, 0, NULL); adj_s.adjinfo = XtVaCreateManagedWidget("adjinfo", labelWidgetClass, adj_s.form, XtNwidth, (2*32+iwd), XtNheight, 32, XtNborderWidth, 0, /* XtNshadowWidth, 2, */ /* XtNfromHoriz, last, */ XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); last = adj_s.adjinfo; adj_s.lshift = XtVaCreateManagedWidget("lshift", commandWidgetClass, adj_s.form, XtNwidth, 32, XtNheight, 32, /* XtNfromHoriz, posneg, */ XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); adj_s.azimut = XtVaCreateManagedWidget("azimut", commandWidgetClass, adj_s.form, XtNwidth, 32, XtNheight, 32, XtNfromHoriz, adj_s.lshift, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); return n_form; } /* create form with numerical FAX-parameters */ Widget cr_faxparams(Widget parent) { int iwd; num_s.form = XtVaCreateManagedWidget("faxparams", formWidgetClass, parent, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, /* XtNfromVert, menuform, */ /* XtNfromHoriz, faxformA, */ NULL); XtVaGetValues(num_s.form, XtNdefaultDistance, &iwd, NULL); /* the numerical entry fields */ num_s.numinfo = XtVaCreateManagedWidget("numinfo", labelWidgetClass, num_s.form, XtNwidth, (11*32+18*iwd), XtNborderWidth, 0, /* XtNshadowWidth, 2, */ XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); last = num_s.numinfo; num_s.lpmtxt = XtVaCreateManagedWidget("lpmtxt", labelWidgetClass, num_s.form, XtNborderWidth, 0, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.lpmval = XtVaCreateManagedWidget("lpmval", asciiTextWidgetClass, num_s.form, XtNlength, 4, XtNwidth, 44, XtNstring, "", XtNeditType, XawtextEdit, XtNtranslations, txt_trans, XtNfromHoriz, num_s.lpmtxt, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.ioctxt = XtVaCreateManagedWidget("ioctxt", labelWidgetClass, num_s.form, XtNborderWidth, 0, XtNfromHoriz, num_s.lpmval, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.iocval = XtVaCreateManagedWidget("iocval", asciiTextWidgetClass, num_s.form, XtNlength, 4, XtNwidth, 44, XtNstring, "", XtNeditType, XawtextEdit, XtNtranslations, txt_trans, XtNfromHoriz, num_s.ioctxt, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.statxt = XtVaCreateManagedWidget("statxt", labelWidgetClass, num_s.form, XtNborderWidth, 0, XtNfromHoriz, num_s.iocval, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.staval = XtVaCreateManagedWidget("staval", asciiTextWidgetClass, num_s.form, XtNlength, 4, XtNwidth, 44, XtNstring, "", XtNeditType, XawtextEdit, XtNtranslations, txt_trans, XtNfromHoriz, num_s.statxt, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.stotxt = XtVaCreateManagedWidget("stotxt", labelWidgetClass, num_s.form, XtNborderWidth, 0, XtNfromHoriz, num_s.staval, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, NULL); num_s.stoval = XtVaCreateManagedWidget("stoval", asciiTextWidgetClass, num_s.form, XtNlength, 4, XtNwidth, 44, XtNstring, "", XtNeditType, XawtextEdit, XtNtranslations, txt_trans, XtNfromHoriz, num_s.stotxt, XtNfromVert, last, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainBottom, NULL); return num_s.form; } /* create the menu-bar with the menuButtons and their pulldown-menus */ Widget cr_menubar(Widget parent) { Widget n_form; n_form = XtVaCreateManagedWidget("menuform", formWidgetClass, parent, XtNborderWidth, 0, NULL); file_m.butn = XtVaCreateManagedWidget("filebut", menuButtonWidgetClass, n_form, XtNwidth, 80, XtNheight, 20, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNmenuName, "file_mw", NULL); file_m.menu = XtVaCreatePopupShell("file_mw", simpleMenuWidgetClass, file_m.butn, NULL); file_m.autosave = XtVaCreateManagedWidget("autosave", smeBSBObjectClass, file_m.menu, NULL); file_m.saveas = XtVaCreateManagedWidget("saveas", smeBSBObjectClass, file_m.menu, NULL); file_m.close = XtVaCreateManagedWidget("close", smeBSBObjectClass, file_m.menu, NULL); file_m.quit = XtVaCreateManagedWidget("quit", smeBSBObjectClass, file_m.menu, NULL); return n_form; } Widget cr_infopop(Widget parent) { info_s.shell = XtVaCreatePopupShell("info_shell", applicationShellWidgetClass, parent, XtNallowShellResize, True, /* XtNwidth, 260, */ /* XtNheight, 120, */ NULL); info_s.form = XtVaCreateManagedWidget("info_form", formWidgetClass, info_s.shell, XtNresizable, True, NULL); info_s.text = XtVaCreateManagedWidget("info_text", labelWidgetClass, info_s.form, /* XtNlabel, "1234567890123456789012345678901234567890\n\nX", */ XtNleft, XtChainLeft, XtNright, XtChainRight, XtNresizable, True, NULL); info_s.butn = XtVaCreateManagedWidget("info_butn", commandWidgetClass, info_s.form, XtNlabel, "big_enough", XtNfromVert, info_s.text, NULL); return info_s.shell; } void create_filebrowser(Widget parent) { XtAccelerators okacc; /* accelerators for OK-button */ XtAccelerators canacc; /* accelerators for cancel-button */ fileb_s.shell = XtVaCreatePopupShell("file_shell", transientShellWidgetClass, parent, XtNtitle, "File selector", NULL); okacc = XtParseAcceleratorTable("#override\n\ Return: set() notify() unset()\n\ Linefeed: set() notify() unset()"); canacc = XtParseAcceleratorTable("#override\n\ Escape: set() notify() unset()"); fileb_s.form = XtVaCreateManagedWidget("file_form", formWidgetClass, fileb_s.shell, NULL); fileb_s.fchs = XtVaCreateManagedWidget("file_fch", xfwfFileChooserWidgetClass, fileb_s.form, XtNwidth, 320, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainBottom, NULL); fileb_s.okbut = XtVaCreateManagedWidget("file_ok", commandWidgetClass, fileb_s.form, XtNwidth, 64, XtNheight, 24, XtNlabel, "Ok", XtNaccelerators, okacc, XtNfromHoriz, fileb_s.fchs, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainBottom, NULL); fileb_s.cancel = XtVaCreateManagedWidget("file_cancel", commandWidgetClass, fileb_s.form, XtNwidth, 64, XtNheight, 24, XtNlabel, "cancel", XtNaccelerators, canacc, XtNfromHoriz, fileb_s.fchs, XtNfromVert, fileb_s.okbut, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainBottom, NULL); fileb_s.fname = XtVaCreateManagedWidget("file_name", asciiTextWidgetClass, fileb_s.form, XtNlength, 40, XtNwidth, 384, XtNeditType, XawtextEdit, XtNfromVert, fileb_s.fchs, XtNleft, XtChainLeft, XtNright, XtChainRight, XtNtop, XtChainTop, XtNbottom, XtChainBottom, NULL); XtSetKeyboardFocus(fileb_s.form, fileb_s.fname); XtInstallAccelerators(fileb_s.fname, fileb_s.okbut); XtAddCallback(fileb_s.okbut, XtNcallback, file_ok_cb, (XtPointer)NULL); XtAddCallback(fileb_s.cancel, XtNcallback, file_cancel_cb, (XtPointer)NULL); XtAddCallback(fileb_s.fchs, XtNcallback, fchs_cb, (XtPointer)NULL); } /* callback for the fileChooser-widget: update the filename-display */ static void fchs_cb(Widget w, XtPointer client_data, XtPointer call_data) { char *fname; XtVaGetValues(fileb_s.fchs, XtNcurrentFile, &fname, NULL); XtVaSetValues(fileb_s.fname, XtNstring, fname, NULL); /* anything else to do ? */ } /* callback for Ok-button: get name from filename-display */ static void file_ok_cb(Widget w, XtPointer client_data, XtPointer call_data) { char *fname; char *path; XtVaGetValues(fileb_s.fname, XtNstring, &fname, NULL); XtVaGetValues(fileb_s.fchs, XtNcurrentDirectory, &path, NULL); /* look if there is an absolute pathname given */ if (*fname == '/') { strcpy(fileb_s.name, fname); } else { strcpy(fileb_s.name, path); strcat(fileb_s.name, fname); } /* remember directory for next time */ strcpy (fileb_s.fsarg->dir_io, path); /* call the function */ fileb_s.fsarg->file_act(fileb_s.name); XtPopdown(fileb_s.shell); } static void file_cancel_cb(Widget w, XtPointer client_data, XtPointer call_data) { XtPopdown(fileb_s.shell); } void query_filename(struct fileshell_args *fst) { if (fst->title) { XtVaSetValues(fileb_s.shell, XtNtitle, fst->title, NULL); } if ((fst->dir_io) && (*fst->dir_io)) { XtVaSetValues(fileb_s.fchs, XtNcurrentDirectory, fst->dir_io, NULL); } fileb_s.fsarg = fst; fprintf(stderr, "popping up fileb_s.shell\n"); XtPopup(fileb_s.shell, XtGrabNone); } void create_widgets(Widget toplevel) { /* Dimension iwd; */ Widget wd_menu, wd_modem, wd_fctl, wd_fpar; fax_shell = XtVaCreatePopupShell("fax_shell", applicationShellWidgetClass, toplevel, XtNtitle, "ACfax control", NULL); fax_form = XtVaCreateManagedWidget("fax_form", formWidgetClass, fax_shell, XtNborderWidth, 0, NULL); fprintf(stderr,"creating menu-line\n"); wd_menu = cr_menubar(fax_form); fprintf(stderr,"creating modem-form\n"); wd_modem = cr_modemform(fax_form); fprintf(stderr,"creating fax-ctrls\n"); wd_fctl = cr_faxctrls(fax_form); fprintf(stderr,"creating fax-params\n"); wd_fpar = cr_faxparams(fax_form); fprintf(stderr,"setting placement-order\n"); XtVaSetValues(wd_modem, XtNfromVert, wd_menu, NULL); XtVaSetValues(wd_fctl, XtNfromVert, wd_modem, NULL); XtVaSetValues(wd_fpar, XtNfromVert, wd_fctl, NULL); fprintf(stderr,"creating info-popup\n"); cr_infopop(toplevel); create_filebrowser(toplevel); fprintf(stderr,"creating disp_form\n"); disp_form = XtVaCreateManagedWidget("disp_form", formWidgetClass, toplevel, NULL); /* modebut = XtVaCreateManagedWidget("modebut", menuButtonWidgetClass, form, XtNwidth, 112, XtNheight, 32, XtNresizable, False, / XtNlabel, "Mode..", / XtNfromHoriz, filebut, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNmenuName, "modes", NULL); */ /* optbut = XtVaCreateManagedWidget("optbut", menuButtonWidgetClass, form, XtNwidth, 80, XtNheight, 32, / XtNlabel, "Options..", / XtNfromHoriz, filebut, XtNleft, XtChainLeft, XtNright, XtChainLeft, XtNtop, XtChainTop, XtNbottom, XtChainTop, XtNmenuName, "options", NULL); */ vport = XtVaCreateManagedWidget("vport", viewportWidgetClass, disp_form, XtNwidth, 750, XtNheight, 540, XtNallowHoriz, True, XtNallowVert, True, XtNuseRight, True, XtNleft, XtChainLeft, XtNtop, XtChainTop, XtNright, XtChainRight, XtNbottom, XtChainBottom, NULL); canvas = XtVaCreateManagedWidget("canvas", canvasWidgetClass, vport, /* XtNwidth, C_WIDTH, XtNheight, C_HEIGHT, */ XtNleft, XtChainLeft, /* XtNright, XtChainLeft, */ XtNtop, XtChainTop, /* XtNbottom, XtChainTop, */ NULL); fprintf(stderr,"create_widgets done.\n"); } void simple_info(char *str) { XtVaSetValues(info_s.shell, XtNtitle, "Info", NULL); XtVaSetValues(info_s.text, XtNstring, str, NULL); XtVaSetValues(info_s.butn, XtNlabel, "-OK-"); XtAddCallback(info_s.butn, XtNcallback, end_simple_info, (XtPointer)NULL); XtPopup(info_s.shell, XtGrabNone); } static void end_simple_info(Widget w, XtPointer client_data, XtPointer call_data) { XtPopdown(info_s.shell); } void create_pixmaps(Widget wid) { #include "bitmaps/horiz.bit" #include "bitmaps/vert.bit" #include "bitmaps/left.bit" #include "bitmaps/right.bit" #include "bitmaps/top.bit" #include "bitmaps/bottom.bit" #include "bitmaps/nphs.bit" #include "bitmaps/iphs.bit" #include "bitmaps/normal.bit" #include "bitmaps/invers.bit" #include "bitmaps/azimut.bit" #include "bitmaps/shift.bit" #include "bitmaps/stop.bit" #include "bitmaps/syn.bit" #include "bitmaps/run.bit" #include "bitmaps/ammod.bit" #include "bitmaps/fmmod.bit" #include "bitmaps/narrow.bit" #include "bitmaps/middle.bit" #include "bitmaps/wide.bit" Window win; Display *dpy; win = XtWindow(wid); dpy = XtDisplay(wid); px_horiz = XCreateBitmapFromData(dpy, win, horiz_bits, horiz_width, horiz_height); px_vert = XCreateBitmapFromData(dpy, win, vert_bits, vert_width, vert_height); px_right = XCreateBitmapFromData(dpy, win, right_bits, right_width, right_height); px_left = XCreateBitmapFromData(dpy, win, left_bits, left_width, left_height); px_top = XCreateBitmapFromData(dpy, win, top_bits, top_width, top_height); px_bottom = XCreateBitmapFromData(dpy, win, bottom_bits, bottom_width, bottom_height); px_nphs = XCreateBitmapFromData(dpy, win, nphs_bits, nphs_width, nphs_height); px_iphs = XCreateBitmapFromData(dpy, win, iphs_bits, iphs_width, iphs_height); px_normal = XCreateBitmapFromData(dpy, win, normal_bits, normal_width, normal_height); px_invers = XCreateBitmapFromData(dpy, win, invers_bits, invers_width, invers_height); px_azimut = XCreateBitmapFromData(dpy, win, azimut_bits, azimut_width, azimut_height); px_shift = XCreateBitmapFromData(dpy, win, shift_bits, shift_width, shift_height); px_stop = XCreateBitmapFromData(dpy, win, stop_bits, stop_width, stop_height); px_syn = XCreateBitmapFromData(dpy, win, syn_bits, syn_width, syn_height); px_run = XCreateBitmapFromData(dpy, win, run_bits, run_width, run_height); px_mam = XCreateBitmapFromData(dpy, win, ammod_bits, ammod_width, ammod_height); px_mfm = XCreateBitmapFromData(dpy, win, fmmod_bits, fmmod_width, fmmod_height); px_narrow = XCreateBitmapFromData(dpy, win, narrow_bits, narrow_width, narrow_height); px_middle = XCreateBitmapFromData(dpy, win, middle_bits, middle_width, middle_height); px_wide = XCreateBitmapFromData(dpy, win, wide_bits, wide_width, wide_height); XtVaSetValues(dir_s.dirhv, XtNbitmap, px_horiz, NULL); XtVaSetValues(dir_s.dirlr, XtNbitmap, px_right, NULL); XtVaSetValues(dir_s.dirtb, XtNbitmap, px_bottom, NULL); XtVaSetValues(pol_s.norinv, XtNbitmap, px_normal, NULL); XtVaSetValues(pol_s.posneg, XtNbitmap, px_nphs, NULL); XtVaSetValues(adj_s.lshift, XtNbitmap, px_shift, NULL); XtVaSetValues(adj_s.azimut, XtNbitmap, px_azimut, NULL); XtVaSetValues(run_s.rmstop, XtNbitmap, px_stop, NULL); XtVaSetValues(run_s.rmsyn, XtNbitmap, px_syn, NULL); XtVaSetValues(run_s.rmrun, XtNbitmap, px_run, NULL); XtVaSetValues(mod_s.mmode, XtNbitmap, px_mfm, NULL); XtVaSetValues(mod_s.mfilter, XtNbitmap, px_middle, NULL); } /* * update the signal level display; sig has range 0 to 1.0 */ void set_sigdisplay(double sig) { XawScrollbarSetThumb(mod_s.sigbar, 0, sig); } acfax/widgets.h100644 765 144 12731 6605506526 13037 0ustar andreasusers/* ACfax - Fax reception with X11-interface for amateur radio Copyright (C) 1995-1998 Andreas Czechanowski, DL4SDC This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. andreas.czechanowski@ins.uni-stuttgart.de */ /* * widgets.h - structure definitions for widgets.c */ #include /* * these structures are for grouping widgets together and not having * too many global widget-variables. Most states are remembered by the * status of the appropriate widget. For numeric values, or multi-state * widgets, integer variables have been added. */ struct modem_ws { Widget form, /* form widget containining... : */ modemdesc, /* label "modem settings" */ modinfo, /* label "modulation type" */ mmode, /* toggle (AM/FM) */ filinfo, /* label "filter select" */ mfilter, /* command (narrow/middle/wide filter) */ mflpd, /* simpleMenu containing... : */ mflt1, /* smeBSB: narrow filter */ mflt2, /* smeBSB: middle filter */ mflt3, /* smeBSB: wide filter */ fmdevinfo, /* label "deviation (+/- Hz)" */ fmdevval, /* asciiText (entry of deviation value) */ siginfo, /* label "Signal" */ sigbar; /* scrollbar showing current input signal level */ int c_filter, /* currently selected filter (see mod_demod.h) */ c_devi; /* currently selected deviation (for FM) */ }; struct runctl_ws { Widget form, /* form widget containining... : */ runinfo, /* label "operation control" */ rmstop, /* toggle (stop) */ rmsyn, /* toggle (sync) */ rmrun; /* toggle (run) */ }; struct dirctl_ws { Widget form, /* form widget containining... : */ dirinfo, /* label "direction control" */ dirhv, /* toggle (hor/vert) */ dirlr, /* toggle (right/left) */ dirtb; /* toggle (bottom/top) */ }; struct polctl_ws { Widget form, /* form widget containining... : */ polinfo, /* label "image polarity" */ norinv, /* toggle (normal/invers) */ phsinfo, /* label "phase polarity" */ posneg; /* toggle (pos/neg phase) */ }; struct adjctl_ws { Widget form, /* form widget containining... : */ adjinfo, /* label "image adjust" */ lshift, /* command (shift image) */ azimut; /* command (azimut correction) */ }; struct numval_ws { Widget form, /* form widget containining... : */ numinfo, /* label "numeric parameters" */ lpmtxt, /* label "lpm" */ lpmval, /* asciiText (lpm entry) */ ioctxt, /* label "IOC" */ iocval, /* asciiText (IOC entry) */ statxt, /* label "APT start" */ staval, /* asciiText (APT start entry) */ stotxt, /* label "APT stop" */ stoval; /* asciiText (APT stop entry) */ int c_lpm, c_ioc, c_aptsta, c_aptstp; }; struct info_popup { Widget shell, /* popup-shell for displaying auxiliary information */ form, /* form widget containing... : */ text, /* asciiText, displaying message */ butn; /* button for Ok/cancel/dismiss etc */ }; struct file_menu { Widget butn, /* menuButton opening... : */ menu, /* simpleMenu containing... : */ saveas, /* smeBSB "save-as" */ close, /* smeBSB "close" */ autosave, /* smeBSB "save (auto-filename)" */ quit; /* smeBSB "quit ACfax" */ }; struct fileshell_args { char *title; /* title of shell to be poped up */ char *dir_io; /* directory input/output */ char *filename; /* filename_return */ void (*file_act)(char *); /* function accepting name as argument */ }; struct file_browser { Widget shell, /* popup-shell for the file-browser */ form, /* form widget containing... : */ fchs, /* XfwfFileChooserWidget */ okbut, /* command "Ok" */ cancel, /* command "cancel" */ fname; /* asciiText for file-/directory name entry */ char name[256]; /* name of file being selected */ struct fileshell_args *fsarg; /* file-shell arguments passed from application */ }; extern Widget /* form, */ fax_shell, fax_form, disp_form, vport, canvas; extern Pixmap px_horiz, px_vert, px_right, px_left, px_top, px_bottom, px_normal, px_invers, px_nphs, px_iphs, px_azimut, px_shift, px_stop, px_syn, px_run, px_mam, px_mfm, px_narrow, px_middle, px_wide; extern struct modem_ws mod_s; extern struct runctl_ws run_s; extern struct dirctl_ws dir_s; extern struct polctl_ws pol_s; extern struct adjctl_ws adj_s; extern struct numval_ws num_s; extern struct file_menu file_m; extern struct info_popup info_s; Widget cr_modemform(Widget); /* creates mod_s */ Widget cr_faxctls(Widget); /* creates run_s, dir_s, pol_s, adj_s */ Widget cr_faxparams(Widget); /* creates num_s */ Widget cr_menubar(Widget); /* creates menu with pulldown-menus */ Widget cr_infopop(Widget); /* creates info_s */ void query_filename(struct fileshell_args *); void create_widgets(Widget); void simple_info(char *); void create_pixmaps(Widget); void set_sigdisplay(double); acfax/FChooser.c100644 765 144 67036 5773037735 13112 0ustar andreasusers/* * FChooser.c : A widget for choosing a file * * George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993. * * This code is derived from the FileSelector widget by Brian Totty, * hence the following copyright applies: * * Copyright 1990,1991,1992 Brian Totty * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Brian Totty or * University of Illinois not be used in advertising or publicity * pertaining to distribution of the software without specific, written * prior permission. Brian Totty and University of Illinois make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * Brian Totty and University of Illinois disclaim all warranties with * regard to this software, including all implied warranties of * merchantability and fitness, in no event shall Brian Totty or * University of Illinois 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: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #include #include #include #include #include #include #include #include #ifdef USE_XAW3D #include #include #include #include #include #else #include #include #include #include #include #endif #include "DirMgr.h" #include "FChooserP.h" #include "FChooser.h" /*---------------------------------------------------------------------------* I N T E R N A L R O U T I N E S *---------------------------------------------------------------------------*/ #if (!NeedFunctionPrototypes) static void Initialize(); static void Realize(); static void Destroy(); static void Resize(); static Boolean SetValues(); static XtGeometryResult GeometryManager(); static void ChildrenCreate(); static void ChildrenRealize(); static void ChildrenUpdate(); static void DirectoryCallback(); static void FileCallback(); static void SelectFileByIndex(); static Boolean SelectFileByName(); static void UnselectAll(); static void Notify(); static void GotoDeepestLegalDirectory(); static void UpdateLists(); static void Chdir(); #else static void Initialize(Widget request, Widget new); static void Realize(Widget w, XtValueMask *valueMask, XSetWindowAttributes *attrs); static void Destroy(XfwfFileChooserWidget fcw); static void Resize(Widget w); static Boolean SetValues(Widget current, Widget request, Widget new); static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply); static void ChildrenCreate(XfwfFileChooserWidget fcw); static void ChildrenRealize(XfwfFileChooserWidget fcw); static void ChildrenUpdate(XfwfFileChooserWidget fcw); static void DirectoryCallback(Widget w, XtPointer client_data, XtPointer call_data); static void FileCallback(Widget w, XtPointer client_data, XtPointer call_data); static void SelectFileByIndex(XfwfFileChooserWidget fcw, int index); static Boolean SelectFileByName(XfwfFileChooserWidget fcw, char *name); static void UnselectAll(XfwfFileChooserWidget fcw); static void Notify(XfwfFileChooserWidget fcw); static void GotoDeepestLegalDirectory(XfwfFileChooserWidget fcw); static void UpdateLists(XfwfFileChooserWidget fcw); static void Chdir(XfwfFileChooserWidget fcw); #endif /*---------------------------------------------------------------------------* R E S O U R C E I N I T I A L I Z A T I O N *---------------------------------------------------------------------------*/ #define FCFieldOffset(FIELD) XtOffset(XfwfFileChooserWidget,fileChooser.FIELD) #define CoreFieldOffset(FIELD) XtOffset(Widget,core.FIELD) static XtResource resources[] = { { XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), CoreFieldOffset(width), XtRString, "500" }, { XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), CoreFieldOffset(height), XtRString, "250" }, { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel), CoreFieldOffset(background_pixel), XtRString, "white" }, { XtNcurrentDirectory, XtCPathname, XtRString, sizeof(String), FCFieldOffset(current_dir), XtRString, NULL }, { XtNcurrentFile, XtCFilename, XtRString, sizeof(String), FCFieldOffset(current_file), XtRString, NULL }, { XtNcallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), FCFieldOffset(callbacks), XtRCallback, NULL}, {XtNsortMode, XtCValue, XtRInt, sizeof(int), FCFieldOffset(sort_mode), XtRString, "2"}, {XtNpattern, XtCFile, XtRString, sizeof(String), FCFieldOffset(pattern), XtRString, NULL}, }; #undef FCFieldOffset #undef CoreFieldOffset /*---------------------------------------------------------------------------* C L A S S A L L O C A T I O N *---------------------------------------------------------------------------*/ XfwfFileChooserClassRec xfwfFileChooserClassRec = { { /* superclass */ (WidgetClass)&compositeClassRec, /* class_name */ "XfwfFileChooser", /* widget_size */ sizeof(XfwfFileChooserRec), /* class_initialize */ NULL, /* class_part_initialize*/ NULL, /* class_inited */ FALSE, /* initialize */ (XtInitProc)Initialize, /* initialize_hook */ NULL, /* realize */ (XtRealizeProc)Realize, /* actions */ NULL, /* num_actions */ 0, /* resources */ resources, /* resource_count */ XtNumber(resources), /* xrm_class */ NULLQUARK, /* compress_motion */ TRUE, /* compress_exposure */ TRUE, /* compress_enterleave */ TRUE, /* visible_interest */ FALSE, /* destroy */ (XtWidgetProc)Destroy, /* resize */ (XtWidgetProc)Resize, /* expose */ XtInheritExpose, /* set_values */ (XtSetValuesFunc)SetValues, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ NULL, /* version */ XtVersion, /* callback_private */ NULL, /* tm_table */ NULL, /* query_geometry */ XtInheritQueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL }, /* Core Part */ { /* geometry_manager */ GeometryManager, /* change_managed */ XtInheritChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL }, /* Composite Part */ { /* no extra class data */ 0 } /* FileSelector Part */ }; WidgetClass xfwfFileChooserWidgetClass = (WidgetClass)&xfwfFileChooserClassRec; /*---------------------------------------------------------------------------* E X P O R T E D M E T H O D S *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* Initialize() This procedure is called by the X toolkit to initialize the FileChooser widget instance. The hook to this routine is in the initialize part of the core part of the class. *---------------------------------------------------------------------------*/ /* ARGSUSED */ static void Initialize(request,new) Widget request,new; { XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)new; char *str,*initial_file,path[MAXPATHLEN + 2]; static char *star = "*"; FCBusyCursor(fcw) = XCreateFontCursor(XtDisplay(fcw),XC_watch); FCDirMenu(fcw) = NULL; FCDirMenuButton(fcw) = NULL; FCFileList(fcw) = NULL; FCDirMgr(fcw) = NULL; FCFileNames(fcw) = NULL; FCNumFileNames(fcw) = 0; FCDirNames(fcw) = NULL; FCNumDirNames(fcw) = 0; str = (char *)XtCalloc((MAXPATHLEN + 2),sizeof(char)); if (FCCurrentDirectory(fcw) != NULL) { /* User Specified Path */ strcpy(str,FCCurrentDirectory(fcw)); } else { getwd(path); strcpy(str,path); } FCCurrentDirectory(fcw) = str; str = (char *)XtCalloc((MAXPATHLEN + 2),sizeof(char)); initial_file = FCCurrentFile(fcw); FCCurrentFile(fcw) = str; if (FCCorePart(request)->width <= 0) FCCorePart(new)->width = 500; if (FCCorePart(request)->height <= 0) FCCorePart(new)->height = 200; if (FCPattern(fcw) == NULL) FCPattern(fcw) = star; FCPattern(fcw) = XtNewString(FCPattern(fcw)); ChildrenCreate(fcw); GotoDeepestLegalDirectory(fcw); if (initial_file) SelectFileByName(fcw,initial_file); } /* End Initialize */ /*---------------------------------------------------------------------------* Realize() This function is called to realize a FileChooser widget. *---------------------------------------------------------------------------*/ static void Realize(w,valueMask,attrs) Widget w; XtValueMask *valueMask; XSetWindowAttributes *attrs; { XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)w; XtCreateWindow(w,InputOutput,(Visual *)CopyFromParent,*valueMask,attrs); ChildrenRealize(fcw); ChildrenUpdate(fcw); Resize(w); Notify(fcw); } /* End Realize */ /*---------------------------------------------------------------------------* Destroy() This function is called to destroy a FileChooser widget. *---------------------------------------------------------------------------*/ static void Destroy(fcw) XfwfFileChooserWidget fcw; { int i; XtFree(FCCurrentDirectory(fcw)); XtFree(FCCurrentFile(fcw)); XtFree(FCPattern(fcw)); if (FCFileNames(fcw) != NULL) { for (i=0; i < FCNumFileNames(fcw); i++) XtFree(FCFileNames(fcw)[i]); XtFree(FCFileNames(fcw)); } if (FCDirNames(fcw) != NULL) { for (i=0; i < FCNumDirNames(fcw); i++) XtFree(FCDirNames(fcw)[i]); XtFree(FCDirNames(fcw)); } } /* End Destroy */ /*---------------------------------------------------------------------------* Resize() This function is called to resize a FileChooser widget. *---------------------------------------------------------------------------*/ static void Resize(w) Widget w; { XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)w; ChildrenUpdate(fcw); } /* End Resize */ /*---------------------------------------------------------------------------* SetValues() This function is the external interface for setting resources. *---------------------------------------------------------------------------*/ /* ARGSUSED */ static Boolean SetValues(current,request,new) Widget current,request,new; { XfwfFileChooserWidget fcw_current = (XfwfFileChooserWidget)current; XfwfFileChooserWidget fcw_new = (XfwfFileChooserWidget)new; XfwfFileChooserWidget fcw_request = (XfwfFileChooserWidget)request; if (FCCurrentDirectory(fcw_current) != FCCurrentDirectory(fcw_new)){ /* strcpy(FCCurrentDirectory(fcw_current),FCCurrentDirectory(fcw_new)); FCCurrentDirectory(fcw_new) = FCCurrentDirectory(fcw_current); */ /* didn't understand why to copy the new string into old space and use this for the new widget ?! - ACZ */ Chdir(fcw_new); } if (FCCurrentFile(fcw_current) != FCCurrentFile(fcw_new)) { char *new_name; new_name = FCCurrentFile(fcw_new); FCCurrentFile(fcw_new) = FCCurrentFile(fcw_current); SelectFileByName(fcw_new,new_name); } if (FCPattern(fcw_current) != FCPattern(fcw_new)) { /* XtFree(FCPattern(fcw_current)); FCPattern(fcw_new) = XtNewString(FCPattern(fcw_request)); */ /* above was XtNewString(FCPattern(fcw_current)) - ACZ */ Chdir(fcw_new); } if (FCSortMode(fcw_current) != FCSortMode(fcw_new)) { Chdir(fcw_new); } return(False); } /* End SetValues() */ /*---------------------------------------------------------------------------* GeometryManager(w,request,reply) This routine acts as the geometry_manager method for the FileChooser widget. It is called when a child wants to resize/reposition itself. Currently, we allow all requests. *---------------------------------------------------------------------------*/ /* ARGSUSED */ static XtGeometryResult GeometryManager(w,request,reply) Widget w; XtWidgetGeometry *request; XtWidgetGeometry *reply; { return(XtGeometryYes); } /* End GeometryManager */ /*---------------------------------------------------------------------------* L O C A L R O U T I N E S *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* ChildrenCreate(fcw) This routine creates the initial child widgets for the file selector widget and places them in the widget fcw. No placement or resizing is done. That is done by ChildrenUpdate(). *---------------------------------------------------------------------------*/ static void ChildrenCreate(fcw) XfwfFileChooserWidget fcw; { static char *str = NULL; FCDirMenuButton(fcw) = XtVaCreateManagedWidget(FC_DIR_MENU_BUTTON_NAME,menuButtonWidgetClass, (Widget)fcw, XtNmenuName, FC_DIR_MENU_NAME, NULL); FCFileViewport(fcw) = XtVaCreateManagedWidget(FC_FILE_VIEWPORT_NAME,viewportWidgetClass, (Widget)fcw, XtNallowVert, True, XtNforceBars, True, XtNuseRight, True, NULL); FCFileList(fcw) = XtVaCreateManagedWidget(FC_FILE_LIST_NAME,listWidgetClass, FCFileViewport(fcw), XtNlist, &str, XtNdefaultColumns, 1, XtNforceColumns, True, XtNverticalList, True, /* XtNborderWidth, 0, */ NULL); XtAddCallback(FCFileList(fcw),XtNcallback, (XtCallbackProc)FileCallback,(XtPointer)fcw); } /* End ChildrenCreate */ /*---------------------------------------------------------------------------* ChildrenRealize(fcw) This routine realizes the child widgets. The widgets must already have been created and initialized. Their coordinates should already have been set. *---------------------------------------------------------------------------*/ static void ChildrenRealize(fcw) XfwfFileChooserWidget fcw; { XtRealizeWidget(FCDirMenuButton(fcw)); XtRealizeWidget(FCFileViewport(fcw)); XtRealizeWidget(FCFileList(fcw)); } /* End ChildrenRealize */ /*---------------------------------------------------------------------------* ChildrenUpdate(fcw) This routine takes a FileChooser widget fcw and updates the child widgets by recalculating their coordinates based on the current size of the FileChooser, and setting the appropriate resources. We go to some trouble to get something useful displayed in the FCDirMenuButton(fcw) if the current directory name is too long to fit in the button. It would be nice if the "justify" resource of the MenuButton widget did this, but... *---------------------------------------------------------------------------*/ static void ChildrenUpdate(fcw) XfwfFileChooserWidget fcw; { Dimension w,h; int gap; Dimension menuButtonW,menuButtonH,fileListW,fileListH; Position menuButtonX,menuButtonY,fileListX,fileListY; XtWidgetGeometry parent_idea,child_idea; XFontStruct *fs; char *label; Dimension intw; if (!XtIsRealized((Widget)fcw)) { return; } w = CoreWidth(fcw); h = CoreHeight(fcw); gap = 3; intw = 8; XtVaGetValues(FCDirMenuButton(fcw), XtNfont, &fs, NULL); /* Get The Child Widgets Current Widths And Heights */ /* (although we don't actually use the existing values... */ menuButtonW = CoreWidth(FCDirMenuButton(fcw)); menuButtonH = CoreHeight(FCDirMenuButton(fcw)); /* Adjust Widths */ menuButtonW = w; fileListW = w; /* Adjust menu button label if too small */ /* It would be nice if the "justify" resource of MenuButton did this... */ label = FCCurrentDirectory(fcw); if (XTextWidth(fs,label,strlen(label)) > menuButtonW-intw) { char newLabel[MAXPATHLEN]; /* cut away chars from left side until it fits into the button */ while (*label && XTextWidth(fs,label,strlen(label))>menuButtonW-intw) { label += 1; } if (*label) label += 1; strcpy(newLabel,""); /* was "<" - ACZ */ strcat(newLabel,label); XtVaSetValues(FCDirMenuButton(fcw), XtNlabel, newLabel, NULL); } else { XtVaSetValues(FCDirMenuButton(fcw), XtNlabel, label, NULL); } /* Adjust Heights */ fileListH = h - menuButtonH - gap; /* Listen To Child Height Request For List */ /* parent_idea.request_mode = CWWidth | CWHeight; parent_idea.width = fileListW; parent_idea.height = fileListH; XtQueryGeometry(FCFileList(fcw),&parent_idea,&child_idea); if ((child_idea.request_mode & CWHeight) && (child_idea.height < parent_idea.height)) { fileListH = child_idea.height; } */ /* Vertical Positions */ menuButtonY = 0; fileListY = menuButtonH + gap; /* Horizontal Positions */ menuButtonX = 0; fileListX = 0; /* Move them */ XtMoveWidget(FCDirMenuButton(fcw),menuButtonX,menuButtonY); XtMoveWidget(FCFileViewport(fcw),fileListX,fileListY); /* Resize them */ XtResizeWidget(FCDirMenuButton(fcw),menuButtonW,menuButtonH, CoreBorderWidth(FCDirMenuButton(fcw))); XtResizeWidget(FCFileViewport(fcw),fileListW,fileListH, CoreBorderWidth(FCFileViewport(fcw))); } /* End ChildrenUpdate */ /*---------------------------------------------------------------------------* I N T E R N A L C A L L B A C K S *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* DirectoryCallback(w,client_data,call_data) This is called when the user selects an ancestor directory from the menu. The argument "w" is the selected object (hence the two calls to XtParent()) and "client_data" is it's index in the menu. *---------------------------------------------------------------------------*/ /*ARGSUSED*/ static void DirectoryCallback(w,client_data,call_data) Widget w; XtPointer client_data; /* index */ XtPointer call_data; /* not used */ { int index = (int)client_data; XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)XtParent(XtParent(w)); int i; strcpy(FCCurrentDirectory(fcw),"/"); for (i = 1; i <= index; i++) { strcat(FCCurrentDirectory(fcw),FCDirNames(fcw)[i]); strcat(FCCurrentDirectory(fcw),"/"); } Chdir(fcw); } /* End DirectoryCallback */ /*---------------------------------------------------------------------------* FileCallback(w,client_data,call_data) This is called when the user selects a file in the fileList. The argument "client_data" is the FileChooser widget, "call_data" is a pointer to the standard List widget callback information. *---------------------------------------------------------------------------*/ /*ARGSUSED*/ static void FileCallback(w,client_data,call_data) Widget w; XtPointer client_data; /* fcw */ XtPointer call_data; /* return struct */ { XfwfFileChooserWidget fcw = (XfwfFileChooserWidget)client_data; XawListReturnStruct *ret = (XawListReturnStruct *)call_data; if (ret->list_index == -1) { UnselectAll(fcw); /* Click On Blank Space */ Notify(fcw); } else { SelectFileByIndex(fcw,ret->list_index); } } /* End FileCallback */ /*---------------------------------------------------------------------------* I N T E R N A L S U P P O R T R O U T I N E S *---------------------------------------------------------------------------*/ static void SelectFileByIndex(fcw,index) XfwfFileChooserWidget fcw; int index; { DirEntry *dir_entry; DirectoryMgrGotoItem(FCDirMgr(fcw),index); if ((dir_entry=DirectoryMgrCurrentEntry(FCDirMgr(fcw))) == NULL) { fprintf(stderr,"SelectFileByIndex: Entry %d invalid\n",index); exit(-1); } if (DirEntryIsDir(dir_entry) || DirEntryIsDirectoryLink(dir_entry)) { strcat(FCCurrentDirectory(fcw),DirEntryFileName(dir_entry)); Chdir(fcw); } else if (!DirEntryIsBrokenLink(dir_entry)) { /* File */ strcpy(FCCurrentFile(fcw),DirEntryFileName(dir_entry)); XawListHighlight(FCFileList(fcw),index); Notify(fcw); } else { /* Broken Link */ XBell(XtDisplay(fcw),0); UnselectAll(fcw); } } /* End SelectFileByIndex */ static Boolean SelectFileByName(fcw,name) XfwfFileChooserWidget fcw; char *name; { if (DirectoryMgrGotoNamedItem(FCDirMgr(fcw),name) == FALSE) { return(False); } SelectFileByIndex(fcw,DirectoryMgrCurrentIndex(FCDirMgr(fcw))); return(True); } /* End SelectFileByName */ static void UnselectAll(fcw) XfwfFileChooserWidget fcw; { Boolean selected = FCCurrentFile(fcw)[0] != '\0'; FCCurrentFile(fcw)[0] = '\0'; XawListUnhighlight(FCFileList(fcw)); if (selected) Notify(fcw); } /* End UnselectAll */ static void Notify(fcw) XfwfFileChooserWidget fcw; { XfwfFileChooserReturnStruct ret; if (FCCurrentFile(fcw)[0] != '\0') { ret.directory = FCCurrentDirectory(fcw); ret.file = FCCurrentFile(fcw); } else { ret.directory = NULL; ret.file = NULL; } XtCallCallbacks((Widget)fcw,XtNcallback,(XtPointer)&ret); } /* End Notify */ /*---------------------------------------------------------------------------* GotoDeepestLegalDirectory(fcw) This function takes a FileChooser widget and modifies the directory string in FCCurrentDirectory(fcw) to be the deepest legal directory above the string. Partial or incorrect directory names are stripped starting at the end. It then calls UpdateLists() to reset the information dislayed in the FileChooser. *---------------------------------------------------------------------------*/ static void GotoDeepestLegalDirectory(fcw) XfwfFileChooserWidget fcw; { char *dir,*end; char temp[MAXPATHLEN + 2]; dir = FCCurrentDirectory(fcw); for (end=dir; *end != '\0'; ++end) /*EMPTY*/; while (1) { if (DirectoryPathExpand(dir,temp) == NULL) { while (*end != '/' && end != dir) { end -= 1; } *end = '\0'; } else { strcpy(FCCurrentDirectory(fcw),temp); break; } } UnselectAll(fcw); UpdateLists(fcw); } /* End GotoDeepestLegalDirectory */ /*---------------------------------------------------------------------------* UpdateLists(fcw) This routine resets the information displayed in a FileChooser widget by doing the following: 1. It changes the cursor to the value of the "busyCursor" resource. 2. The old directory manager (FCDirMgr(fcw)) is closed and a new one opened based on the value of FCCurrentDirectory(fcw). 3. Any old string arrays are freed, and any existing directory menu is destroyed. 4. A new array of strings (FCFileNames(fcw)) is allocated and filled with the names of the files in the directory, then this array is used to set what is displayed in the FCFileList(fcw) widget. 5. A new array of strings (FCDirNames(fcw)) is allocated and filled with the names of the ancestor directories. These are also used to create a new FCDirMenu(fcw), and the label FCDirMenuButton(fcw) is set to the name of the directory. 6. Finally, the cursor is restored. *---------------------------------------------------------------------------*/ static void UpdateLists(fcw) XfwfFileChooserWidget fcw; { int i,count; char *dir,*start; DirEntry *dir_entry; char temp[MAXPATHLEN + 2]; Widget menuItem; if (XtIsRealized((Widget)fcw)) { /* This is puke-ola. */ XDefineCursor(XtDisplay(fcw),XtWindow(fcw),FCBusyCursor(fcw)); XDefineCursor(XtDisplay(fcw),XtWindow(FCFileList(fcw)), FCBusyCursor(fcw)); XDefineCursor(XtDisplay(fcw),XtWindow(FCDirMenuButton(fcw)), FCBusyCursor(fcw)); XFlush(XtDisplay(fcw)); } if (FCDirMgr(fcw)) DirectoryMgrClose(FCDirMgr(fcw)); FCDirMgr(fcw) = DirectoryMgrSimpleOpen(FCCurrentDirectory(fcw), FCSortMode(fcw),FCPattern(fcw)); /* Throw away old info */ if (FCFileNames(fcw) != NULL) { for (i = 0; i < FCNumFileNames(fcw); i++) XtFree(FCFileNames(fcw)[i]); XtFree((char *)FCFileNames(fcw)); } if (FCDirNames(fcw) != NULL) { for (i = 0; i < FCNumDirNames(fcw); i++) XtFree(FCDirNames(fcw)[i]); XtFree((char *)FCDirNames(fcw)); } if (FCDirMenu(fcw) != NULL) XtDestroyWidget(FCDirMenu(fcw)); /* Count how many files and dirs we have now */ FCNumFileNames(fcw) = DirectoryMgrFilteredCount(FCDirMgr(fcw)); FCNumDirNames(fcw) = 1; for (dir=FCCurrentDirectory(fcw)+1; *dir != '\0'; dir++) { if (*dir == '/') FCNumDirNames(fcw) += 1; } /* Make the array of filenames and set the fileList widget */ FCFileNames(fcw) = (char **)XtCalloc(FCNumFileNames(fcw)+1,sizeof(char *)); for (i=0; i < FCNumFileNames(fcw); i++) { dir_entry = DirectoryMgrNextEntry(FCDirMgr(fcw)); if (dir_entry == NULL) XtError("Inconsistent Directory"); strcpy(temp,DirEntryFileName(dir_entry)); if (DirEntryIsDir(dir_entry)) strcat(temp,"/"); else if (DirEntryIsBrokenLink(dir_entry)) strcat(temp," X"); else if (DirEntryIsDirectoryLink(dir_entry)) strcat(temp,"/"); else if (DirEntryIsSymLink(dir_entry)) strcat(temp," @"); FCFileNames(fcw)[i] = XtNewString(temp); } FCFileNames(fcw)[i] = NULL; XawListChange(FCFileList(fcw),FCFileNames(fcw),0,0,True); /* Make the array of dirnames and build a new dirMenu widget */ FCDirNames(fcw) = (char **)XtCalloc(FCNumDirNames(fcw)+1,sizeof(char *)); FCDirNames(fcw)[0] = XtNewString("/"); FCDirMenu(fcw) = XtCreatePopupShell(FC_DIR_MENU_NAME,simpleMenuWidgetClass, (Widget)fcw,NULL,0); menuItem = XtCreateManagedWidget("/",smeBSBObjectClass,FCDirMenu(fcw), NULL,0); XtAddCallback(menuItem,XtNcallback,DirectoryCallback,(XtPointer)0); start = FCCurrentDirectory(fcw); for (i = 1; i < FCNumDirNames(fcw); i++) { while (*start != '\0' && *start == '/') start += 1; count = 0; while (*start != '\0' && *start != '/') temp[count++] = *start++; temp[count] = '\0'; FCDirNames(fcw)[i] = XtNewString(temp); menuItem = XtVaCreateManagedWidget("dirMenuItem",smeBSBObjectClass, FCDirMenu(fcw), XtNlabel, temp, NULL); XtAddCallback(menuItem,XtNcallback,DirectoryCallback,(XtPointer)i); } XtVaSetValues(FCDirMenuButton(fcw), XtNlabel,FCCurrentDirectory(fcw), NULL); if (XtIsRealized((Widget)fcw)) { XUndefineCursor(XtDisplay(fcw),XtWindow(fcw)); XUndefineCursor(XtDisplay(fcw),XtWindow(FCFileList(fcw))); XUndefineCursor(XtDisplay(fcw),XtWindow(FCDirMenuButton(fcw))); } } /* End UpdateLists */ static void Chdir(fcw) XfwfFileChooserWidget fcw; { GotoDeepestLegalDirectory(fcw); ChildrenUpdate(fcw); } /* End Chdir */ /*---------------------------------------------------------------------------* E X T E R N A L R O U T I N E S *---------------------------------------------------------------------------*/ void XfwfFileChooserChangeDirectory(fcw,dir) XfwfFileChooserWidget fcw; char *dir; { strcpy(FCCurrentDirectory(fcw),dir); Chdir(fcw); } /* End XfwfFileChooserChangeDirectory */ void XfwfFileChooserRefresh(fcw) XfwfFileChooserWidget fcw; { XfwfFileChooserChangeDirectory(fcw,"."); } /* End XfwfFileChooserRefresh */ char * XfwfFileChooserCurrentDirectory(fcw) XfwfFileChooserWidget fcw; { return(FCCurrentDirectory(fcw)); } /* End XfwfFileChooserCurrentDirectory */ char * XfwfFileChooserCurrentFile(fcw) XfwfFileChooserWidget fcw; { return(FCCurrentFile(fcw)); } /* End XfwfFileChooserCurrentFile */ acfax/FChooser.h100644 765 144 5734 6002243255 13052 0ustar andreasusers/* * FChooser.h : Public header file for the FileChooser widget * * George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993. * * This code is derived from the FileSelector widget by Brian Totty, * hence the following copyright applies: * * Copyright 1990,1991,1992 Brian Totty * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Brian Totty or * University of Illinois not be used in advertising or publicity * pertaining to distribution of the software without specific, written * prior permission. Brian Totty and University of Illinois make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * Brian Totty and University of Illinois disclaim all warranties with * regard to this software, including all implied warranties of * merchantability and fitness, in no event shall Brian Totty or * University of Illinois 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: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #ifndef _FCHOOSER_H #define _FCHOOSER_H #include "DirMgr.h" extern WidgetClass xfwfFileChooserWidgetClass; typedef struct _XfwfFileChooserClassRec *XfwfFileChooserWidgetClass; typedef struct _XfwfFileChooserRec *XfwfFileChooserWidget; #ifndef XtNcurrentDirectory #define XtNcurrentDirectory "currentDirectory" #endif #define XtNcurrentFile "currentFile" #define XtNsortMode "sortMode" #define XtNpattern "pattern" #define XtCPathname "Pathname" #define XtCFilename "Filename" typedef struct _XfwfFileChooserReturnStruct { char *directory; char *file; } XfwfFileChooserReturnStruct; /*---------------------------------------------------------------------------* E X T E R N A L F U N C T I O N S *---------------------------------------------------------------------------*/ #if (!NeedFunctionPrototypes) void XfwfFileChooserChangeDirectory(); void XfwfFileChooserRefresh(); char *XfwfFileChooserCurrentDirectory(); char *XfwfFileChooserCurrentFile(); #else void XfwfFileChooserChangeDirectory(XfwfFileChooserWidget fcw, char *dir); void XfwfFileChooserRefresh(XfwfFileChooserWidget fcw); char *XfwfFileChooserCurrentDirectory(XfwfFileChooserWidget fcw); char *XfwfFileChooserCurrentFile(XfwfFileChooserWidget fcw); #endif /* !NeedFunctionPrototypes */ #endif /* !_FCHOOSER_H */ acfax/FChooserP.h100644 765 144 10701 6002243275 13202 0ustar andreasusers/* * FChooserP.h : Private header file for the FileChooser widget * * George Ferguson, ferguson@cs.rochester.edu, 21 Jan 1993. * * This code is derived from the FileSelector widget by Brian Totty, * hence the following copyright applies: * * Copyright 1990,1991,1992 Brian Totty * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Brian Totty or * University of Illinois not be used in advertising or publicity * pertaining to distribution of the software without specific, written * prior permission. Brian Totty and University of Illinois make no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * Brian Totty and University of Illinois disclaim all warranties with * regard to this software, including all implied warranties of * merchantability and fitness, in no event shall Brian Totty or * University of Illinois 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: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #ifndef _FCHOOSERP_H #define _FCHOOSERP_H #include "DirMgr.h" #include #include /*---------------------------------------------------------------------------* C O N S T A N T S *---------------------------------------------------------------------------*/ #define FC_DIR_MENU_NAME "dirMenu" #define FC_DIR_MENU_BUTTON_NAME "dirMenuButton" #define FC_FILE_VIEWPORT_NAME "fileViewport" #define FC_FILE_LIST_NAME "fileList" /*---------------------------------------------------------------------------* S T R U C T U R E & W I D G E T A C C E S S M A C R O S *---------------------------------------------------------------------------*/ #define FCCorePart(w) (&((w)->core)) #define FCCompositePart(w) (&((w)->composite)) #define FCFCPart(w) (&((w)->fileChooser)) #define FCDirMgr(w) (FCFCPart(w)->dir_mgr) #define FCDirMenu(w) (FCFCPart(w)->dir_menu) #define FCDirMenuButton(w) (FCFCPart(w)->dir_menu_button) #define FCFileViewport(w) (FCFCPart(w)->file_viewport) #define FCFileList(w) (FCFCPart(w)->file_list) #define FCCurrentDirectory(w) (FCFCPart(w)->current_dir) #define FCCurrentFile(w) (FCFCPart(w)->current_file) #define FCDirNames(w) (FCFCPart(w)->dir_names) #define FCNumDirNames(w) (FCFCPart(w)->num_dir_names) #define FCFileNames(w) (FCFCPart(w)->file_names) #define FCNumFileNames(w) (FCFCPart(w)->num_file_names) #define FCBusyCursor(w) (FCFCPart(w)->busy_cursor) #define FCSortMode(w) (FCFCPart(w)->sort_mode) #define FCPattern(w) (FCFCPart(w)->pattern) #define CoreWidth(w) ((w)->core.width) #define CoreHeight(w) ((w)->core.height) #define CoreBorderWidth(w) ((w)->core.border_width) /*---------------------------------------------------------------------------* W I D G E T S T R U C T U R E D E F I N I T I O N *---------------------------------------------------------------------------*/ typedef struct { DIRECTORY_MGR *dir_mgr; Widget dir_menu; Widget dir_menu_button; Widget file_viewport; Widget file_list; char *current_dir; char *current_file; char **dir_names; int num_dir_names; char **file_names; int num_file_names; XtCallbackList callbacks; Cursor busy_cursor; int sort_mode; char *pattern; } XfwfFileChooserPart; typedef struct _XfwfFileChooserClassPart { int empty; } XfwfFileChooserClassPart; typedef struct _XfwfFileChooserClassRec { CoreClassPart core_class; CompositeClassPart composite_class; XfwfFileChooserClassPart fileChooser_class; } XfwfFileChooserClassRec; /* This Is What A Widget Instance Points To */ typedef struct _XfwfFileChooserRec { CorePart core; CompositePart composite; XfwfFileChooserPart fileChooser; } XfwfFileChooserRec; extern XfwfFileChooserClassRec xfwfFileChooserClassRec; #endif /* !_FCHOOSERP_H */ acfax/DirMgr.c100644 765 144 26123 5773037127 12551 0ustar andreasusers/**************************************************************************** DirMgr.c This file contains the C code to implement the DirectoryMgr system. This system is intended to manage filtered and sorted directory lists. ****************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #include "DirMgr.h" #ifndef NO_REGEXP #include "RegExp.h" #endif #define DIR_MGR_FSM_SIZE 1024 /*---------------------------------------------------------------------------* S I M P L E I N T E R F A C E *---------------------------------------------------------------------------*/ DirectoryMgr *DirectoryMgrSimpleOpen(path,sort_type,pattern) char *path; int sort_type; char *pattern; { DirectoryMgr *dm; PFI f_func,s_func; char *f_data; if (pattern == NULL) pattern = "*"; if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data)) { return(NULL); } if (!DirectoryMgrSimpleSortingFunc(sort_type,&s_func)) { free(f_data); return(NULL); } dm = DirectoryMgrOpen(path,s_func,f_func,f_data,TRUE); return(dm); } /* End DirectoryMgrSimpleOpen */ int DirectoryMgrSimpleRefilter(dm,pattern) DirectoryMgr *dm; char *pattern; { PFI f_func; char *f_data; if (!DirectoryMgrSimpleFilterFunc(pattern,&f_func,&f_data)) { return(FALSE); } DirectoryMgrRefilter(dm,f_func,f_data,TRUE); return(TRUE); } /* End DirectoryMgrSimpleRefilter */ int DirectoryMgrSimpleResort(dm,sort_type) DirectoryMgr *dm; int sort_type; { PFI c_func; if (!DirectoryMgrSimpleSortingFunc(sort_type,&c_func)) { return(FALSE); } DirectoryMgrResort(dm,c_func); return(TRUE); } /* End DirectoryMgrSimpleResort */ /*---------------------------------------------------------------------------* N O R M A L I N T E R F A C E *---------------------------------------------------------------------------*/ int DirectoryMgrCanOpen(path) char *path; { int status; Directory dir; status = DirectoryOpen(path,&dir); if (status == TRUE) DirectoryClose(&dir); return(status); } /* End DirectoryMgrCanOpen */ DirectoryMgr *DirectoryMgrOpen(path,c_func,f_func,f_data,free_data) char *path; PFI c_func,f_func; char *f_data; int free_data; { DirectoryMgr *dm; dm = (DirectoryMgr *)calloc(1,sizeof(DirectoryMgr)); if (dm == NULL) { fprintf(stderr,"DirectoryMgrOpen: out of memory\n"); if (free_data && f_data) free(f_data); return(NULL); } if (DirectoryOpen(path,DirectoryMgrDir(dm)) == FALSE) { fprintf(stderr,"DirectoryMgrOpen: can't open dir '%s'\n", DirectoryMgrDir(dm)); free(dm); if (free_data && f_data) free(f_data); return(NULL); } DirectoryMgrCompFunc(dm) = c_func; DirectoryMgrRefilter(dm,f_func,f_data,free_data); return(dm); } /* End DirectoryMgrOpen */ void DirectoryMgrClose(dm) DirectoryMgr *dm; { free(DirectoryMgrData(dm)); free(DirectoryMgrSortedPtrs(dm)); if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm)) { free(DirectoryMgrFilterData(dm)); } DirectoryClose(DirectoryMgrDir(dm)); free(dm); } /* End DirectoryMgrClose */ int DirectoryMgrRefilter(dm,f_func,f_data,f_free) DirectoryMgr *dm; PFI f_func; char *f_data; int f_free; { if (DirectoryMgrFilterData(dm) && DirectoryMgrFreeFilterData(dm)) { free(DirectoryMgrFilterData(dm)); } DirectoryMgrFilterFunc(dm) = f_func; DirectoryMgrFilterData(dm) = f_data; DirectoryMgrFreeFilterData(dm) = f_free; DirectoryMgrRefresh(dm); } /* End DirectoryMgrRefilter */ int DirectoryMgrRefresh(dm) DirectoryMgr *dm; { int err,data_size,ptrs_size,i; DirEntryCons *head,*tail,*cons; DirEntry *dm_data,**dm_ptrs; PFI f_func; char *f_data; DirectoryMgrTotalCount(dm) = 0; DirectoryMgrFilteredCount(dm) = 0; DirectoryRestart(DirectoryMgrDir(dm)); if (DirectoryMgrData(dm)) free(DirectoryMgrData(dm)); if (DirectoryMgrSortedPtrs(dm)) free(DirectoryMgrSortedPtrs(dm)); head = NULL; f_func = DirectoryMgrFilterFunc(dm); f_data = DirectoryMgrFilterData(dm); while (1) { cons = (DirEntryCons *)malloc(sizeof(DirEntryCons)); if (cons == NULL) { fprintf(stderr, "DirectoryMgrRefresh: Can't Alloc Cons\n"); exit(-1); } err = DirectoryReadNextEntry(DirectoryMgrDir(dm), &(cons->dir_entry)); if (err == FALSE) { free(cons); break; } ++ DirectoryMgrTotalCount(dm); if ((f_func == NULL) || (f_func && f_func(&(cons->dir_entry),f_data))) { cons->next = NULL; if (head == NULL) head = cons; else tail->next = cons; tail = cons; ++ DirectoryMgrFilteredCount(dm); } else /* Filter Failed */ { free(cons); } } data_size = sizeof(DirEntry) * DirectoryMgrFilteredCount(dm); ptrs_size = sizeof(DirEntry *) * DirectoryMgrFilteredCount(dm); /* changed next 2 lines due to malloc(0) returning NULL - ACZ */ if (data_size) dm_data = (DirEntry *)malloc(data_size); if (ptrs_size) dm_ptrs = (DirEntry **)malloc(ptrs_size); if ((dm_data == NULL) || (dm_ptrs == NULL)) { fprintf(stderr,"DirectoryMgrRefresh: Out of memory\n"); exit(1); } DirectoryMgrData(dm) = dm_data; DirectoryMgrSortedPtrs(dm) = dm_ptrs; for (i = 0; i < DirectoryMgrFilteredCount(dm); i++) { DirectoryMgrData(dm)[i] = head->dir_entry; DirectoryMgrSortedPtrs(dm)[i] = &(DirectoryMgrData(dm)[i]); cons = head->next; free(head); head = cons; } DirectoryMgrResort(dm,DirectoryMgrCompFunc(dm)); DirectoryMgrRestart(dm); return(TRUE); } /* End DirectoryMgrRefresh */ void DirectoryMgrResort(dm,c_func) DirectoryMgr *dm; PFI c_func; { DirectoryMgrCompFunc(dm) = c_func; if (c_func != NULL) { qsort(DirectoryMgrSortedPtrs(dm),DirectoryMgrFilteredCount(dm), sizeof(DirEntry *),DirectoryMgrCompFunc(dm)); } DirectoryMgrRestart(dm); } /* End DirectoryMgrResort */ /*---------------------------------------------------------------------------* I T E R A T I O N C O M M A N D S *---------------------------------------------------------------------------*/ int DirectoryMgrGotoItem(dm,i) DirectoryMgr *dm; int i; { if (i < 0 || i >= DirectoryMgrFilteredCount(dm)) return(FALSE); DirectoryMgrCurrentIndex(dm) = i; return(TRUE); } /* End DirectoryMgrGotoItem */ int DirectoryMgrGotoNamedItem(dm,name) DirectoryMgr *dm; char *name; { int i; DirEntry *entry; for (i = 0; i < DirectoryMgrFilteredCount(dm); i++) { entry = DirectoryMgrSortedPtrs(dm)[i]; if (strcmp(DirEntryFileName(entry),name) == 0) { DirectoryMgrCurrentIndex(dm) = i; return(TRUE); } } return(FALSE); } /* End DirectoryMgrGotoNamedItem */ void DirectoryMgrRestart(dm) DirectoryMgr *dm; { DirectoryMgrCurrentIndex(dm) = 0; } /* End DirectoryMgrRestart */ DirEntry *DirectoryMgrCurrentEntry(dm) DirectoryMgr *dm; { int index; index = DirectoryMgrCurrentIndex(dm); if (index < 0 || index >= DirectoryMgrFilteredCount(dm)) return(NULL); return(DirectoryMgrSortedPtrs(dm)[index]); } /* End DirectoryMgrCurrentEntry */ DirEntry *DirectoryMgrNextEntry(dm) DirectoryMgr *dm; { int index; index = DirectoryMgrCurrentIndex(dm); if (index >= DirectoryMgrFilteredCount(dm)) return(NULL); ++ DirectoryMgrCurrentIndex(dm); return(DirectoryMgrSortedPtrs(dm)[index]); } /* End DirectoryMgrNextEntry */ DirEntry *DirectoryMgrPrevEntry(dm) DirectoryMgr *dm; { int index; index = DirectoryMgrCurrentIndex(dm) - 1; if (index < 0) return(NULL); -- DirectoryMgrCurrentIndex(dm); return(DirectoryMgrSortedPtrs(dm)[index]); } /* End DirectoryMgrPrevEntry */ /*---------------------------------------------------------------------------* U T I L I T Y F U N C T I O N S *---------------------------------------------------------------------------*/ int DirectoryMgrSimpleFilterFunc(pattern,ff_ptr,fd_ptr) char *pattern; PFI *ff_ptr; char **fd_ptr; { #ifndef NO_REGEXP char regexp[2048]; *ff_ptr = DirectoryMgrFilterName; *fd_ptr = (char *)malloc(sizeof(regex_t)); if (*fd_ptr == NULL) return(FALSE); RegExpPatternToRegExp(pattern,regexp); re_set_syntax(RE_SYNTAX_EGREP); strcat(regexp,"|^\\.+$"); /* ALWAYS! match . and .. - ACZ */ RegExpCompile(regexp,(regex_t *)*fd_ptr); #endif return(TRUE); } /* End DirectoryMgrSimpleFilterFunc */ int DirectoryMgrSimpleSortingFunc(sort_type,sf_ptr) int sort_type; PFI *sf_ptr; { *sf_ptr = NULL; switch (sort_type) { case DIR_MGR_SORT_NONE: break; case DIR_MGR_SORT_NAME: *sf_ptr = DirectoryMgrCompareName; break; case DIR_MGR_SORT_SIZE_ASCENDING: *sf_ptr = DirectoryMgrCompareSizeAscending; break; case DIR_MGR_SORT_SIZE_DESCENDING: *sf_ptr = DirectoryMgrCompareSizeDescending; break; case DIR_MGR_SORT_NAME_DIRS_FIRST: *sf_ptr = DirectoryMgrCompareNameDirsFirst; break; case DIR_MGR_SORT_ACCESS_ASCENDING: *sf_ptr = DirectoryMgrCompareLastAccessAscending; break; case DIR_MGR_SORT_ACCESS_DESCENDING: *sf_ptr = DirectoryMgrCompareLastAccessDescending; break; default: fprintf(stderr,"Bad sort type %d\n",sort_type); return(FALSE); } return(TRUE); } /* End DirectoryMgrSimpleSortingFunc */ /*---------------------------------------------------------------------------* S O R T I N G R O U T I N E S *---------------------------------------------------------------------------*/ int DirectoryMgrCompareName(e1p,e2p) DirEntry **e1p,**e2p; { return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p))); } /* End DirectoryMgrCompareName */ int DirectoryMgrCompareNameDirsFirst(e1p,e2p) DirEntry **e1p,**e2p; { if (DirEntryLeadsToDir(*e1p)) { if (!DirEntryLeadsToDir(*e2p)) return(-1); } else if (DirEntryLeadsToDir(*e2p)) { return(1); } return(strcmp(DirEntryFileName(*e1p),DirEntryFileName(*e2p))); } /* End DirectoryMgrCompareNameDirsFirst */ int DirectoryMgrCompareSizeAscending(e1p,e2p) DirEntry **e1p,**e2p; { if (DirEntryFileSize(*e1p) < DirEntryFileSize(*e2p)) return (-1); else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p)) return (0); else return (1); } /* End DirectoryMgrCompareSizeAscending */ int DirectoryMgrCompareSizeDescending(e1p,e2p) DirEntry **e1p,**e2p; { if (DirEntryFileSize(*e1p) > DirEntryFileSize(*e2p)) return (-1); else if (DirEntryFileSize(*e1p) == DirEntryFileSize(*e2p)) return (0); else return (1); } /* End DirectoryMgrCompareSizeDescending */ int DirectoryMgrCompareLastAccessAscending(e1p,e2p) DirEntry **e1p,**e2p; { return((long)DirEntryLastAccess(*e1p) > (long)DirEntryLastAccess(*e2p)); } /* End DirectoryMgrCompareLastAccessAscending */ int DirectoryMgrCompareLastAccessDescending(e1p,e2p) DirEntry **e1p,**e2p; { return((long)DirEntryLastAccess(*e1p) < (long)DirEntryLastAccess(*e2p)); } /* End DirectoryMgrCompareLastAccessDescending */ /*---------------------------------------------------------------------------* F I L T E R R O U T I N E S *---------------------------------------------------------------------------*/ int DirectoryMgrFilterName(de,fsm) DirEntry *de; regex_t *fsm; { #ifndef NO_REGEXP return(RegExpMatch(DirEntryFileName(de),fsm)); #else return(TRUE); #endif } /* End DirectoryMgrFilterName */ acfax/DirMgr.h100644 765 144 12635 6002243236 12543 0ustar andreasusers/**************************************************************************** DirMgr.h This file contains the C declarations and definitions for the DirectoryMgr system. This system is intended to managed filtered and sorted directory lists. ****************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #ifndef _DIRECTORY_MGR_H_ #define _DIRECTORY_MGR_H_ #include "Directory.h" /*---------------------------------------------------------------------------* Simple DirectoryMgr Interface DirectoryMgrSimpleOpen(); DirectoryMgrSimpleRefilter(); DirectoryMgrSimpleResort(); Standard DirectoryMgr Interface DirectoryMgrCanOpen(); DirectoryMgrOpen(); DirectoryMgrClose(); DirectoryMgrRefilter(); DirectoryMgrRefresh(); DirectoryMgrResort(); Moving Around Items DirectoryMgrGotoItem(); DirectoryMgrGotoNamedItem(); DirectoryMgrRestart(); DirectoryMgrGetIndex(); DirectoryMgrCurrentEntry(); DirectoryMgrNextEntry(); DirectoryMgrPrevEntry(); Utility Functions DirectoryMgrSimpleFilterFunc(); DirectoryMgrSimpleSortingFunc(); Comparison Functions DirectoryMgrCompareName(); DirectoryMgrCompareSizeAscending(); DirectoryMgrCompareSizeDescending(); Macros DirectoryMgrDir(); DirectoryMgrData(); DirectoryMgrSortedPtrs(); DirectoryMgrFilterFunc(); DirectoryMgrCompFunc(); DirectoryMgrFilterData(); DirectoryMgrFreeFilterData(); DirectoryMgrTotalCount(); DirectoryMgrFilteredCount(); DirectoryMgrCurrentIndex(); *---------------------------------------------------------------------------*/ #ifndef PFI typedef int (*PFI)(); #endif typedef struct entry_cons { DIR_ENTRY dir_entry; struct entry_cons *next; } DIR_ENTRY_CONS; typedef DIR_ENTRY_CONS DirEntryCons; typedef struct { DIRECTORY dir; DIR_ENTRY *data; DIR_ENTRY **sorted_ptrs; int total_count; int filtered_count; PFI filter_func; char *filter_data; int free_filter_data; PFI comp_func; int current_index; } DIRECTORY_MGR; typedef DIRECTORY_MGR DirectoryMgr; #define DIR_MGR_SORT_NONE 0 #define DIR_MGR_SORT_NAME 1 #define DIR_MGR_SORT_NAME_DIRS_FIRST 2 #define DIR_MGR_SORT_SIZE_ASCENDING 3 #define DIR_MGR_SORT_SIZE_DESCENDING 4 #define DIR_MGR_SORT_ACCESS_ASCENDING 5 #define DIR_MGR_SORT_ACCESS_DESCENDING 6 #define DirectoryMgrDir(dm) (&((dm)->dir)) #define DirectoryMgrData(dm) ((dm)->data) #define DirectoryMgrSortedPtrs(dm) ((dm)->sorted_ptrs) #define DirectoryMgrFilterFunc(dm) ((dm)->filter_func) #define DirectoryMgrCompFunc(dm) ((dm)->comp_func) #define DirectoryMgrFilterData(dm) ((dm)->filter_data) #define DirectoryMgrFreeFilterData(dm) ((dm)->free_filter_data) #define DirectoryMgrTotalCount(dm) ((dm)->total_count) #define DirectoryMgrFilteredCount(dm) ((dm)->filtered_count) #define DirectoryMgrCurrentIndex(dm) ((dm)->current_index) #if (!NeedFunctionPrototypes) DirectoryMgr * DirectoryMgrSimpleOpen(); int DirectoryMgrSimpleRefilter(); int DirectoryMgrSimpleResort(); int DirectoryMgrCanOpen(); DirectoryMgr * DirectoryMgrOpen(); void DirectoryMgrClose(); int DirectoryMgrRefilter(); int DirectoryMgrRefresh(); void DirectoryMgrResort(); int DirectoryMgrGotoItem(); int DirectoryMgrGotoNamedItem(); void DirectoryMgrRestart(); int DirectoryMgrGetIndex(); DirEntry * DirectoryMgrCurrentEntry(); DirEntry * DirectoryMgrNextEntry(); DirEntry * DirectoryMgrPrevEntry(); int DirectoryMgrSimpleFilterFunc(); int DirectoryMgrSimpleSortingFunc(); int DirectoryMgrCompareName(); int DirectoryMgrCompareNameDirsFirst(); int DirectoryMgrCompareSizeAscending(); int DirectoryMgrCompareSizeDescending(); int DirectoryMgrCompareLastAccessAscending(); int DirectoryMgrCompareLastAccessDescending(); int DirectoryMgrFilterName(); #else DirectoryMgr * DirectoryMgrSimpleOpen(char *path, int sort_type, char *pattern); int DirectoryMgrSimpleRefilter(DirectoryMgr *dm, char *pattern); int DirectoryMgrSimpleResort(DirectoryMgr *dm, int sort_type); int DirectoryMgrCanOpen(char *path); DirectoryMgr * DirectoryMgrOpen(char *path, PFI c_func, PFI f_func, char *f_data, int free_data); void DirectoryMgrClose(DirectoryMgr *dm); int DirectoryMgrRefilter(DirectoryMgr *dm, PFI f_func, char *f_data, int f_free); int DirectoryMgrRefresh(DirectoryMgr *dm); void DirectoryMgrResort(DirectoryMgr *dm, PFI c_func); int DirectoryMgrGotoItem(DirectoryMgr *dm, int i); int DirectoryMgrGotoNamedItem(DirectoryMgr *dm, char *name); void DirectoryMgrRestart(DirectoryMgr *dm); DirEntry * DirectoryMgrCurrentEntry(DirectoryMgr *dm); DirEntry * DirectoryMgrNextEntry(DirectoryMgr *dm); DirEntry * DirectoryMgrPrevEntry(DirectoryMgr *dm); int DirectoryMgrSimpleFilterFunc(char *pattern, PFI *ff_ptr, char **fd_ptr); int DirectoryMgrSimpleSortingFunc(int sort_type, PFI *sf_ptr); int DirectoryMgrCompareName(DirEntry **e1p, DirEntry **e2p); int DirectoryMgrCompareNameDirsFirst(DirEntry **e1p, DirEntry **e2p); int DirectoryMgrCompareSizeAscending(DirEntry **e1p, DirEntry **e2p); int DirectoryMgrCompareSizeDescending(DirEntry **e1p, DirEntry **e2p); int DirectoryMgrCompareLastAccessAscending(DirEntry **e1p, DirEntry **e2p); int DirectoryMgrCompareLastAccessDescending(DirEntry **e1p, DirEntry **e2p); int DirectoryMgrFilterName(DirEntry *de, char *fsm); #endif #endif acfax/Directory.c100644 765 144 12140 5773037127 13323 0ustar andreasusers/**************************************************************************** Directory.c This file contains the C code that implements the directory iteration and file information subsystem. This code is intended to be used as a convenient, machine independent interface to iterate through the contents of a directory. ****************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #include "Directory.h" #include "RegExp.h" /*--------------------------------------------------------------------------* L O W L E V E L D I R E C T O R Y I N T E R F A C E *--------------------------------------------------------------------------*/ int DirectoryOpen(dir_name,dp) char *dir_name; Directory *dp; { if (DirectoryPathExpand(dir_name,DirectoryPath(dp)) == NULL) { return(FALSE); } DirectoryDir(dp) = opendir(DirectoryPath(dp)); if (DirectoryDir(dp) == NULL) return(FALSE); return(TRUE); } /* End DirectoryOpen */ void DirectoryRestart(dp) Directory *dp; { rewinddir(DirectoryDir(dp)); } /* End DirectoryRestart */ void DirectoryClose(dp) Directory *dp; { closedir(DirectoryDir(dp)); } /* End DirectoryClose */ long DirectoryTellPosition(dp) Directory *dp; { return(telldir(DirectoryDir(dp))); } /* End DirectoryTellPosition */ void DirectorySetPosition(dp,pos) Directory *dp; long pos; { seekdir(dp->filep,pos); } /* End DirectorySetPosition */ int DirectoryReadNextEntry(dp,de) Directory *dp; DirEntry *de; { u_short orig_file_type; static struct dirent *_ep; static struct stat _lstats,_stats; char full_path[MAXPATHLEN + 2]; _ep = readdir(DirectoryDir(dp)); if (_ep == NULL) return(FALSE); strcpy(DirEntryFileName(de),_ep->d_name); strcpy(full_path,DirectoryPath(dp)); strcat(full_path,DirEntryFileName(de)); if (lstat(full_path,&_lstats) != 0) return(FALSE); orig_file_type = _lstats.st_mode & S_IFMT; switch (orig_file_type) { case S_IFDIR: DirEntryType(de) = F_TYPE_DIR; break; case S_IFREG: DirEntryType(de) = F_TYPE_FILE; break; case S_IFCHR: DirEntryType(de) = F_TYPE_CHAR_SPECIAL; break; case S_IFBLK: DirEntryType(de) = F_TYPE_BLOCK_SPECIAL; break; case S_IFLNK: DirEntryType(de) = F_TYPE_SYM_LINK; break; case S_IFSOCK: DirEntryType(de) = F_TYPE_SOCKET; break; #ifdef S_IFIFO case S_IFIFO: DirEntryType(de) = F_TYPE_FIFO; break; #endif default: DirEntryType(de) = orig_file_type; break; } DirEntryIsBrokenLink(de) = FALSE; DirEntryIsDirectoryLink(de) = FALSE; if (DirEntryIsSymLink(de)) /* Symbolic Link */ { if (stat(full_path,&_stats) != 0) /* Can't Stat File */ { DirEntryIsBrokenLink(de) = TRUE; _stats = _lstats; } else /* Link Not Broken */ { #ifdef SLOW_DIRLINK_TEST char temp_path[MAXPATHLEN + 2]; if (DirectoryPathExpand(full_path,temp_path) != NULL) { #else if ((_stats.st_mode & S_IFMT) == S_IFDIR) { #endif DirEntryIsDirectoryLink(de) = TRUE; } } } else /* Not Symbolic Link */ { _stats = _lstats; } FileInfoOrigMode(DirEntrySelfInfo(de)) = _lstats.st_mode; FileInfoProt(DirEntrySelfInfo(de)) = _lstats.st_mode & 0777; FileInfoUserID(DirEntrySelfInfo(de)) = _lstats.st_uid; FileInfoGroupID(DirEntrySelfInfo(de)) = _lstats.st_gid; FileInfoFileSize(DirEntrySelfInfo(de)) = _lstats.st_size; FileInfoLastAccess(DirEntrySelfInfo(de)) = _lstats.st_atime; FileInfoLastModify(DirEntrySelfInfo(de)) = _lstats.st_mtime; FileInfoLastStatusChange(DirEntrySelfInfo(de)) = _lstats.st_ctime; FileInfoOrigMode(DirEntryActualInfo(de)) = _stats.st_mode; FileInfoProt(DirEntryActualInfo(de)) = _stats.st_mode & 0777; FileInfoUserID(DirEntryActualInfo(de)) = _stats.st_uid; FileInfoGroupID(DirEntryActualInfo(de)) = _stats.st_gid; FileInfoFileSize(DirEntryActualInfo(de)) = _stats.st_size; FileInfoLastAccess(DirEntryActualInfo(de)) = _stats.st_atime; FileInfoLastModify(DirEntryActualInfo(de)) = _stats.st_mtime; FileInfoLastStatusChange(DirEntryActualInfo(de)) = _stats.st_ctime; return(TRUE); } /* End DirectoryReadNextEntry */ char *DirectoryPathExpand(old_path,new_path) char *old_path,*new_path; { register char *p; char path[MAXPATHLEN + 2]; if (getwd(path) == NULL) return(NULL); if (chdir(old_path) != 0) return(NULL); if (getwd(new_path) == NULL) strcpy(new_path,old_path); if (chdir(path) != 0) return(NULL); for (p = new_path; *p != '\0'; p++); /* append trailing slash if not already in place... */ if ((p != new_path) && *(p - 1) != '/') { *p++ = '/'; *p = '\0'; } return(new_path); } /* End DirectoryPathExpand */ /*---------------------------------------------------------------------------* D I R E C T O R Y E N T R Y R O U T I N E S *---------------------------------------------------------------------------*/ void DirEntryDump(fp,de) FILE *fp; DirEntry *de; { fprintf(fp,"%20s, Size %7d, Prot %3o\n", DirEntryFileName(de),DirEntryFileSize(de),DirEntryProt(de)); } /* End DirEntryDump */ acfax/Directory.h100644 765 144 14122 5773037127 13332 0ustar andreasusers/**************************************************************************** Directory.h This file contains the C definitions and declarations for the Directory.c directory iteration code. This code is intended to be used as a convenient, machine independent interface to iterate through the contents of a directory. ****************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #ifndef _DIRECTORY_H_ #define _DIRECTORY_H_ #include #include #include #include #include #include #if defined(SYSV) || defined(SVR4) #define getwd(path) getcwd(path, MAXPATHLEN) #endif #ifndef NO_DIRENT #include #else #include #define dirent direct #endif #ifndef _SYS_NAME_MAX #ifndef MAXNAMLEN ERROR, ONE OF THESE MUST BE DEFINED #else #define MAX_NAME_LENGTH MAXNAMLEN #endif #else #define MAX_NAME_LENGTH _SYS_NAME_MAX #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define PERM_READ 4 #define PERM_WRITE 2 #define PERM_EXECUTE 1 #define F_TYPE_DIR 1 #define F_TYPE_FILE 2 #define F_TYPE_CHAR_SPECIAL 3 #define F_TYPE_BLOCK_SPECIAL 4 #define F_TYPE_SYM_LINK 5 #define F_TYPE_SOCKET 6 #define F_TYPE_FIFO 7 /*--------------------------------------------------------------------------* D A T A T Y P E A C C E S S M A C R O S *--------------------------------------------------------------------------*/ /* Directory: Directory Iterator */ #define DirectoryDir(dp) ((dp)->filep) #define DirectoryPath(dp) ((dp)->path) /* FileInfo: Information About A File Or Link */ #define FileInfoProt(fi) ((fi)->protections) #define FileInfoOrigMode(fi) ((fi)->orig_mode) #define FileInfoUserID(fi) ((fi)->user_id) #define FileInfoGroupID(fi) ((fi)->group_id) #define FileInfoFileSize(fi) ((fi)->size) #define FileInfoLastAccess(fi) ((fi)->last_access) #define FileInfoLastModify(fi) ((fi)->last_modify) #define FileInfoLastStatusChange(fi) ((fi)->last_status_change) #define FIProt(fi) FileInfoProt(fi) #define FIOrigMode(fi) FileInfoOrigMode(fi) #define FIUserID(fi) FileInfoUserID(fi) #define FIGroupID(fi) FileInfoGroupID(fi) #define FIFileSize(fi) FileInfoFileSize(fi) #define FILastAccess(fi) FileInfoLastAccess(fi) #define FILastModify(fi) FileInfoLastModify(fi) #define FILastStatusChange(fi) FileInfoLastStatusChange(fi) /* FType: File Type Macros */ #define FTypeIsDir(ft) ((ft) == F_TYPE_DIR) #define FTypeIsFile(ft) ((ft) == F_TYPE_FILE) #define FTypeIsCharSpecial(ft) ((ft) == F_TYPE_CHAR_SPECIAL) #define FTypeIsBlockSpecial(ft) ((ft) == F_TYPE_BLOCK_SPECIAL) #define FTypeIsSymLink(ft) ((ft) == F_TYPE_SYM_LINK) #define FTypeIsSocket(ft) ((ft) == F_TYPE_SOCKET) #define FTypeIsFifo(ft) ((ft) == F_TYPE_FIFO) /* DirEntry: Information About A Item In A Directory */ #define DirEntryFileName(fi) ((fi)->filename) #define DirEntryType(fi) ((fi)->file_type) #define DirEntrySelfInfo(fi) (&((fi)->self_info)) #define DirEntryActualInfo(fi) (&((fi)->actual_info)) #define DirEntryIsBrokenLink(fi) ((fi)->broken_link) #define DirEntryIsDirectoryLink(fi) ((fi)->directory_link) #define DirEntryIsDir(fi) (FTypeIsDir(DirEntryType(fi))) #define DirEntryIsFile(fi) (FTypeIsFile(DirEntryType(fi))) #define DirEntryIsCharSpecial(fi) (FTypeIsCharSpecial(DirEntryType(fi))) #define DirEntryIsBlockSpecial(fi) (FTypeIsBlockSpecial(DirEntryType(fi))) #define DirEntryIsSymLink(fi) (FTypeIsSymLink(DirEntryType(fi))) #define DirEntryIsSocket(fi) (FTypeIsSocket(DirEntryType(fi))) #define DirEntryIsFifo(fi) (FTypeIsFifo(DirEntryType(fi))) #define DirEntryLeadsToDir(fi) (DirEntryIsDir(fi) || \ DirEntryIsDirectoryLink(fi)) #define DirEntryProt(d) FIProt(DirEntrySelfInfo(d)) #define DirEntryOrigMode(d) FIOrigMode(DirEntrySelfInfo(d)) #define DirEntryUserID(d) FIUserID(DirEntrySelfInfo(d)) #define DirEntryGroupID(d) FIGroupID(DirEntrySelfInfo(d)) #define DirEntryFileSize(d) FIFileSize(DirEntrySelfInfo(d)) #define DirEntryLastAccess(d) FILastAccess(DirEntrySelfInfo(d)) #define DirEntryLastModify(d) FILastModify(DirEntrySelfInfo(d)) #define DirEntryLastStatusChange(d) FILastStatusChange(DirEntrySelfInfo(d)) /*--------------------------------------------------------------------------* D A T A T Y P E D E F I N I T I O N S *--------------------------------------------------------------------------*/ /* Directory: Directory Iterator */ typedef struct { DIR *filep; char path[MAXPATHLEN + 2]; } DIRECTORY; typedef DIRECTORY Directory; /* FileInfo: Information About A File Or Link */ typedef struct { short protections; short orig_mode; short user_id; short group_id; long size; time_t last_access; time_t last_modify; time_t last_status_change; } FILE_INFO; typedef FILE_INFO FileInfo; /* DirEntry: Information About A Item In A Directory */ typedef struct { char filename[MAX_NAME_LENGTH + 1]; short file_type; short broken_link; short directory_link; FileInfo self_info; FileInfo actual_info; } DIR_ENTRY; typedef DIR_ENTRY DirEntry; /*--------------------------------------------------------------------------* L O W L E V E L D I R E C T O R Y I N T E R F A C E *--------------------------------------------------------------------------*/ #if (!NeedFunctionPrototypes) int DirectoryOpen(); void DirectoryRestart(); void DirectoryClose(); long DirectoryTellPosition(); void DirectorySetPosition(); int DirectoryReadNextEntry(); char * DirectoryPathExpand(); void DirEntryDump(); #else int DirectoryOpen(char *dir_name, Directory *dp); void DirectoryRestart(Directory *dp); void DirectoryClose(Directory *dp); long DirectoryTellPosition(Directory *dp); void DirectorySetPosition(Directory *dp, long int pos); int DirectoryReadNextEntry(Directory *dp, DirEntry *de); char * DirectoryPathExpand(char *old_path, char *new_path); void DirEntryDump(FILE *fp, DirEntry *de); #endif #endif acfax/RegExp.c100644 765 144 3536 5777546201 12544 0ustar andreasusers/**************************************************************************** RegExp.c This file contains the C code for the regular expression matching code. The routines supported act as a more friendly, user level interface to the regexp regular expression matching system. ****************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #include "RegExp.h" #include void RegExpCompile(regexp,fsm_ptr) char *regexp; regex_t *fsm_ptr; { regcomp(fsm_ptr, regexp, REG_NOSUB|REG_EXTENDED); /* compile(regexp,fsm_ptr,&(fsm_ptr[fsm_length]),'\0'); */ } /* End RegExpCompile */ int RegExpMatch(string,fsm_ptr) char *string; regex_t *fsm_ptr; { if (regexec(fsm_ptr, string, 0, NULL, 0) == 0) return(TRUE); return(FALSE); /* if (advance(string,fsm_ptr) != 0) return(TRUE); else return(FALSE); */ } /* End RegExpMatch */ void _RegExpError(val) int val; { fprintf(stderr,"Regular Expression Error %d\n",val); exit(-1); } /* End _RegExpError */ void RegExpPatternToRegExp(pattern,reg_exp) char *pattern,*reg_exp; { int in_bracket; in_bracket = 0; while (*pattern != '\0') { if (in_bracket) { if (*pattern == ']') in_bracket = 0; *reg_exp++ = *pattern++; } else { switch (*pattern) { case '[': in_bracket = 1; *reg_exp++ = '['; break; case '?': *reg_exp++ = '.'; break; case '*': *reg_exp++ = '.'; *reg_exp++ = '*'; break; case '.': *reg_exp++ = '\\'; *reg_exp++ = '.'; break; default: *reg_exp++ = *pattern; break; } ++ pattern; } } *reg_exp++ = '$'; *reg_exp++ = '\0'; } /* End RegExpPatternToRegExp */ acfax/RegExp.h100644 765 144 2361 5777546205 12550 0ustar andreasusers/**************************************************************************** RegExp.h This file contains the C definitions and declarations for the regular expression matching code. The routines supported act as a more friendly, user level interface to the regexp regular expression matching system. ****************************************************************************/ /* * Author: * Brian Totty * Department of Computer Science * University Of Illinois at Urbana-Champaign * 1304 West Springfield Avenue * Urbana, IL 61801 * * totty@cs.uiuc.edu * */ #ifndef _REGEXP_H_ #define _REGEXP_H_ #include #include #if (!NeedFunctionPrototypes) void RegExpCompile(); int RegExpMatch(); void _RegExpError(); void RegExpPatternToRegExp(); #else void RegExpCompile(char *regexp, regex_t *fsm_ptr); int RegExpMatch(char *string, regex_t *fsm_ptr); void _RegExpError(int val); void RegExpPatternToRegExp(char *pattern, char *reg_exp); #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define INIT register char *sp = instring; #define GETC() (*sp++) #define PEEKC() (*sp) #define UNGETC(c) -- sp #define RETURN(ptr) return; #define ERROR(val) _RegExpError(val) #endif acfax/ACfax100644 765 144 2666 6550720341 12103 0ustar andreasusers! ! --- Applicaion defaults file for acfax. ---- ! ! You may want to install it under /usr/lib/X11/app-defaults/ ! or append it to your $HOME/.Xdefaults . ! This is the German version; the english labeling is compiled in, ! so that it works without any application defaults file. ACfax.title: ACfax Bildanzeige ACfax.fax_shell.title: ACfax Steuerung ACfax.fax_shell*menuform.filebut.label: Datei... ACfax.fax_shell*menuform*file_mw.label: Dateioperationen ACfax.fax_shell*menuform*autosave.label: Speichern (autom. Dateiname) ACfax.fax_shell*menuform*saveas.label: Speichern als... ACfax.fax_shell*menuform*close.label: Speicherdatei schließen ACfax.fax_shell*menuform*quit.label: ACfax beenden ACfax.fax_shell*modemform*modemdesc.label: Modem-Einstellungen ACfax.fax_shell*modemform*modinfo.label: Modula-\ntionsart ACfax.fax_shell*modemform*filinfo.label: Filter-\nauswahl ACfax.fax_shell*modemform*mfilter*mflt1.label: schmal ACfax.fax_shell*modemform*mfilter*mflt2.label: mittel ACfax.fax_shell*modemform*mfilter*mflt3.label: breit ACfax.fax_shell*modemform*fmdevinfo.label: Frequenzhub (+/- Hz) ACfax.fax_shell*faxctrls*runinfo.label: Programm-\nsteuerung ACfax.fax_shell*faxctrls*dirinfo.label: Schreib-\nrichtung ACfax.fax_shell*faxctrls*polinfo.label: Bild-\npolarität ACfax.fax_shell*faxctrls*phsinfo.label: Sync-\npolarität ACfax.fax_shell*faxctrls*adjinfo.label: Bild-\nkorrektur ACfax.fax_shell*faxparams*numinfo.label: numerische FAX-parameter acfax/bitmaps/ 40755 765 144 0 5777552576 12555 5ustar andreasusersacfax/bitmaps/ammod.bit100644 765 144 1030 5761642401 14415 0ustar andreasusers#define ammod_width 24 #define ammod_height 24 static unsigned char ammod_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x70, 0xf8, 0x78, 0x78, 0x8c, 0x79, 0x78, 0x06, 0xdb, 0x6c, 0x06, 0xdb, 0x6f, 0x06, 0x9b, 0x67, 0x06, 0x9b, 0x67, 0x06, 0x1b, 0x63, 0xfe, 0x1b, 0x63, 0xfe, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x06, 0x1b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/azimut.bit100644 765 144 1033 5761346457 14650 0ustar andreasusers#define azimut_width 24 #define azimut_height 24 static unsigned char azimut_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x49, 0x00, 0x00, 0x49, 0x00, 0x00, 0x49, 0x00, 0x00, 0x49, 0x00, 0x8f, 0x88, 0x78, 0x83, 0x88, 0x60, 0x87, 0x88, 0x70, 0x59, 0x08, 0x4d, 0xe0, 0xff, 0x03, 0x40, 0x08, 0x01, 0x40, 0x08, 0x01, 0x20, 0x08, 0x02, 0x20, 0x08, 0x02, 0x00, 0x00, 0x00}; acfax/bitmaps/bottom.bit100644 765 144 1033 5751640164 14632 0ustar andreasusers#define bottom_width 24 #define bottom_height 24 static unsigned char bottom_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0xc0, 0x18, 0x03, 0x80, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/fmmod.bit100644 765 144 1030 5761642267 14434 0ustar andreasusers#define fmmod_width 24 #define fmmod_height 24 static unsigned char fmmod_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3b, 0x70, 0xfe, 0x7b, 0x78, 0x06, 0x78, 0x78, 0x06, 0xd8, 0x6c, 0x06, 0xd8, 0x6f, 0x06, 0x98, 0x67, 0x06, 0x98, 0x67, 0x06, 0x18, 0x63, 0xfe, 0x18, 0x63, 0xfe, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/go.bit100644 765 144 1017 5761120064 13726 0ustar andreasusers#define go_width 24 #define go_height 24 static unsigned char go_bits[] = { 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07, 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0x3e, 0x7c, 0x7c, 0x1e, 0x38, 0x79, 0x8e, 0x99, 0x73, 0xcf, 0x9b, 0xf3, 0xcf, 0x9f, 0xf3, 0xcf, 0x9f, 0xf3, 0x4f, 0x98, 0xf3, 0xcf, 0x99, 0xf3, 0xcf, 0x99, 0xf3, 0x8e, 0x99, 0x73, 0x1e, 0x38, 0x79, 0x3e, 0x78, 0x7c, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f, 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00}; acfax/bitmaps/horiz.bit100644 765 144 1030 5751637750 14465 0ustar andreasusers#define horiz_width 24 #define horiz_height 24 static unsigned char horiz_bits[] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xdf, 0x36, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0xff, 0x03, 0xc0, 0xff, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0xc0, 0x00, 0x03, 0x00, 0x00, 0x00}; acfax/bitmaps/invers.bit100644 765 144 1033 5762164047 14637 0ustar andreasusers#define invers_width 24 #define invers_height 24 static unsigned char invers_bits[] = { 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x14, 0x00, 0x00, 0x34, 0x00, 0x00, 0x64, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x84, 0xc1, 0x3f, 0x04, 0xc3, 0x3f, 0x04, 0x06, 0x00, 0x04, 0x0c, 0x00, 0x04, 0x18, 0x00, 0x04, 0x30, 0x00, 0x04, 0x60, 0x00, 0x04, 0xc0, 0x00, 0x04, 0x80, 0x01, 0x04, 0x00, 0x03, 0x04, 0x00, 0x16, 0x04, 0x00, 0x30, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10}; acfax/bitmaps/iphs.bit100644 765 144 1025 5762164472 14277 0ustar andreasusers#define iphs_width 24 #define iphs_height 24 static unsigned char iphs_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0xfe, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0xfc, 0x23, 0x02, 0xfc, 0x23, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/left.bit100644 765 144 1025 5751640130 14252 0ustar andreasusers#define left_width 24 #define left_height 24 static unsigned char left_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/normal.bit100644 765 144 1033 5762163754 14625 0ustar andreasusers#define normal_width 24 #define normal_height 24 static unsigned char normal_bits[] = { 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1f, 0x00, 0x18, 0x04, 0x00, 0x0c, 0x04, 0x00, 0x06, 0x04, 0x00, 0x03, 0x04, 0x80, 0x01, 0x04, 0xc0, 0x00, 0x04, 0x60, 0x00, 0x04, 0x30, 0x06, 0x04, 0x18, 0x06, 0x04, 0x0c, 0x06, 0x04, 0xc6, 0x3f, 0x04, 0xc3, 0x3f, 0x84, 0x01, 0x06, 0xc4, 0x00, 0x06, 0x64, 0x00, 0x06, 0x34, 0x00, 0x00, 0x1c, 0x00, 0x10, 0x0c, 0x00, 0x30, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10}; acfax/bitmaps/nphs.bit100644 765 144 1025 5762164362 14302 0ustar andreasusers#define nphs_width 24 #define nphs_height 24 static unsigned char nphs_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x60, 0x20, 0x02, 0x60, 0x20, 0x02, 0x60, 0x20, 0x02, 0xfc, 0x23, 0x02, 0xfc, 0x23, 0x02, 0x60, 0x20, 0x02, 0x60, 0x20, 0x02, 0x60, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0xff, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/right.bit100644 765 144 1030 5751640105 14433 0ustar andreasusers#define right_width 24 #define right_height 24 static unsigned char right_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x30, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/run.bit100644 765 144 1022 5761646013 14130 0ustar andreasusers#define run_width 24 #define run_height 24 static unsigned char run_bits[] = { 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07, 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xc2, 0x99, 0x4c, 0x82, 0x99, 0x4c, 0x33, 0x99, 0xc8, 0x33, 0x99, 0xc8, 0x83, 0x99, 0xc8, 0xc3, 0x99, 0xc4, 0x93, 0x99, 0xc4, 0x93, 0x99, 0xc4, 0x32, 0x81, 0x4c, 0x32, 0xc3, 0x4c, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f, 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00}; acfax/bitmaps/shift.bit100644 765 144 1030 5761347034 14441 0ustar andreasusers#define shift_width 24 #define shift_height 24 static unsigned char shift_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x30, 0x18, 0x0c, 0x18, 0x18, 0x18, 0xfc, 0xff, 0x3f, 0x18, 0x18, 0x18, 0x30, 0x18, 0x0c, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/stop.bit100644 765 144 1025 5761117340 14310 0ustar andreasusers#define stop_width 24 #define stop_height 24 static unsigned char stop_bits[] = { 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07, 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0x03, 0x88, 0xc1, 0x01, 0x00, 0x81, 0x79, 0x26, 0x99, 0x79, 0x72, 0x98, 0x79, 0x72, 0x98, 0x61, 0x72, 0x80, 0x43, 0x72, 0xc0, 0x4f, 0x72, 0xf8, 0x4f, 0x72, 0xf8, 0x4f, 0x26, 0xf9, 0x41, 0x06, 0xf9, 0x61, 0x8e, 0xf9, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f, 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03}; acfax/bitmaps/syn.bit100644 765 144 1022 5761650220 14130 0ustar andreasusers#define syn_width 24 #define syn_height 24 static unsigned char syn_bits[] = { 0x40, 0x00, 0x02, 0xc0, 0x00, 0x03, 0xc0, 0x81, 0x03, 0xfe, 0xc3, 0x7f, 0xfe, 0xe7, 0x7f, 0xfe, 0xc3, 0x7f, 0xc0, 0x81, 0x03, 0xc0, 0x00, 0x03, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe1, 0x31, 0xfc, 0xe1, 0x33, 0x8c, 0xf3, 0x33, 0x0c, 0xb3, 0x33, 0x0c, 0xb3, 0x37, 0x3c, 0x9e, 0x37, 0x78, 0x9e, 0x3d, 0x60, 0x8c, 0x3d, 0x60, 0x8c, 0x39, 0x60, 0x8c, 0x39, 0x7c, 0x8c, 0x39, 0x3c, 0x8c, 0x31, 0x00, 0x00, 0x00}; acfax/bitmaps/top.bit100644 765 144 1022 5751640147 14127 0ustar andreasusers#define top_width 24 #define top_height 24 static unsigned char top_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xdb, 0x00, 0x80, 0x99, 0x01, 0xc0, 0x18, 0x03, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/vert.bit100644 765 144 1025 5751637500 14307 0ustar andreasusers#define vert_width 24 #define vert_height 24 static unsigned char vert_bits[] = { 0x24, 0x01, 0x00, 0x24, 0x01, 0x00, 0x24, 0x01, 0x00, 0x24, 0x01, 0x00, 0x24, 0x01, 0x00, 0x24, 0x19, 0x30, 0x24, 0x19, 0x30, 0x24, 0x19, 0x30, 0x24, 0x19, 0x30, 0x24, 0x31, 0x18, 0x24, 0x31, 0x18, 0x24, 0x31, 0x18, 0x24, 0x61, 0x0c, 0x24, 0x60, 0x0c, 0x24, 0x61, 0x0c, 0x24, 0xc1, 0x06, 0x24, 0xc0, 0x06, 0x24, 0xc1, 0x06, 0x24, 0x81, 0x03, 0x24, 0x80, 0x03, 0x24, 0x01, 0x00, 0x24, 0x01, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00}; acfax/bitmaps/middle.bit100644 765 144 1033 5773042607 14566 0ustar andreasusers#define middle_width 24 #define middle_height 24 static unsigned char middle_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x80, 0x81, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0xc0, 0x00, 0x03, 0x40, 0x00, 0x02, 0x60, 0x00, 0x06, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/narrow.bit100644 765 144 1033 5773042334 14635 0ustar andreasusers#define narrow_width 24 #define narrow_height 24 static unsigned char narrow_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x63, 0x00, 0x00, 0x41, 0x00, 0x80, 0xc1, 0x00, 0xff, 0x80, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/bitmaps/wide.bit100644 765 144 1025 5773043023 14252 0ustar andreasusers#define wide_width 24 #define wide_height 24 static unsigned char wide_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x03, 0x60, 0x00, 0x06, 0x30, 0x00, 0x0c, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x18, 0x00, 0x18, 0x08, 0x00, 0x10, 0x0c, 0x00, 0x30, 0x07, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; acfax/COPYING100644 765 144 43114 6550715246 12252 0ustar andreasusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. acfax/0README100644 765 144 5155 6616311577 12144 0ustar andreasusers ACfax - amateur FAX receiving software for Linux / X11 Andreas Czechanowski, DL4SDC andreas.czechanowski@ins.uni-stuttgart.de !!! THIS PROGRAM IS PROVIDED "AS IS" WITHOUT ANY WARRANTY !!! USE AT YOUR OWN RISK ! IT IS STILL UNDER DEVELOPMENT ! Five steps to success....: * Edit the Imakefile, and look for the DEFINES after the description. You normally should not have to edit much here. If you do not have libXaw3d, remove -DUSE_XAW3D from the DEFINES and change -lXaw3d to -lXaw in the LOCAL_LIBRARIES line. If you have only a normal SoundBlaster/Pro (without software controllable mixer), remove -DSBL_16 also from the DEFINES line. * type "xmkmf" * type "make" (if this fails, and you don't get it fixed, you may mail me the output of the make command - but don't expect a 24-minute instant hotline service !) * Be sure to have /dev/dsp (and /dev/mixer for SoundBlaster 16) readable and writable for the user that wants to execute acfax ! * now, type "./acfax" and don't be surprised about weird messages appearing on your terminal screen from which acfax was started - it may be only useful for me while debugging. Just ignore it. NOTES / BUGS / BEFORE YOU ASK: - The "Signal" scrollbar in the Modem-part of the ACFax-control-window indicates the audio signal level. With the SoundBlaster 16, the LINE IN is selected as audio input. For the "FM" Modem type, levels of 25% can even be okay, optimum would be 50% to 80%, and if it is at maximum then the signal is probably too loud ! When using the AM modem, the audio level is directly proportional to the image contrast. You probably have to experimentally find out how to set the audio volume. You may change the input sensitivity (SoundBlaster 16 only) by setting "linevol = nn;" on line 64 of the file sblaster.c , whereas nn=99 is the maximum. - When receiving on longwave/shortwave, set the Modem to "FM" mode, the receiver/transceiver to USB or LSB, and the AGC to fast (this compensates best for signal fading). If you want to receive Meteosat, you have to use an FM receiver with not too narrow IF filters and the "AM" Modem type. If this seems confusing or unlogical to you, be aware that AM/FM means the operation of the Modem, so either varying tone-pitch or varying loudness determines the luminosity of the beam writing the image lines. - You may switch reception manually on and off using the "STOP" and "RUN" buttons in the operation control. If you want the image to be written from the beginning, switch to "SYN" once, and then back to "RUN". This will reset the internal writing pointer to the beginning. acfax/0TODO100644 765 144 2003 6616312004 11723 0ustar andreasusers ACfax - amateur FAX receiving software for Linux / X11 Andreas Czechanowski, DL4SDC andreas.czechanowski@ins.uni-stuttgart.de To be done: Documentation! Actually, there exists nothing but the source code, or just ask me if it is not clear how to operate. This should be done first, also for some interna (how does it work, anyway ?) Clean up the code in some places Transmission of FAX - you will see some preparations in the source code, and I'll eventually do it. Color modes for Fax, surely not so easy to implement Adjustable image size (by now, the size of the received image is fixed, and it is placed within a frame with scrollbars) SSTV would be very nice to have in the same program, if possible, especially the color modes (Martin1 very popular here in europe) A frequency tuning indicator, e.g. with Xaw-scrollbars like the signal level indicator. Loading/saving of images in different data formats, such as JPEG and PNG (not urgent) ...surely much more... acfax/0FEATURES100644 765 14 2025 6551134425 12144 0ustar andreasmail ACfax - amateur FAX receiving software for Linux / X11 Andreas Czechanowski, DL4SDC andreas.czechanowski@ins.uni-stuttgart.de Features (or whatever you call it): AM or FM demodulation possible, adjustable filter width (3 levels), FM deviation adjustable for contrast adjustment. Uses the system processor for signal processing (filtering, demodulation). Grayscale reception with 64 gray levels Most parameters (except the modem settings) can subsequentially be adjusted (while or after the image is recieved), because the demodulated raw data stream is kept in memory. Image Polarity switch (pos/neg), Phasing polarity switch (pos/neg) APT tone detection for automatic start/stop (both frequencies adjustable), automatic phase-in (starts a new image) Variable IOC for height/width adjustment, variable LPM Writing direction horizontal/vertical up/down left/right switchable subsequent image centering and LPM fine correction possible automatic saving of received images as simple pgm-file acfax/0Where_to_get100644 765 144 174 6614142272 13566 0ustar andreasusersftp://ftp.funet.fi/pub/ham/unix/Linux/misc/acfax-980709.tar.gz ftp://ftp.aba.net.au/pub/Linux/apps/ham/acfax-980709.tar.gz acfax/ChangeLog100644 765 144 514 6616307350 12722 0ustar andreasusersacfax-981011: - First steps to use TrueColor-Displays with 16/24/32bpp, not only PseudoColor with 8bpp. - Scrollbar as signal level indicator instead of the "level preview" on stdout on program startup. - hopefully fixed problems with receiver-stop when switching AM/FM. acfax-980709: - first public release (GPL).