diff --git a/bitmap/AUTHORS b/bitmap/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/bitmap/BitEdit.c b/bitmap/BitEdit.c new file mode 100644 index 0000000..ee850d8 --- /dev/null +++ b/bitmap/BitEdit.c @@ -0,0 +1,1128 @@ +/* $Xorg: BitEdit.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/BitEdit.c,v 1.6tsi Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Bitmap.h" + +#include + +static char *usage = "[-options ...] filename\n\ +\n\ +where options include all standard toolkit options plus:\n\ + -size WIDTHxHEIGHT\n\ + -sw dimension\n\ + -sh dimension\n\ + -gt dimension\n\ + -grid, +grid\n\ + -axes, +axes\n\ + -dashed, +dashed\n\ + -stippled, +stippled\n\ + -proportional, +proportional\n\ + -basename basename\n\ + -dashes filename\n\ + -stipple filename\n\ + -hl color\n\ + -fr color\n\ +\n\ +The default WIDTHxHEIGHT is 16x16.\n"; + +static XrmOptionDescRec options[] = { + { "-axes", "*bitmap.axes", XrmoptionNoArg, "True"}, + { "+axes", "*bitmap.axes", XrmoptionNoArg, "False"}, + { "-basename", "*bitmap.basename", XrmoptionSepArg, NULL}, + { "-dashed", "*bitmap.dashed", XrmoptionNoArg, "True"}, + { "+dashed", "*bitmap.dashed", XrmoptionNoArg, "False"}, + { "-dashes", "*bitmap.dashes", XrmoptionSepArg, NULL}, + { "-fr", "*bitmap.frame", XrmoptionSepArg, NULL}, + { "-gt", "*bitmap.gridTolerance",XrmoptionSepArg, NULL}, + { "-grid", "*bitmap.grid", XrmoptionNoArg, "True"}, + { "+grid", "*bitmap.grid", XrmoptionNoArg, "False"}, + { "-hl", "*bitmap.highlight", XrmoptionSepArg, NULL}, + { "-proportional","*bitmap.proportional", XrmoptionNoArg, "True"}, + { "+proportional","*bitmap.proportional", XrmoptionNoArg, "False"}, + { "-size", "*bitmap.size", XrmoptionSepArg, NULL}, + { "-sh", "*bitmap.squareHeight", XrmoptionSepArg, NULL}, + { "-sw", "*bitmap.squareWidth", XrmoptionSepArg, NULL}, + { "-stipple", "*bitmap.stipple", XrmoptionSepArg, NULL}, + { "-stippled", "*bitmap.stippled", XrmoptionNoArg, "True"}, + { "+stippled", "*bitmap.stippled", XrmoptionNoArg, "False"}, +}; + +typedef struct { + int id; + String name; + Boolean trap; + Widget widget; + } ButtonRec; + +static ButtonRec file_menu[] = { +#define New 101 + {New, "new", True}, +#define Load 102 + {Load, "load", True}, +#define Insert 103 + {Insert, "insert", True}, +#define Save 104 + {Save, "save", True}, +#define SaveAs 105 + {SaveAs, "saveAs", True}, +#define Resize 106 + {Resize, "resize", True}, +#define Rescale 107 + {Rescale, "rescale", True}, +#define Filename 108 + {Filename, "filename", True}, +#define Basename 109 + {Basename, "basename", True}, +#define Dummy -1 + {Dummy, "line", False}, +#define Quit 110 + {Quit, "quit", True}, +}; + +static ButtonRec edit_menu[] = { +#define Image 201 + {Image, "image", True}, +#define Grid 203 + {Grid, "grid", True}, +#define Dashed 204 + {Dashed, "dashed", True}, +#define Axes 205 + {Axes, "axes", True}, +#define Stippled 206 + {Stippled, "stippled", True}, +#define Proportional 207 + {Proportional, "proportional", True}, +#define Zoom 208 + {Zoom, "zoom", True}, +/* Dummy */ + {Dummy, "line", False}, +#define Cut 209 + {Cut, "cut", True}, +#define Copy 210 + {Copy, "copy", True}, +#define Paste 211 + {Paste, "paste", True}, +}; + +static ButtonRec buttons[] = { +/*#define Clear 1*/ + {Clear, "clear", False}, +/*#define Set 2*/ + {Set, "set", False}, +/*#define Invert 3*/ + {Invert, "invert", False}, +#define Mark 26 + {Mark, "mark", True}, +#define Unmark 27 + {Unmark, "unmark", False}, +#define CopyImm 4 + {CopyImm, "copy", True}, +#define MoveImm 5 + {MoveImm, "move", True}, +#define FlipHoriz 6 + {FlipHoriz, "flipHoriz", False}, +#define Up 7 + {Up, "up", False}, +#define FlipVert 8 + {FlipVert, "flipVert", False}, +#define Left 9 + {Left, "left", False}, +#define Fold 10 + {Fold, "fold", False}, +#define Right 11 + {Right, "right", False}, +#define RotateLeft 12 + {RotateLeft, "rotateLeft", False}, +#define Down 13 + {Down, "down", False}, +#define RotateRight 14 + {RotateRight, "rotateRight", False}, +#define Point 15 + {Point, "point", True}, +#define Curve 16 + {Curve, "curve", True}, +#define Line 17 + {Line, "line", True}, +#define Rectangle 18 + {Rectangle, "rectangle", True}, +#define FilledRectangle 19 + {FilledRectangle, "filledRectangle", True}, +#define Circle 20 + {Circle, "circle", True}, +#define FilledCircle 21 + {FilledCircle, "filledCircle", True}, +#define FloodFill 22 + {FloodFill, "floodFill", True}, +#define SetHotSpot 23 + {SetHotSpot, "setHotSpot", True}, +#define ClearHotSpot 24 + {ClearHotSpot, "clearHotSpot", False}, +#define Undo 25 + {Undo, "undo", False}, +}; + +#include "Dialog.h" + +static Widget + top_widget, + parent_widget, + formy_widget, + fileMenu_widget, + editMenu_widget, + status_widget, + pane_widget, + form_widget, + bitmap_widget, + image_shell, + box_widget, + normal_image_widget, + inverted_image_widget; +static Boolean image_visible = False; +static Pixmap check_mark; +static Dialog input_dialog, error_dialog, qsave_dialog; +static Time btime; +static String filename = NULL, base_name = NULL, format; +static char message[80]; + + +void FixMenu ( Widget w, XEvent *event, String *params, Cardinal *num_params ); +void SwitchImage ( void ); +void SwitchGrid( void ); +void SwitchDashed( void ); +void SwitchAxes( void ); +void SwitchStippled( void ); +void SwitchProportional( void ); +void SwitchZoom( void ); +void DoCut( void ); +void DoCopy( void ); +void DoPaste( void ); +void DoNew( void ); +void DoLoad( void ); +void DoInsert( void ); +void DoSave( void ); +void DoSaveAs( void ); +void DoResize( void ); +void DoRescale( void ); +void DoFilename( void ); +void DoBasename( void ); +void DoQuit ( Widget w, XEvent *event, String *params, Cardinal *num_params ); + +static XtActionsRec actions_table[] = { + {"fix-menu", FixMenu}, + {"switch-image", (XtActionProc)SwitchImage}, + {"switch-grid", (XtActionProc)SwitchGrid}, + {"switch-dashed", (XtActionProc)SwitchDashed}, + {"switch-axes", (XtActionProc)SwitchAxes}, + {"switch-stippled", (XtActionProc)SwitchStippled}, + {"switch-proportional", (XtActionProc)SwitchProportional}, + {"switch-zoom", (XtActionProc)SwitchZoom}, + {"do-cut", (XtActionProc)DoCut}, + {"do-copy", (XtActionProc)DoCopy}, + {"do-paste", (XtActionProc)DoPaste}, + {"do-new", (XtActionProc)DoNew}, + {"do-load", (XtActionProc)DoLoad}, + {"do-insert", (XtActionProc)DoInsert}, + {"do-save", (XtActionProc)DoSave}, + {"do-save-as", (XtActionProc)DoSaveAs}, + {"do-resize", (XtActionProc)DoResize}, + {"do-rescale", (XtActionProc)DoRescale}, + {"do-filename", (XtActionProc)DoFilename}, + {"do-basename", (XtActionProc)DoBasename}, + {"do-quit", DoQuit} +}; + +static Atom wm_delete_window; + +static void +FixImage(void) +{ + Pixmap old_image, image; + int n; + Arg wargs[2]; + + if (!image_visible) return; + + n=0; + XtSetArg(wargs[n], XtNbitmap, &old_image); n++; + XtGetValues(normal_image_widget, wargs, n); + + + image = BWGetUnzoomedPixmap(bitmap_widget); + + n=0; + XtSetArg(wargs[n], XtNbitmap, image); n++; + XtSetValues(normal_image_widget, wargs, n); + XtSetValues(inverted_image_widget, wargs, n); + + if (old_image != XtUnspecifiedPixmap) + XFreePixmap(XtDisplay(bitmap_widget), old_image); +} + +static void +FixStatus(void) +{ + int n; + Arg wargs[2]; + String str, label; + + str = BWUnparseStatus(bitmap_widget); + + n=0; + XtSetArg(wargs[n], XtNlabel, &label); n++; + XtGetValues(status_widget, wargs, n); + + if (strcmp(str, label)) { + n = 0; + XtSetArg(wargs[n], XtNlabel, str); n++; + XtSetValues(status_widget, wargs, n); + } + + /*XtFree(str); */ +} + +static void +FixUp(void) +{ + FixImage(); + FixStatus(); +} + +static void +FixEntry(Widget w, int *id) +{ + int n; + Arg wargs[2]; + Time dummy = 0; + + n = 0; + + switch (*id) { + + case Image: + XtSetArg(wargs[n], XtNleftBitmap, + image_visible ? check_mark : None); n++; + break; + + case Grid: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryGrid(bitmap_widget) ? check_mark : None); n++; + break; + + case Dashed: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryDashed(bitmap_widget) ? check_mark : None); n++; + break; + + case Axes: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryAxes(bitmap_widget) ? check_mark : None); n++; + break; + + case Stippled: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryStippled(bitmap_widget) ? check_mark : None); n++; + break; + + case Proportional: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryProportional(bitmap_widget) ? check_mark : None); n++; + break; + + case Zoom: + XtSetArg(wargs[n], XtNleftBitmap, + BWQueryZooming(bitmap_widget) ? check_mark : None); n++; + break; + + case Copy: + case Cut: + XtSetArg(wargs[n], XtNsensitive, BWQueryMarked(bitmap_widget)); n++; + break; + + case Paste: + XtSetArg(wargs[n], XtNsensitive, + BWQuerySelection(bitmap_widget, dummy)); n++; + break; + + default: + return; + } + + XtSetValues(w, wargs, n); +} + +/* ARGSUSED */ +void FixMenu(Widget w, + XEvent *event, + String *params, + Cardinal *num_params) +{ + int i; + + btime = event->xbutton.time; + + for (i = 0; i < XtNumber(edit_menu); i++) + FixEntry(edit_menu[i].widget, &edit_menu[i].id); +} + +static int zero = 0; +#define Plain (char *)&zero,sizeof(int) +/* ARGSUSED */ +static void +TheCallback(Widget w, /* not used */ + XtPointer clientData, + XtPointer callData) +{ + int *id = (int *)clientData; + switch (*id) { + + case New: + DoNew(); + break; + + case Load: + DoLoad(); + break; + + case Insert: + DoInsert(); + break; + + case Save: + DoSave(); + break; + + case SaveAs: + DoSaveAs(); + break; + + case Resize: + DoResize(); + break; + + case Rescale: + DoRescale(); + break; + + case Filename: + DoFilename(); + break; + + case Basename: + DoBasename(); + break; + + case Image: + SwitchImage(); + break; + + case Grid: + SwitchGrid(); + break; + + case Dashed: + SwitchDashed(); + break; + + case Axes: + SwitchAxes(); + break; + + case Stippled: + SwitchStippled(); + break; + + case Proportional: + SwitchProportional(); + break; + + case Zoom: + SwitchZoom(); + break; + + case Cut: + DoCut(); + break; + + case Copy: + DoCopy(); + break; + + case Paste: + DoPaste(); + break; + + case Clear: + BWStoreToBuffer(bitmap_widget); + BWClear(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Set: + BWStoreToBuffer(bitmap_widget); + BWSet(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); +break; + + case Invert: + BWStoreToBuffer(bitmap_widget); + BWInvert(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Mark: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, MarkRequest, True, Plain); + break; + + case Unmark: + BWUnmark(bitmap_widget); + break; + + case CopyImm: + BWRemoveAllRequests(bitmap_widget); + if (BWQueryMarked(bitmap_widget)) { + BWAddRequest(bitmap_widget, MarkRequest, False, Plain); + BWEngageRequest(bitmap_widget, CopyRequest, True, Plain); + } + else { + BWEngageRequest(bitmap_widget, MarkRequest, False, Plain); + BWAddRequest(bitmap_widget, CopyRequest, True, Plain); + } + break; + + case MoveImm: + BWRemoveAllRequests(bitmap_widget); + if (BWQueryMarked(bitmap_widget)) { + BWAddRequest(bitmap_widget, MarkRequest, False, Plain); + BWEngageRequest(bitmap_widget, MoveRequest, True, Plain); + } + else { + BWEngageRequest(bitmap_widget, MarkRequest, False, Plain); + BWAddRequest(bitmap_widget, MoveRequest, True, Plain); + } + break; + + case Up: + BWStoreToBuffer(bitmap_widget); + BWUp(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Down: + BWStoreToBuffer(bitmap_widget); + BWDown(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Left: + BWStoreToBuffer(bitmap_widget); + BWLeft(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Right: + BWStoreToBuffer(bitmap_widget); + BWRight(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Fold: + BWStoreToBuffer(bitmap_widget); + BWFold(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case FlipHoriz: + BWStoreToBuffer(bitmap_widget); + BWFlipHoriz(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case FlipVert: + BWStoreToBuffer(bitmap_widget); + BWFlipVert(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case RotateRight: + BWStoreToBuffer(bitmap_widget); + BWRotateRight(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case RotateLeft: + BWStoreToBuffer(bitmap_widget); + BWRotateLeft(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Point: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, PointRequest, True, Plain); + break; + + case Curve: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, CurveRequest, True, Plain); + break; + + case Line: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, LineRequest, True, Plain); + break; + + case Rectangle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, RectangleRequest, True, Plain); + break; + + case FilledRectangle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, FilledRectangleRequest, True, Plain); + break; + + case Circle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, CircleRequest, True, Plain); + break; + + case FilledCircle: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, FilledCircleRequest, True, Plain); + break; + + case FloodFill: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, FloodFillRequest, True, Plain); + break; + + case SetHotSpot: + BWRemoveAllRequests(bitmap_widget); + BWEngageRequest(bitmap_widget, HotSpotRequest, True, Plain); + break; + + case ClearHotSpot: + BWStoreToBuffer(bitmap_widget); + BWClearHotSpot(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Undo: + BWUndo(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + break; + + case Quit: + DoQuit(bitmap_widget, NULL, NULL, NULL); + break; + } /* don't add anything below this line */ +} + +/* ARGSUSED */ + +void SwitchImage() +{ + if (image_visible) { + XtPopdown(image_shell); + image_visible = False; + } + else { + Position image_x, image_y; + int n; + Arg wargs[3]; + + XtTranslateCoords(bitmap_widget, + 10, 10, &image_x, &image_y); + + n = 0; + XtSetArg(wargs[n], XtNx, image_x); n++; + XtSetArg(wargs[n], XtNy, image_y); n++; + XtSetValues(image_shell, wargs, n); + + image_visible = True; + + FixImage(); + XtPopup(image_shell, XtGrabNone); + FixImage(); + } +} + +void SwitchGrid() +{ + BWSwitchGrid(bitmap_widget); +} + +void SwitchDashed() +{ + BWSwitchDashed(bitmap_widget); +} + +void SwitchAxes() +{ + BWSwitchAxes(bitmap_widget); +} + +void SwitchStippled() +{ + BWSwitchStippled(bitmap_widget); +} + +void SwitchProportional() +{ + BWSwitchProportional(bitmap_widget); +} + +void SwitchZoom() +{ + if (BWQueryZooming(bitmap_widget)) { + BWZoomOut(bitmap_widget); + BWChangeNotify(bitmap_widget); + } + else { + if (BWQueryMarked(bitmap_widget)) { + BWStoreToBuffer(bitmap_widget); + BWZoomMarked(bitmap_widget); + BWChangeNotify(bitmap_widget); + } + else { + BWEngageRequest(bitmap_widget, ZoomInRequest, False, Plain); + } + } +} + +void DoCut() +{ + BWStore(bitmap_widget); + BWStoreToBuffer(bitmap_widget); + BWClearMarked(bitmap_widget); + BWUnmark(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); +} + +void DoCopy() +{ + BWStore(bitmap_widget); + BWUnmark(bitmap_widget); +} + +void DoPaste() +{ + BWRequestSelection(bitmap_widget, btime, TRUE); + BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain); +} + +void DoNew() +{ + BWGetFilename(bitmap_widget, &filename); + if (PopupDialog(input_dialog, "New file:", + filename, &filename, XtGrabExclusive) == Okay) { + BWChangeFilename(bitmap_widget, filename); + BWChangeBasename(bitmap_widget, filename); + BWStoreToBuffer(bitmap_widget); + BWClear(bitmap_widget); + BWClearHotSpot(bitmap_widget); + BWChangeNotify(bitmap_widget); + BWClearChanged(bitmap_widget); + BWUnmark(bitmap_widget); + FixStatus(); + } +} + +void DoLoad() +{ + if (BWQueryChanged(bitmap_widget)) { + BWGetFilename(bitmap_widget, &filename); + RetryLoadSave: + switch (PopupDialog(qsave_dialog, "Save file before loading?", + filename, &filename, XtGrabExclusive)) { + case Yes: + if (BWWriteFile(bitmap_widget, filename, NULL) + != BitmapSuccess) { + XmuSnprintf(message, sizeof(message), "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryLoadSave; + } + break; + + case Cancel: + return; + } + } + BWGetFilepath(bitmap_widget, &filename); + RetryLoad: + if (PopupDialog(input_dialog, "Load file:", + filename, &filename, XtGrabExclusive) == Okay) { + if (BWReadFile(bitmap_widget, filename, NULL) != BitmapSuccess) { + XmuSnprintf(message, sizeof(message), "Can't read file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryLoad; + } + else { + BWChangeNotify(bitmap_widget); + BWClearChanged(bitmap_widget); + FixStatus(); + } + } +} + +void DoInsert() +{ + BWGetFilepath(bitmap_widget, &filename); + RetryInsert: + if (PopupDialog(input_dialog, "Insert file:", + filename, &filename, XtGrabExclusive) == Okay) { + if (BWStoreFile(bitmap_widget, filename, NULL) != BitmapSuccess) { + XmuSnprintf(message, sizeof(message), "Can't read file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryInsert; + } + else { + BWEngageRequest(bitmap_widget, RestoreRequest, False, Plain); + } + } +} + +void DoSave() +{ + BWGetFilename(bitmap_widget, &filename); + if (!strcmp(filename, "")) + DoSaveAs(); + else if (BWWriteFile(bitmap_widget, NULL, NULL) != BitmapSuccess) { + XmuSnprintf(message, sizeof(message), "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + DoSaveAs(); + } + else { + BWClearChanged(bitmap_widget); + } +} + +void DoSaveAs() +{ + BWGetFilename(bitmap_widget, &filename); + RetrySave: + if (PopupDialog(input_dialog, "Save file:", + filename, &filename, XtGrabExclusive) == Okay) { + if (BWWriteFile(bitmap_widget, filename, NULL) != BitmapSuccess) { + XmuSnprintf(message, sizeof(message), "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetrySave; + } + else { + BWClearChanged(bitmap_widget); + FixStatus(); + } + } +} + +void DoResize() +{ + Dimension width, height; + format = ""; + RetryResize: + if (PopupDialog(input_dialog, "Resize to WIDTHxHEIGHT:", + format, &format, XtGrabExclusive) == Okay) { + if (BWParseSize(format, &width, &height)) { + BWResize(bitmap_widget, width, height); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + FixStatus(); + } + else { + XmuSnprintf(message, sizeof(message), "Wrong format: %s", format); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryResize; + } + } +} + +void DoRescale() +{ + Dimension width, height; + + format = ""; + RetryRescale: + if (PopupDialog(input_dialog, "Rescale to WIDTHxHEIGHT:", + format, &format, XtGrabExclusive) == Okay) { + if (BWParseSize(format, &width, &height)) { + BWRescale(bitmap_widget, width, height); + BWChangeNotify(bitmap_widget); + BWSetChanged(bitmap_widget); + FixStatus(); + } + else { + XmuSnprintf(message, sizeof(message), "Wrong format: %s", format); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryRescale; + } + } +} + +void DoFilename() +{ + BWGetFilename(bitmap_widget, &filename); + if (PopupDialog(input_dialog, "Change filename:", + filename, &filename, XtGrabExclusive) == Okay) { + BWChangeFilename(bitmap_widget, filename); + FixStatus(); + } +} + +void DoBasename() +{ + BWGetBasename(bitmap_widget, &base_name); + if (PopupDialog(input_dialog, "Change basename:", + base_name, &base_name, XtGrabExclusive) == Okay) { + BWChangeBasename(bitmap_widget, base_name); + FixStatus(); + } +} + +void DoQuit(w, event, params, num_params) /* ARGSUSED */ + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (BWQueryChanged(bitmap_widget)) { + BWGetFilename(bitmap_widget, &filename); + RetryQuit: + switch (PopupDialog(qsave_dialog, "Save file before quitting?", + filename, &filename, XtGrabExclusive)) { + case Yes: + if (BWWriteFile(bitmap_widget, filename, NULL) + != BitmapSuccess) { + XmuSnprintf(message, sizeof(message), "Can't write file: %s", filename); + if (PopupDialog(error_dialog, message, + NULL, NULL, XtGrabExclusive) == Retry) + goto RetryQuit; + else return; + } + break; + + case Cancel: + return; + } + } + exit(0); +} + +int main(int argc, char *argv[]) +{ + int i, n; + Arg wargs[2]; + Widget w; + Widget radio_group = NULL; + XtPointer radio_data = NULL; + + top_widget = XtInitialize(NULL, "Bitmap", + options, XtNumber(options), &argc, argv); + + if (argc > 2) { + fprintf(stderr, usage); + exit (0); + } + + check_mark = XCreateBitmapFromData(XtDisplay(top_widget), + RootWindowOfScreen(XtScreen(top_widget)), + (char *) xlogo16_bits, + xlogo16_width, + xlogo16_height); + + XtAddActions(actions_table, XtNumber(actions_table)); + XtOverrideTranslations + (top_widget, + XtParseTranslationTable("WM_PROTOCOLS: do-quit()")); + + parent_widget = XtCreateManagedWidget("parent", panedWidgetClass, + top_widget, NULL, 0); + + formy_widget = XtCreateManagedWidget("formy", formWidgetClass, + parent_widget, NULL, 0); + + fileMenu_widget = XtCreatePopupShell("fileMenu", + simpleMenuWidgetClass, + formy_widget, NULL, 0); + + (void) XtCreateManagedWidget("fileButton", + menuButtonWidgetClass, + formy_widget, NULL, 0); + + for (i = 0; i < XtNumber(file_menu); i++) { + w = XtCreateManagedWidget(file_menu[i].name, + (file_menu[i].trap ? + smeBSBObjectClass : smeLineObjectClass), + fileMenu_widget, NULL, 0), + XtAddCallback(w, + XtNcallback, + TheCallback, + (XtPointer)&file_menu[i].id); + + file_menu[i].widget = w; + } + + editMenu_widget = XtCreatePopupShell("editMenu", + simpleMenuWidgetClass, + formy_widget, NULL, 0); + + (void) XtCreateManagedWidget("editButton", + menuButtonWidgetClass, + formy_widget, NULL, 0); + + for (i = 0; i < XtNumber(edit_menu); i++) { + w = XtCreateManagedWidget(edit_menu[i].name, + (edit_menu[i].trap ? + smeBSBObjectClass : smeLineObjectClass), + editMenu_widget, NULL, 0), + XtAddCallback(w, + XtNcallback, + TheCallback, + (XtPointer)&edit_menu[i].id); + + edit_menu[i].widget = w; + } + + status_widget = XtCreateManagedWidget("status", labelWidgetClass, + formy_widget, NULL, 0); + + pane_widget = XtCreateManagedWidget("pane", panedWidgetClass, + parent_widget, NULL, 0); + + form_widget = XtCreateManagedWidget("form", formWidgetClass, + pane_widget, NULL, 0); + + for (i = 0; i < XtNumber(buttons); i++) { + w = XtCreateManagedWidget(buttons[i].name, + (buttons[i].trap ? + toggleWidgetClass : commandWidgetClass), + form_widget, NULL, 0); + + XtAddCallback(w, + XtNcallback, + TheCallback, + (XtPointer)&buttons[i].id); + + buttons[i].widget = w; + + if (buttons[i].id == Point) { + radio_group = buttons[i].widget; + radio_data = buttons[i].name; + } + } + bitmap_widget = XtCreateManagedWidget("bitmap", bitmapWidgetClass, + pane_widget, NULL, 0); + XtRealizeWidget(top_widget); + if (argc > 1) + if (BWReadFile(bitmap_widget, argv[1], NULL)) + + wm_delete_window = XInternAtom(XtDisplay(top_widget), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(top_widget), XtWindow(top_widget), + &wm_delete_window, 1); + + + image_shell = XtCreatePopupShell("image", transientShellWidgetClass, + top_widget, NULL, 0); + + box_widget = XtCreateManagedWidget("box", boxWidgetClass, + image_shell, NULL, 0); + + normal_image_widget = XtCreateManagedWidget("normalImage", + labelWidgetClass, + box_widget, NULL, 0); + + inverted_image_widget = XtCreateManagedWidget("invertedImage", + labelWidgetClass, + box_widget, NULL, 0); + + n=0; + XtSetArg(wargs[n], XtNbitmap, BWGetUnzoomedPixmap(bitmap_widget)); n++; + XtSetValues(normal_image_widget, wargs, n); + XtSetValues(inverted_image_widget, wargs, n); + + XtRealizeWidget(image_shell); + + BWNotify(bitmap_widget, (XtActionProc)FixUp); + + FixStatus(); + + input_dialog = CreateDialog(top_widget, "input", Okay | Cancel); + error_dialog = CreateDialog(top_widget, "error", Abort | Retry); + qsave_dialog = CreateDialog(top_widget, "qsave", Yes | No | Cancel); + + XawToggleSetCurrent(radio_group, radio_data); + BWEngageRequest(bitmap_widget, PointRequest, True, Plain); + + XtMainLoop(); + exit(0); +} diff --git a/bitmap/Bitmap-color.ad b/bitmap/Bitmap-color.ad new file mode 100644 index 0000000..bd88b6e --- /dev/null +++ b/bitmap/Bitmap-color.ad @@ -0,0 +1,19 @@ +! $Xorg: Bitmap-co.ad,v 1.3 2000/08/17 19:53:49 cpqbld Exp $ +! The App-defaults file for Bitmap on a color screen. + +#include "Bitmap" + +*background: medium blue +*foreground: cyan +*borderColor: plum +*frame: deep sky blue +*highlight: magenta +*Command.background: purple +*Toggle.background: purple +*MenuButton.background: purple +*Command.foreground: white +*Toggle.foreground: white +*MenuButton.foreground: white +*status.foreground: green +*Dialog.icon.foreground: pale green +*bitmap.stippled: off diff --git a/bitmap/Bitmap-nocase.ad b/bitmap/Bitmap-nocase.ad new file mode 100644 index 0000000..cfa6b83 --- /dev/null +++ b/bitmap/Bitmap-nocase.ad @@ -0,0 +1,233 @@ +! $Xorg: Bitmap.ad,v 1.3 2000/08/17 19:53:49 cpqbld Exp $ +! +! $XFree86: $ +! +! The App-defaults file for Bitmap for use on file systems +! that are not case sensitive. + +*TransientShell.allowShellResize: True +*shapeStyle: oval +*cursor: left_ptr +*pane.orientation: horizontal + +*Form*top: ChainTop +*Form*bottom: ChainTop +*Form*left: ChainLeft +*Form*right: ChainLeft + +*MenuButton.leftBitmap: menu12 +*form*width: 120 +*form*height: 15 + +*baseTranslations:#override\ + Ctrlc: do-quit()\n\ + q: do-quit()\n\ + Ctrln: do-new()\n\ + Ctrlf: do-load()\n\ + Ctrli: do-insert()\n\ + Ctrls: do-save()\n\ + Ctrlw: do-save-as()\n\ + Ctrlr: do-resize()\n\ + Ctrlx: do-rescale()\n\ + Ctrle: do-filename()\n\ + Ctrlb: do-basename()\n\ + Metai: switch-image()\n\ + Metag: switch-grid()\n\ + Metad: switch-dashed()\n\ + Metaa: switch-axes()\n\ + Metas: switch-stippled()\n\ + Metap: switch-proportional()\n\ + Metaz: switch-zoom()\n\ + Metac: do-cut()\n\ + Metaw: do-copy()\n\ + Metay: do-paste() + + +*Toggle.translations: : highlight(WhenUnset)\n\ + : unhighlight()\n\ + ,: set() notify() + +*MenuButton.translations:: highlight()\n\ + : reset()\n\ + Any: reset() fix-menu() PopupMenu() + +*Dialog*baseTranslations:#override\ + Return: set-dialog-button(okay, yes, retry)\n\ + Ctrlg: set-dialog-button(cancel, abort) +*image*baseTranslations:#override\ + ,: switch-image() +*image*width: 0 +*image*height: 0 +*image*Label.internalWidth: 0 +*image*Label.internalHeight: 0 +*image*normalImage.foreground: white +*image*normalImage.background: black +*image*invertedImage.foreground: black +*image*invertedImage.background: white + +*bitmap.cursor: tcross +*bitmap.dashes: Dashes +*bitmap.stipple: Stippler +*bitmap.stippled: on + +*TransientShell.width: 300 + +*input*icon: Term +*qsave*icon: Term +*error*icon: Excl +*Dialog.yes.label: Yes +*Dialog.no.label: No +*Dialog.okay.label: OK +*Dialog.abort.label: Abort +*Dialog.cancel.label: Cancel +*Dialog.retry.label: Retry + +*MenuButton.width: 58 + +*SimpleMenu.width: 0 +*SimpleMenu.height: 0 +*SimpleMenu.cursor: hand2 +*SimpleMenu.line.height: 0 + +*fileButton.label: File +*fileButton.menuName: fileMenu + +*editButton.label: Edit +*editButton.fromHoriz: fileButton +*editButton.menuName: editMenu + +*formy.status*top: ChainTop +*formy.status*bottom: ChainTop +*formy.status*left: ChainLeft +*formy.status*right: ChainRight +*status.fromHoriz: editButton +*status.borderWidth: 0 + +*SmeBSB.HorizontalMargins: 32 + +*fileMenu.new.label: New (Ctrl-N)... +*fileMenu.load.label: Load (Ctrl-F)... +*fileMenu.insert.label: Insert (Ctrl-I)... +*fileMenu.save.label: Save (Ctrl-S) +*fileMenu.saveAs.label: Save As (Ctrl-W)... +*fileMenu.resize.label: Resize (Ctrl-R)... +*fileMenu.rescale.label: Rescale (Ctrl-X)... +*fileMenu.filename.label: Filename (Ctrl-E)... +*fileMenu.basename.label: Basename (Ctrl-B)... +*fileMenu.quit.label: Quit (Ctrl-C, Q) + +*editMenu.image.label: Image (Meta-I) +*editMenu.grid.label: Grid (Meta-G) +*editMenu.dashed.label: Dashed (Meta-D) +*editMenu.axes.label: Axes (Meta-A) +*editMenu.stippled.label: Stippled (Meta-S) +*editMenu.proportional.label: Proportional (Meta-P) +*editMenu.zoom.label: Zoom (Meta-Z) +*editMenu.cut.label: Cut (Meta-C) +*editMenu.copy.label: Copy (Meta-W) +*editMenu.paste.label: Paste (Meta-Y, Ctrl-mb) + +*form.clear.label: Clear +*form.set.fromVert: clear +*form.set.label: Set +*form.invert.fromVert: set +*form.invert.label: Invert + +*form.mark.vertDistance: 10 +*form.mark.fromVert: invert +*form.mark.label: Mark +*form.unmark.fromVert: mark +*form.unmark.label: Unmark + +*form.copy.vertDistance: 10 +*form.copy.fromVert: unmark +*form.copy.radioGroup: mark +*form.copy.label: Copy +*form.move.fromVert: copy +*form.move.radioGroup: copy +*form.move.label: Move + +*form.flipHoriz.vertDistance: 10 +*form.flipHoriz.width: 36 +*form.flipHoriz.height: 36 +*form.flipHoriz.fromVert: move +*form.flipHoriz.bitmap: FlipHoriz +*form.up.vertDistance: 10 +*form.up.width: 36 +*form.up.height: 36 +*form.up.fromVert: move +*form.up.fromHoriz: flipHoriz +*form.up.bitmap: Up +*form.flipVert.vertDistance: 10 +*form.flipVert.width: 36 +*form.flipVert.height: 36 +*form.flipVert.fromVert: move +*form.flipVert.fromHoriz: up +*form.flipVert.bitmap: FlipVert +*form.left.width: 36 +*form.left.height: 36 +*form.left.fromVert: flipHoriz +*form.left.bitmap: Left +*form.fold.width: 36 +*form.fold.height: 36 +*form.fold.fromVert: up +*form.fold.fromHoriz: left +*form.fold.bitmap: Fold +*form.right.width: 36 +*form.right.height: 36 +*form.right.fromVert: flipVert +*form.right.fromHoriz: fold +*form.right.bitmap: Right +*form.rotateLeft.width: 36 +*form.rotateLeft.height: 36 +*form.rotateLeft.fromVert: left +*form.rotateLeft.bitmap: RotateLeft +*form.down.width: 36 +*form.down.height: 36 +*form.down.fromVert: fold +*form.down.fromHoriz: rotateLeft +*form.down.bitmap: Down +*form.rotateRight.width: 36 +*form.rotateRight.height: 36 +*form.rotateRight.fromVert: right +*form.rotateRight.fromHoriz: down +*form.rotateRight.bitmap: RotateRight + +*form.point.vertDistance: 10 +*form.point.fromVert: rotateLeft +*form.point.radioGroup: move +*form.point.label: Point +*form.curve.fromVert: point +*form.curve.radioGroup: point +*form.curve.label: Curve +*form.line.fromVert: curve +*form.line.radioGroup: curve +*form.line.label: Line +*form.rectangle.fromVert: line +*form.rectangle.radioGroup: line +*form.rectangle.label: Rectangle +*form.filledRectangle.fromVert: rectangle +*form.filledRectangle.radioGroup: rectangle +*form.filledRectangle.label: Filled Rectangle +*form.circle.fromVert: filledRectangle +*form.circle.radioGroup: filledRectangle +*form.circle.label: Circle +*form.filledCircle.fromVert: circle +*form.filledCircle.radioGroup: circle +*form.filledCircle.label: Filled Circle +*form.floodFill.fromVert: filledCircle +*form.floodFill.radioGroup: filledCircle +*form.floodFill.label: Flood Fill + +*form.setHotSpot.vertDistance: 10 +*form.setHotSpot.fromVert: floodFill +*form.setHotSpot.radioGroup: floodFill +*form.setHotSpot.label: Set Hot Spot +*form.clearHotSpot.fromVert: setHotSpot +*form.clearHotSpot.label: Clear Hot Spot + +*form.undo.vertDistance: 10 +*form.undo.fromVert: clearHotSpot +*form.undo.label: Undo + + diff --git a/bitmap/Bitmap.ad b/bitmap/Bitmap.ad new file mode 100644 index 0000000..5047c12 --- /dev/null +++ b/bitmap/Bitmap.ad @@ -0,0 +1,229 @@ +! $Xorg: Bitmap.ad,v 1.3 2000/08/17 19:53:49 cpqbld Exp $ +! The App-defaults file for Bitmap. + +*TransientShell.allowShellResize: True +*shapeStyle: oval +*cursor: left_ptr +*pane.orientation: horizontal + +*Form*top: ChainTop +*Form*bottom: ChainTop +*Form*left: ChainLeft +*Form*right: ChainLeft + +*MenuButton.leftBitmap: menu12 +*form*width: 120 +*form*height: 15 + +*baseTranslations:#override\ + Ctrlc: do-quit()\n\ + q: do-quit()\n\ + Ctrln: do-new()\n\ + Ctrlf: do-load()\n\ + Ctrli: do-insert()\n\ + Ctrls: do-save()\n\ + Ctrlw: do-save-as()\n\ + Ctrlr: do-resize()\n\ + Ctrlx: do-rescale()\n\ + Ctrle: do-filename()\n\ + Ctrlb: do-basename()\n\ + Metai: switch-image()\n\ + Metag: switch-grid()\n\ + Metad: switch-dashed()\n\ + Metaa: switch-axes()\n\ + Metas: switch-stippled()\n\ + Metap: switch-proportional()\n\ + Metaz: switch-zoom()\n\ + Metac: do-cut()\n\ + Metaw: do-copy()\n\ + Metay: do-paste() + + +*Toggle.translations: : highlight(WhenUnset)\n\ + : unhighlight()\n\ + ,: set() notify() + +*MenuButton.translations:: highlight()\n\ + : reset()\n\ + Any: reset() fix-menu() PopupMenu() + +*Dialog*baseTranslations:#override\ + Return: set-dialog-button(okay, yes, retry)\n\ + Ctrlg: set-dialog-button(cancel, abort) +*image*baseTranslations:#override\ + ,: switch-image() +*image*width: 0 +*image*height: 0 +*image*Label.internalWidth: 0 +*image*Label.internalHeight: 0 +*image*normalImage.foreground: white +*image*normalImage.background: black +*image*invertedImage.foreground: black +*image*invertedImage.background: white + +*bitmap.cursor: tcross +*bitmap.dashes: Dashes +*bitmap.stipple: Stipple +*bitmap.stippled: on + +*TransientShell.width: 300 + +*input*icon: Term +*qsave*icon: Term +*error*icon: Excl +*Dialog.yes.label: Yes +*Dialog.no.label: No +*Dialog.okay.label: OK +*Dialog.abort.label: Abort +*Dialog.cancel.label: Cancel +*Dialog.retry.label: Retry + +*MenuButton.width: 58 + +*SimpleMenu.width: 0 +*SimpleMenu.height: 0 +*SimpleMenu.cursor: hand2 +*SimpleMenu.line.height: 0 + +*fileButton.label: File +*fileButton.menuName: fileMenu + +*editButton.label: Edit +*editButton.fromHoriz: fileButton +*editButton.menuName: editMenu + +*formy.status*top: ChainTop +*formy.status*bottom: ChainTop +*formy.status*left: ChainLeft +*formy.status*right: ChainRight +*status.fromHoriz: editButton +*status.borderWidth: 0 + +*SmeBSB.HorizontalMargins: 32 + +*fileMenu.new.label: New (Ctrl-N)... +*fileMenu.load.label: Load (Ctrl-F)... +*fileMenu.insert.label: Insert (Ctrl-I)... +*fileMenu.save.label: Save (Ctrl-S) +*fileMenu.saveAs.label: Save As (Ctrl-W)... +*fileMenu.resize.label: Resize (Ctrl-R)... +*fileMenu.rescale.label: Rescale (Ctrl-X)... +*fileMenu.filename.label: Filename (Ctrl-E)... +*fileMenu.basename.label: Basename (Ctrl-B)... +*fileMenu.quit.label: Quit (Ctrl-C, Q) + +*editMenu.image.label: Image (Meta-I) +*editMenu.grid.label: Grid (Meta-G) +*editMenu.dashed.label: Dashed (Meta-D) +*editMenu.axes.label: Axes (Meta-A) +*editMenu.stippled.label: Stippled (Meta-S) +*editMenu.proportional.label: Proportional (Meta-P) +*editMenu.zoom.label: Zoom (Meta-Z) +*editMenu.cut.label: Cut (Meta-C) +*editMenu.copy.label: Copy (Meta-W) +*editMenu.paste.label: Paste (Meta-Y, Ctrl-mb) + +*form.clear.label: Clear +*form.set.fromVert: clear +*form.set.label: Set +*form.invert.fromVert: set +*form.invert.label: Invert + +*form.mark.vertDistance: 10 +*form.mark.fromVert: invert +*form.mark.label: Mark +*form.unmark.fromVert: mark +*form.unmark.label: Unmark + +*form.copy.vertDistance: 10 +*form.copy.fromVert: unmark +*form.copy.radioGroup: mark +*form.copy.label: Copy +*form.move.fromVert: copy +*form.move.radioGroup: copy +*form.move.label: Move + +*form.flipHoriz.vertDistance: 10 +*form.flipHoriz.width: 36 +*form.flipHoriz.height: 36 +*form.flipHoriz.fromVert: move +*form.flipHoriz.bitmap: FlipHoriz +*form.up.vertDistance: 10 +*form.up.width: 36 +*form.up.height: 36 +*form.up.fromVert: move +*form.up.fromHoriz: flipHoriz +*form.up.bitmap: Up +*form.flipVert.vertDistance: 10 +*form.flipVert.width: 36 +*form.flipVert.height: 36 +*form.flipVert.fromVert: move +*form.flipVert.fromHoriz: up +*form.flipVert.bitmap: FlipVert +*form.left.width: 36 +*form.left.height: 36 +*form.left.fromVert: flipHoriz +*form.left.bitmap: Left +*form.fold.width: 36 +*form.fold.height: 36 +*form.fold.fromVert: up +*form.fold.fromHoriz: left +*form.fold.bitmap: Fold +*form.right.width: 36 +*form.right.height: 36 +*form.right.fromVert: flipVert +*form.right.fromHoriz: fold +*form.right.bitmap: Right +*form.rotateLeft.width: 36 +*form.rotateLeft.height: 36 +*form.rotateLeft.fromVert: left +*form.rotateLeft.bitmap: RotateLeft +*form.down.width: 36 +*form.down.height: 36 +*form.down.fromVert: fold +*form.down.fromHoriz: rotateLeft +*form.down.bitmap: Down +*form.rotateRight.width: 36 +*form.rotateRight.height: 36 +*form.rotateRight.fromVert: right +*form.rotateRight.fromHoriz: down +*form.rotateRight.bitmap: RotateRight + +*form.point.vertDistance: 10 +*form.point.fromVert: rotateLeft +*form.point.radioGroup: move +*form.point.label: Point +*form.curve.fromVert: point +*form.curve.radioGroup: point +*form.curve.label: Curve +*form.line.fromVert: curve +*form.line.radioGroup: curve +*form.line.label: Line +*form.rectangle.fromVert: line +*form.rectangle.radioGroup: line +*form.rectangle.label: Rectangle +*form.filledRectangle.fromVert: rectangle +*form.filledRectangle.radioGroup: rectangle +*form.filledRectangle.label: Filled Rectangle +*form.circle.fromVert: filledRectangle +*form.circle.radioGroup: filledRectangle +*form.circle.label: Circle +*form.filledCircle.fromVert: circle +*form.filledCircle.radioGroup: circle +*form.filledCircle.label: Filled Circle +*form.floodFill.fromVert: filledCircle +*form.floodFill.radioGroup: filledCircle +*form.floodFill.label: Flood Fill + +*form.setHotSpot.vertDistance: 10 +*form.setHotSpot.fromVert: floodFill +*form.setHotSpot.radioGroup: floodFill +*form.setHotSpot.label: Set Hot Spot +*form.clearHotSpot.fromVert: setHotSpot +*form.clearHotSpot.label: Clear Hot Spot + +*form.undo.vertDistance: 10 +*form.undo.fromVert: clearHotSpot +*form.undo.label: Undo + + diff --git a/bitmap/Bitmap.c b/bitmap/Bitmap.c new file mode 100644 index 0000000..669187c --- /dev/null +++ b/bitmap/Bitmap.c @@ -0,0 +1,1950 @@ +/* $Xorg: Bitmap.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: Bitmap.c,v 1.5 2001/12/26 21:39:34 paulo Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "BitmapP.h" +#include "Bitmap.h" + +#include +#include + +#define min(x, y) ((((int)(x)) < (int)(y)) ? (x) : (y)) +#define max(x, y) ((((int)(x)) > (int)(y)) ? (x) : (y)) + +Boolean DEBUG; + +#define DefaultGridTolerance 8 +#define DefaultBitmapSize "16x16" +#define FallbackBitmapWidth 16 +#define FallbackBitmapHeight 16 +#define DefaultGrid TRUE +#define DefaultDashed TRUE +#define DefaultStippled TRUE +#define DefaultProportional TRUE +#define DefaultAxes FALSE +#define DefaultMargin 16 +#define DefaultSquareWidth 16 +#define DefaultSquareHeight 16 +#define DefaultFilename "" + +#define Offset(field) XtOffsetOf(BitmapRec, bitmap.field) + +static XtResource resources[] = { +{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset(foreground_pixel), XtRString, XtDefaultForeground}, +{XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel), + Offset(highlight_pixel), XtRString, XtDefaultForeground}, +{XtNframe, XtCFrame, XtRPixel, sizeof(Pixel), + Offset(frame_pixel), XtRString, XtDefaultForeground}, +{XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension), + Offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance}, +{XtNsize, XtCSize, XtRString, sizeof(String), + Offset(size), XtRImmediate, (XtPointer) DefaultBitmapSize}, +{XtNdashed, XtCDashed, XtRBoolean, sizeof(Boolean), + Offset(dashed), XtRImmediate, (XtPointer) DefaultDashed}, +{XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean), + Offset(grid), XtRImmediate, (XtPointer) DefaultGrid}, +{XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean), + Offset(stippled), XtRImmediate, (XtPointer) DefaultStippled}, +{XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean), + Offset(proportional), XtRImmediate, (XtPointer) DefaultProportional}, +{XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean), + Offset(axes), XtRImmediate, (XtPointer) DefaultAxes}, +{XtNsquareWidth, XtCSquareWidth, XtRDimension, sizeof(Dimension), + Offset(squareW), XtRImmediate, (XtPointer) DefaultSquareWidth}, +{XtNsquareHeight, XtCSquareHeight, XtRDimension, sizeof(Dimension), + Offset(squareH), XtRImmediate, (XtPointer) DefaultSquareHeight}, +{XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension), + Offset(margin), XtRImmediate, (XtPointer) DefaultMargin}, +{XtNxHot, XtCXHot, XtRPosition, sizeof(Position), + Offset(hot.x), XtRImmediate, (XtPointer) NotSet}, +{XtNyHot, XtCYHot, XtRPosition, sizeof(Position), + Offset(hot.y), XtRImmediate, (XtPointer) NotSet}, +{XtNbutton1Function, XtCButton1Function, XtRButtonFunction, sizeof(int), + Offset(button_function[0]), XtRImmediate, (XtPointer) Set}, +{XtNbutton2Function, XtCButton2Function, XtRButtonFunction, sizeof(int), + Offset(button_function[1]), XtRImmediate, (XtPointer) Invert}, +{XtNbutton3Function, XtCButton3Function, XtRButtonFunction, sizeof(int), + Offset(button_function[2]), XtRImmediate, (XtPointer) Clear}, +{XtNbutton4Function, XtCButton4Function, XtRButtonFunction, sizeof(int), + Offset(button_function[3]), XtRImmediate, (XtPointer) Clear}, +{XtNbutton5Function, XtCButton5Function, XtRButtonFunction, sizeof(int), + Offset(button_function[4]), XtRImmediate, (XtPointer) Clear}, +{XtNfilename, XtCFilename, XtRString, sizeof(String), + Offset(filename), XtRImmediate, (XtPointer) DefaultFilename}, +{XtNbasename, XtCBasename, XtRString, sizeof(String), + Offset(basename), XtRImmediate, (XtPointer) DefaultFilename}, +{XtNdashes, XtCDashes, XtRBitmap, sizeof(Pixmap), + Offset(dashes), XtRImmediate, (XtPointer) XtUnspecifiedPixmap}, +{XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap), + Offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap}, +}; +#undef Offset + + +static XtActionsRec actions[] = +{ +{"mark", (XtActionProc)BWTMark}, +{"mark-all", (XtActionProc)BWTMarkAll}, +{"unmark", (XtActionProc)BWTUnmark}, +{"paste", (XtActionProc)BWTPaste}, +{"bw-debug", (XtActionProc)BWDebug}, +{"abort", (XtActionProc)BWAbort}, +{"store-to-buffer", (XtActionProc)BWStoreToBuffer}, +{"change-notify", (XtActionProc)BWChangeNotify}, +{"set-changed", (XtActionProc)BWSetChanged}, +{"up", (XtActionProc)BWUp}, +{"down", (XtActionProc)BWDown}, +{"left", (XtActionProc)BWLeft}, +{"right", (XtActionProc)BWRight}, +{"fold", (XtActionProc)BWFold}, +{"flip-horiz", (XtActionProc)BWFlipHoriz}, +{"flip-vert", (XtActionProc)BWFlipVert}, +{"rotate-right", (XtActionProc)BWRotateRight}, +{"rotate-left", (XtActionProc)BWRotateLeft}, +{"set", (XtActionProc)BWSet}, +{"clear", (XtActionProc)BWClear}, +{"invert", (XtActionProc)BWInvert}, +{"undo", (XtActionProc)BWUndo}, +{"redraw", (XtActionProc)BWRedraw}, +}; + +static char translations1[] = +"\ +Shift: mark()\n\ +Shift: mark-all()\n\ +Shift: unmark()\n\ +Ctrl: paste()\n\ +Ctrll: redraw()\n\ +d: bw-debug()\n\ +a: abort()\n\ +Up: store-to-buffer()\ + up()\ + change-notify()\ + set-changed()\n\ +KP_Up: store-to-buffer()\ + up()\ + change-notify()\ + set-changed()\n\ +Down: store-to-buffer()\ + down()\ + change-notify()\ + set-changed()\n\ +KP_Down: store-to-buffer()\ + down()\ + change-notify()\ + set-changed()\n\ +Left: store-to-buffer()\ + left()\ + change-notify()\ + set-changed()\n\ +KP_Left: store-to-buffer()\ + left()\ + change-notify()\ + set-changed()\n\ +Right: store-to-buffer()\ + right()\ + change-notify()\ + set-changed()\n\ +KP_Right: store-to-buffer()\ + right()\ + change-notify()\ + set-changed()\n\ +f: store-to-buffer()\ + fold()\ + change-notify()\ + set-changed()\n\ +h: store-to-buffer()\ + flip-horiz()\ + change-notify()\ + set-changed()\n\ +"; + +static char translations2[] = +"v: store-to-buffer()\ + flip-vert()\ + change-notify()\ + set-changed()\n\ +r: store-to-buffer()\ + rotate-right()\ + change-notify()\ + set-changed()\n\ +l: store-to-buffer()\ + rotate-left()\ + change-notify()\ + set-changed()\n\ +s: store-to-buffer()\ + set()\ + change-notify()\ + set-changed()\n\ +c: store-to-buffer()\ + clear()\ + change-notify()\ + set-changed()\n\ +i: store-to-buffer()\ + invert()\ + change-notify()\ + set-changed()\n\ +u: undo()\ + change-notify()\ + set-changed()\n\ +"; + +Atom targets[] = { + XA_BITMAP, + XA_PIXMAP +}; + +#include "Requests.h" + + +static BWRequestRec requests[] = +{ +{MarkRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawRectangle, + TwoPointsTerminateTimed, (XtPointer) BWSelect, + NULL, (XtPointer) NULL}, +{RestoreRequest, sizeof(BWStatus), + OnePointEngage, (XtPointer) BWDragStored, + OnePointTerminate, (XtPointer) BWRestore, + NULL, (XtPointer) NULL}, +{ImmediateCopyRequest, sizeof(BWStatus), + OnePointEngage, (XtPointer) BWDragMarked, + OnePointTerminate, (XtPointer) BWCopy, + NULL, (XtPointer) NULL}, +{ImmediateMoveRequest, sizeof(BWStatus), + OnePointEngage, (XtPointer) BWDragMarked, + OnePointTerminate, (XtPointer) BWMove, + NULL, (XtPointer) NULL}, +{CopyRequest, sizeof(BWStatus), + DragOnePointEngage, (XtPointer) Paste, + DragOnePointTerminate, (XtPointer) ImmediateCopyRequest, + Interface, (XtPointer) BWUnmark}, +{MoveRequest, sizeof(BWStatus), + DragOnePointEngage, (XtPointer) Paste, + DragOnePointTerminate, (XtPointer) ImmediateMoveRequest, + Interface, (XtPointer) BWUnmark}, +{PointRequest, sizeof(BWStatus), + DragOnePointEngage, (XtPointer) BWDrawPoint, + DragOnePointTerminate, (XtPointer) BWDrawPoint, + NULL, (XtPointer) NULL}, +{CurveRequest, sizeof(BWStatus), + DragTwoPointsEngage, (XtPointer) BWBlindLine, + DragTwoPointsTerminate, (XtPointer) BWBlindLine, + NULL, (XtPointer) NULL}, +{LineRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawLine, + TwoPointsTerminate, (XtPointer) BWDrawLine, + NULL, (XtPointer) NULL}, +{RectangleRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawRectangle, + TwoPointsTerminate, (XtPointer) BWDrawRectangle, + NULL, (XtPointer) NULL}, +{FilledRectangleRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawRectangle, + TwoPointsTerminate, (XtPointer) BWDrawFilledRectangle, + NULL, (XtPointer) NULL}, +{CircleRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawCircle, + TwoPointsTerminate, (XtPointer) BWDrawCircle, + NULL, (XtPointer) NULL}, +{FilledCircleRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawCircle, + TwoPointsTerminate, (XtPointer) BWDrawFilledCircle, + NULL, (XtPointer) NULL}, +{FloodFillRequest, sizeof(BWStatus), + OnePointEngage, (XtPointer) NULL, + OnePointTerminate, (XtPointer) BWFloodFill, + NULL, (XtPointer) NULL}, +{HotSpotRequest, sizeof(BWStatus), + OnePointEngage, (XtPointer) BWDrawHotSpot, + OnePointTerminate, (XtPointer) BWDrawHotSpot, + NULL, (XtPointer) NULL}, +{ZoomInRequest, sizeof(BWStatus), + TwoPointsEngage, (XtPointer) BWDrawRectangle, + TwoPointsTerminate, (XtPointer) BWZoomIn, + NULL, (XtPointer) NULL}, +}; + +static void ClassInitialize(void); +static void Initialize(Widget wrequest, Widget wnew, + ArgList argv, Cardinal *argc); +static void Redisplay(Widget w, XEvent *event, Region region); +static void Resize(Widget w); +static void Destroy(Widget w); +static void Refresh(BitmapWidget BW, Position x, Position y, + Dimension width, Dimension height); +static Boolean SetValues(Widget old, Widget request, Widget new, + ArgList args, Cardinal *num_args); + +BitmapClassRec bitmapClassRec = { +{ /* core fields */ + /* superclass */ (WidgetClass) &simpleClassRec, + /* class_name */ "Bitmap", + /* widget_size */ sizeof(BitmapRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ XtInheritRealize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ FALSE, + /* compress_enterleave */ TRUE, + /* visible_interest */ TRUE, + /* 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 */ NULL , /* set in code */ + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL, + }, + { + /* empty */ XtInheritChangeSensitive, + }, + { + /* targets */ targets, + /* num_trets */ XtNumber(targets), + /* requests */ requests, + /* num_requests */ XtNumber(requests), + } +}; + +WidgetClass bitmapWidgetClass = (WidgetClass) &bitmapClassRec; + +/* ARGSUSED */ + +void +BWDebug(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + DEBUG ^= True; +} + +Pixmap +BWGetPixmap(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return GetPixmap(BW, BW->bitmap.zoom.image); +} + +Pixmap +BWGetUnzoomedPixmap(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + GC gc; + Pixmap pix; + + if (BW->bitmap.zooming) { + pix = XCreatePixmap(XtDisplay(w), XtWindow(w), + BW->bitmap.zoom.image->width, + BW->bitmap.zoom.image->height, 1); + if (!(gc = XCreateGC(XtDisplay(w), pix, + (unsigned long) 0, (XGCValues *) 0))) + return (Pixmap) None; + + XPutImage(XtDisplay(w), pix, gc, + BW->bitmap.zoom.image, + 0, 0, 0, 0, + BW->bitmap.zoom.image->width, + BW->bitmap.zoom.image->height); + XPutImage(XtDisplay(w), pix, gc, + BW->bitmap.image, + 0, 0, + BW->bitmap.zoom.at_x, + BW->bitmap.zoom.at_y, + BW->bitmap.image->width, + BW->bitmap.image->height); + } + else { + pix = XCreatePixmap(XtDisplay(w), XtWindow(w), + BW->bitmap.image->width, + BW->bitmap.image->height, 1); + if (! (gc = XCreateGC(XtDisplay(w), pix, + (unsigned long) 0, (XGCValues *) 0))) + return (Pixmap) None; + + XPutImage(XtDisplay(w), pix, gc, + BW->bitmap.image, + 0, 0, 0, 0, + BW->bitmap.image->width, + BW->bitmap.image->height); + } + XFreeGC(XtDisplay(w), gc); + return(pix); +} + + +XImage * +GetImage(BitmapWidget BW, Pixmap pixmap) +{ + Window root; + int x, y; + unsigned int width, height, border_width, depth; + XImage *source, *image; + + XGetGeometry(XtDisplay(BW), pixmap, &root, &x, &y, + &width, &height, &border_width, &depth); + + source = XGetImage(XtDisplay(BW), pixmap, x, y, width, height, + 1, XYPixmap); + + image = ConvertToBitmapImage(BW, source); + + return image; +} + +XImage * +CreateBitmapImage(BitmapWidget BW, char *data, + Dimension width, Dimension height) +{ + XImage *image = XCreateImage(XtDisplay(BW), + DefaultVisual(XtDisplay(BW), + DefaultScreen(XtDisplay(BW))), + 1, XYBitmap, 0, + data, width, height, + 8, ((int)width + 7) / 8); + + image->height = height; + image->width = width; + image->depth = 1; + image->xoffset = 0; + image->format = XYBitmap; + image->data = (char *)data; + image->byte_order = LSBFirst; + image->bitmap_unit = 8; + image->bitmap_bit_order = LSBFirst; + image->bitmap_pad = 8; + image->bytes_per_line = ((int)width + 7) / 8; + + return image; +} + +void +DestroyBitmapImage(XImage **image) +{ + /*XDestroyImage(*image);*/ + if (image) { + if (*image) { + if ((*image)->data) + XtFree((*image)->data); + XtFree((char *)*image); + } + *image = NULL; + } +} + +#if 0 +XImage * +BWGetImage(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + BitmapWidget BW = (BitmapWidget) w; + + return BW->bitmap.image; +} +#endif + +void +BWChangeNotify(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.notify) + (*BW->bitmap.notify)(w, NULL, NULL, NULL); +} + +void +BWNotify(Widget w, XtActionProc proc) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.notify = proc; +} + +void +BWSetChanged(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.changed = True; +} + +Boolean +BWQueryChanged(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return BW->bitmap.changed; +} + +void +BWClearChanged(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.changed = False; +} + +Boolean +BWQueryStored(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return (BW->bitmap.storage != NULL); +} + +Boolean +BWQueryStippled(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return BW->bitmap.stippled; +} + +static void +RedrawStippled(BitmapWidget BW) +{ + XExposeEvent event; + + event.type = Expose; + event.display = XtDisplay((Widget)BW); + event.window = XtWindow((Widget)BW); + event.x = 0; + event.y = 0; + event.width = BW->core.width; + event.height = BW->core.height; + event.count = 0; + + BWRedrawMark((Widget)BW); + + BW->bitmap.stipple_change_expose_event = True; + + XtDispatchEvent((XEvent *)&event); + + BW->bitmap.stipple_change_expose_event = False; +} + +void +BWSwitchStippled(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + RedrawStippled(BW); + + BW->bitmap.stippled ^= True; + XSetFillStyle(XtDisplay(BW), BW->bitmap.highlighting_gc, + (BW->bitmap.stippled ? FillStippled : FillSolid)); + + RedrawStippled(BW); +} + +void +BWSelect(Widget w, Position from_x, Position from_y, + Position to_x, Position to_y, Time btime) +{ + BWMark(w, from_x, from_y, to_x, to_y); + + BWGrabSelection(w, btime); +} + +Boolean +BWQueryAxes(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return BW->bitmap.axes; +} + +void +BWSwitchAxes(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.axes ^= True; + BWHighlightAxes(w); +} + +void +BWAxes(Widget w, Boolean _switch) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.axes != _switch) + BWSwitchAxes(w); +} + +void +BWRedrawAxes(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.axes) + BWHighlightAxes(w); +} + +#if 0 +void +BWPutImage(BitmapWidget w, Display *display, Drawable drawable, GC gc, + Position x, Position y) +{ + BitmapWidget BW = (BitmapWidget) w; + + XPutImage(display, drawable, gc, BW->bitmap.image, + 0, 0, x, y, BW->bitmap.image->width, BW->bitmap.image->height); +} +#endif + +static String +StripFilename(String filename) +{ + char *begin = strrchr(filename, '/'); + char *end, *result; + int length; + + if (filename) { + begin = (begin ? begin + 1 : filename); + end = strchr(begin, '.'); /* change to strrchr to allow longer names */ + length = (end ? (end - begin) : strlen (begin)); + result = (char *) XtMalloc (length + 1); + strncpy (result, begin, length); + result [length] = '\0'; + return (result); + } + else + return (NULL); +} + +static int +XmuWriteBitmapDataToFile(String filename, String basename, + int width, int height, char *datap, + int x_hot, int y_hot) +{ + FILE *file; + int i, data_length; + + data_length = Length(width, height); + + if(!filename || !strcmp(filename, "") || !strcmp(filename, "-")) { + file = stdout; + filename = "dummy"; + } + else + file = fopen(filename, "w+"); + + if (!basename || !strcmp(basename, "") || !strcmp(basename, "-")) + basename = StripFilename(filename); + + if (file) { + fprintf(file, "#define %s_width %d\n", basename, width); + fprintf(file, "#define %s_height %d\n", basename, height); + if (QuerySet(x_hot, y_hot)) { + fprintf(file, "#define %s_x_hot %d\n", basename, x_hot); + fprintf(file, "#define %s_y_hot %d\n", basename, y_hot); + } + fprintf(file, "static unsigned char %s_bits[] = {\n 0x%02x", + basename, (unsigned char) datap[0]); + for(i = 1; i < data_length; i++) { + fprintf(file, ","); + fprintf(file, (i % 12) ? " " : "\n "); + fprintf(file, "0x%02x", (unsigned char) datap[i]); + } + fprintf(file, "};\n"); + + if (file != stdout) + fclose(file); + + return BitmapSuccess; + } + + return 1; +} + +/* + * + */ + + /* ARGSUSED */ +static void +CvtStringToButtonFunction(XrmValuePtr args, /* not used */ + Cardinal *num_args, /* not used */ + XrmValuePtr from_val, + XrmValuePtr to_val) +{ + static int button_function; + char lower_name[80]; + + XmuCopyISOLatin1Lowered (lower_name, (char*)from_val->addr); + + if (!strcmp(lower_name, XtClear)) { + button_function = Clear; + to_val->addr = (XPointer) &button_function; + to_val->size = sizeof(button_function); + return; + } + + if (!strcmp(lower_name, XtSet)) { + button_function = Set; + to_val->addr = (XPointer) &button_function; + to_val->size = sizeof(button_function); + return; + } + + if (!strcmp(lower_name, XtInvert)) { + button_function = Invert; + to_val->addr = (XPointer) &button_function; + to_val->size = sizeof(button_function); + return; + } + + XtStringConversionWarning(from_val->addr, XtRButtonFunction); + button_function = Clear; + to_val->addr = (XPointer) &button_function; + to_val->size = sizeof(button_function); + +} + +static void +ClassInitialize(void) +{ + char *tm_table = XtMalloc(strlen(translations1) + strlen(translations2) + 1); + strcpy(tm_table, translations1); + strcat(tm_table, translations2); + bitmapClassRec.core_class.tm_table = tm_table; + + XawInitializeWidgetSet(); + XtAddConverter(XtRString, XtRButtonFunction, CvtStringToButtonFunction, + NULL, 0); + DEBUG = False; +} + +static void +SetSizeFromSizeResource(BitmapWidget bw) +{ + if (BWParseSize(bw->bitmap.size, + &bw->bitmap.width, + &bw->bitmap.height) + == + False) { + bw->bitmap.width = FallbackBitmapWidth; + bw->bitmap.height = FallbackBitmapHeight; + XtWarning("Cannot parse the size resource. BitmapWidget"); + } +} + + +/* ARGSUSED */ +static void +Initialize(Widget wrequest, Widget wnew, ArgList argv, Cardinal *argc) +{ + BitmapWidget new = (BitmapWidget) wnew; + + XGCValues values; + XtGCMask mask; + char *image_data, *buffer_data; + + new->bitmap.stipple_change_expose_event = False; + new->bitmap.notify = NULL; + new->bitmap.cardinal = 0; + new->bitmap.current = 0; + new->bitmap.fold = False; + new->bitmap.changed = False; + new->bitmap.zooming = False; + new->bitmap.selection.own = False; + new->bitmap.selection.limbo = False; + + new->bitmap.request_stack = (BWRequestStack *) + XtMalloc(sizeof(BWRequestStack)); + + new->bitmap.request_stack[0].request = NULL; + new->bitmap.request_stack[0].call_data = NULL; + new->bitmap.request_stack[0].trap = False; + + SetSizeFromSizeResource(new); + + new->core.width = new->bitmap.width * new->bitmap.squareW + + 2 * new->bitmap.margin; + new->core.height = new->bitmap.height * new->bitmap.squareH + + 2 * new->bitmap.margin; + + new->bitmap.hot.x = new->bitmap.hot.y = NotSet; + new->bitmap.buffer_hot.x = new->bitmap.buffer_hot.y = NotSet; + + new->bitmap.mark.from_x = new->bitmap.mark.from_y = NotSet; + new->bitmap.mark.to_x = new->bitmap.mark.to_y = NotSet; + new->bitmap.buffer_mark.from_x = new->bitmap.buffer_mark.from_y = NotSet; + new->bitmap.buffer_mark.to_x = new->bitmap.buffer_mark.to_y = NotSet; + + values.foreground = new->bitmap.foreground_pixel; + values.background = new->core.background_pixel; + values.foreground ^= values.background; + values.function = GXxor; + mask = GCForeground | GCBackground | GCFunction; + new->bitmap.drawing_gc = XCreateGC(XtDisplay(new), + RootWindow(XtDisplay(new), + DefaultScreen(XtDisplay(new))), + mask, &values); + + values.foreground = new->bitmap.highlight_pixel; + values.background = new->core.background_pixel; + values.foreground ^= values.background; + values.function = GXxor; + mask = GCForeground | GCBackground | GCFunction; + if (new->bitmap.stipple != XtUnspecifiedPixmap) + { + values.stipple = new->bitmap.stipple; + mask |= GCStipple | GCFillStyle; + } + values.fill_style = (new->bitmap.stippled ? FillStippled : FillSolid); + + new->bitmap.highlighting_gc = XCreateGC(XtDisplay(new), + RootWindow(XtDisplay(new), + DefaultScreen(XtDisplay(new))), + mask, &values); + + + values.foreground = new->bitmap.frame_pixel; + values.background = new->core.background_pixel; + values.foreground ^= values.background; + mask = GCForeground | GCBackground | GCFunction; + if (new->bitmap.dashes != XtUnspecifiedPixmap) + { + values.stipple = new->bitmap.dashes; + mask |= GCStipple | GCFillStyle; + } + values.fill_style = (new->bitmap.dashed ? FillStippled : FillSolid); + + new->bitmap.frame_gc = XCreateGC(XtDisplay(new), + RootWindow(XtDisplay(new), + DefaultScreen(XtDisplay(new))), + mask, &values); + + values.foreground = new->bitmap.highlight_pixel; + values.background = new->core.background_pixel; + values.foreground ^= values.background; + mask = GCForeground | GCBackground | GCFunction; + new->bitmap.axes_gc = XCreateGC(XtDisplay(new), + RootWindow(XtDisplay(new), + DefaultScreen(XtDisplay(new))), + mask, &values); + + image_data = CreateCleanData(Length(new->bitmap.width, + new->bitmap.height)); + buffer_data = CreateCleanData(Length(new->bitmap.width, + new->bitmap.height)); + + new->bitmap.storage = NULL; + + new->bitmap.image = CreateBitmapImage(new, + image_data, + new->bitmap.width, + new->bitmap.height); + new->bitmap.buffer = CreateBitmapImage(new, + buffer_data, + new->bitmap.width, + new->bitmap.height); + + /* Read file */ + { + int status; + XImage *image, *buffer; + unsigned char *image_data; + char *buffer_data; + unsigned int width, height; + int x_hot, y_hot; + + status = XmuReadBitmapDataFromFile(new->bitmap.filename, + &width, &height, &image_data, + &x_hot, &y_hot); + if (status == BitmapSuccess) { + + buffer_data = CreateCleanData(Length(width, height)); + + image = CreateBitmapImage(new, (char *)image_data, width, height); + buffer = CreateBitmapImage(new, buffer_data, width, height); + + TransferImageData(new->bitmap.image, buffer); + + DestroyBitmapImage(&new->bitmap.image); + DestroyBitmapImage(&new->bitmap.buffer); + + new->bitmap.image = image; + new->bitmap.buffer = buffer; + new->bitmap.width = width; + new->bitmap.height = height; + + new->bitmap.hot.x = x_hot; + new->bitmap.hot.y = y_hot; + + new->bitmap.changed = False; + new->bitmap.zooming = False; + } + + new->bitmap.filename = XtNewString(new->bitmap.filename); + + if (!strcmp(new->bitmap.basename, "")) { + new->bitmap.basename = StripFilename(new->bitmap.filename); + } + else + new->bitmap.basename = XtNewString(new->bitmap.basename); + } + + Resize((Widget)new); +} + + +/* returns False if the format is wrong */ +Boolean +BWParseSize(String size, Dimension *width, Dimension *height) +{ + int x, y; + unsigned int w, h; + int status; + + status = XParseGeometry(size, &x, &y, &w, &h); + + if (status & (WidthValue | HeightValue)) { + *width = (Dimension) w; + *height = (Dimension) h; + return True; + } + else return False; + +} + + +Boolean +BWQueryMarked(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y); +} + +static void +FixMark(BitmapWidget BW) +{ + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + BW->bitmap.mark.from_x = min(BW->bitmap.mark.from_x, + BW->bitmap.image->width); + BW->bitmap.mark.from_y = min(BW->bitmap.mark.from_y, + BW->bitmap.image->height); + BW->bitmap.mark.to_x = min(BW->bitmap.mark.to_x, + BW->bitmap.image->width); + BW->bitmap.mark.to_y = min(BW->bitmap.mark.to_y, + BW->bitmap.image->height); + + if((BW->bitmap.mark.from_x == BW->bitmap.mark.from_y) && + (BW->bitmap.mark.to_x == BW->bitmap.mark.to_y)) + BW->bitmap.mark.from_x = + BW->bitmap.mark.from_y = + BW->bitmap.mark.to_x = + BW->bitmap.mark.to_y = NotSet; + } +} + +/* ARGSUSED */ +int +BWStoreFile(Widget w, String filename, String *basename) +{ + BitmapWidget BW = (BitmapWidget) w; + int status; + unsigned char *storage_data; + unsigned int width, height; + int x_hot, y_hot; + + status = XmuReadBitmapDataFromFile(filename, &width, &height, + &storage_data, &x_hot, &y_hot); + if (status == BitmapSuccess) { + + DestroyBitmapImage(&BW->bitmap.storage); + + BW->bitmap.storage = CreateBitmapImage(BW, (char *)storage_data, width, height); + + return BitmapSuccess; + } + else + XtWarning(" read file failed. BitmapWidget"); + + return status; +} + +String +BWUnparseStatus(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + XmuSnprintf(BW->bitmap.status, sizeof(BW->bitmap.status), + "Filename: %s Basename: %s Size: %dx%d", + (strcmp(BW->bitmap.filename, "") ? BW->bitmap.filename : ""), + (strcmp(BW->bitmap.basename, "") ? BW->bitmap.basename : ""), + BW->bitmap.width, BW->bitmap.height); + + return BW->bitmap.status; +} + +void +BWChangeFilename(Widget w, String str) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (str) { + XtFree(BW->bitmap.filename); + BW->bitmap.filename = XtNewString( str); + } +} + +void +BWChangeBasename(Widget w, String str) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (str) { + XtFree(BW->bitmap.basename); + BW->bitmap.basename = XtNewString(str); + } +} + + +int +BWReadFile(Widget w, String filename, String basename) /* ARGSUSED */ +{ + BitmapWidget BW = (BitmapWidget) w; + int status; + XImage *image, *buffer; + unsigned char *image_data; + char *buffer_data; + unsigned int width, height; + int x_hot, y_hot; + + if (!filename) + filename = BW->bitmap.filename; + + status = XmuReadBitmapDataFromFile(filename, &width, &height, &image_data, + &x_hot, &y_hot); + if (status == BitmapSuccess) { + + buffer_data = CreateCleanData(Length(width, height)); + + image = CreateBitmapImage(BW, (char *)image_data, width, height); + buffer = CreateBitmapImage(BW, buffer_data, width, height); + + TransferImageData(BW->bitmap.image, buffer); + + DestroyBitmapImage(&BW->bitmap.image); + DestroyBitmapImage(&BW->bitmap.buffer); + + BW->bitmap.image = image; + BW->bitmap.buffer = buffer; + BW->bitmap.width = width; + BW->bitmap.height = height; + + BW->bitmap.hot.x = x_hot; + BW->bitmap.hot.y = y_hot; + + BW->bitmap.changed = False; + BW->bitmap.zooming = False; + + XtFree(BW->bitmap.filename); + BW->bitmap.filename = XtNewString(filename); + XtFree(BW->bitmap.basename); + BW->bitmap.basename= XtNewString(StripFilename(filename)); + + BWUnmark(w); + + Resize((Widget)BW); + + if (BW->core.visible) { + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); + } + + return BitmapSuccess; + } + else + XtWarning(" read file failed. BitmapWidget"); + + return status; +} + +#if 0 +void +BWSetImage(Widget w, XImage *image) +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *buffer; + char *buffer_data; + + buffer_data = CreateCleanData(Length(image->width, image->height)); + buffer = CreateBitmapImage(BW, buffer_data, + (Dimension) image->width, + (Dimension) image->height); + + TransferImageData(BW->bitmap.image, buffer); + + DestroyBitmapImage(&BW->bitmap.image); + DestroyBitmapImage(&BW->bitmap.buffer); + + BW->bitmap.image = image; + BW->bitmap.buffer = buffer; + BW->bitmap.width = image->width; + BW->bitmap.height = image->height; + + Resize((Widget)BW); + + if (BW->core.visible) { + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); + } +} +#endif + +int +BWWriteFile(Widget w, String filename, String basename) +{ + BitmapWidget BW = (BitmapWidget) w; + char *data; + XImage *image; + XPoint hot; + int status; + + if (BW->bitmap.zooming) { + data = XtMalloc(Length(BW->bitmap.zoom.image->width, + BW->bitmap.zoom.image->height)); + memmove( data, BW->bitmap.zoom.image->data, + Length(BW->bitmap.zoom.image->width, + BW->bitmap.zoom.image->height)); + image = CreateBitmapImage(BW, data, + (Dimension) BW->bitmap.zoom.image->width, + (Dimension) BW->bitmap.zoom.image->height); + CopyImageData(BW->bitmap.image, image, + 0, 0, + BW->bitmap.image->width - 1, + BW->bitmap.image->height - 1, + BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y); + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { + hot.x = BW->bitmap.hot.x + BW->bitmap.zoom.at_x; + hot.y = BW->bitmap.hot.y + BW->bitmap.zoom.at_y; + } + else + hot = BW->bitmap.zoom.hot; + } + else { + image = BW->bitmap.image; + hot = BW->bitmap.hot; + } + + if (!filename) filename = BW->bitmap.filename; + else { + XtFree(BW->bitmap.filename); + BW->bitmap.filename = XtNewString(filename); + XtFree(BW->bitmap.basename); + BW->bitmap.basename= XtNewString(StripFilename(filename)); + } + if (!basename) basename = BW->bitmap.basename; + else { + XtFree(BW->bitmap.basename); + BW->bitmap.basename = XtNewString(basename); + } + + if (DEBUG) + fprintf(stderr, "Saving filename: %s %s\n", filename, basename); + + status = XmuWriteBitmapDataToFile(filename, basename, + image->width, image->height, image->data, + hot.x, hot.y); + if (BW->bitmap.zooming) + DestroyBitmapImage(&image); + + if (status == BitmapSuccess) + BW->bitmap.changed = False; + + return status; +} + +String +BWGetFilename(Widget w, String *str) +{ + BitmapWidget BW = (BitmapWidget) w; + + *str = XtNewString(BW->bitmap.filename); + + return *str; +} + +String +BWGetFilepath(Widget w, String *str) +{ + BitmapWidget BW = (BitmapWidget) w; + String end; + + *str = XtNewString(BW->bitmap.filename); + end = strrchr(*str, '/'); + + if (end) + *(end + 1) = '\0'; + else + **str = '\0'; + + return *str; +} + + +String +BWGetBasename(Widget w, String *str) +{ + BitmapWidget BW = (BitmapWidget) w; + + *str = XtNewString(BW->bitmap.basename); + + return *str; +} + +static void +FixHotSpot(BitmapWidget BW) +{ + if (!QueryInBitmap(BW, BW->bitmap.hot.x, BW->bitmap.hot.y)) + BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet; +} + +static void +ZoomOut(BitmapWidget BW) +{ + CopyImageData(BW->bitmap.image, BW->bitmap.zoom.image, + 0, 0, + BW->bitmap.image->width - 1, + BW->bitmap.image->height - 1, + BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y); + + DestroyBitmapImage(&BW->bitmap.image); + DestroyBitmapImage(&BW->bitmap.buffer); + + BW->bitmap.image = BW->bitmap.zoom.image; + BW->bitmap.buffer = BW->bitmap.zoom.buffer; + BW->bitmap.width = BW->bitmap.image->width; + BW->bitmap.height = BW->bitmap.image->height; + BW->bitmap.fold = BW->bitmap.zoom.fold; + BW->bitmap.changed |= BW->bitmap.zoom.changed; + BW->bitmap.grid = BW->bitmap.zoom.grid; + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { + BW->bitmap.hot.x += BW->bitmap.zoom.at_x; + BW->bitmap.hot.y += BW->bitmap.zoom.at_y; + } + else + BW->bitmap.hot = BW->bitmap.zoom.hot; + + BW->bitmap.mark.from_x = NotSet; + BW->bitmap.mark.from_y = NotSet; + BW->bitmap.mark.to_x = NotSet; + BW->bitmap.mark.to_y = NotSet; + BW->bitmap.zooming = False; +} + +void +BWZoomOut(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.zooming) { + ZoomOut(BW); + + Resize((Widget)BW); + if (BW->core.visible) + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); + } +} + + +void +BWZoomMarked(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BWZoomIn(w, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y); +} + +void +BWZoomIn(Widget w, + Position from_x, Position from_y, + Position to_x, Position to_y) +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *image, *buffer; + Dimension width, height; + char *image_data, *buffer_data; + + if (BW->bitmap.zooming) + ZoomOut(BW); + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + from_x = max(0, from_x); + from_y = max(0, from_y); + to_x = min(BW->bitmap.width - 1, to_x); + to_y = min(BW->bitmap.height - 1, to_y); + + width = to_x - from_x + 1; + height = to_y - from_y + 1; + + image_data = CreateCleanData(Length(width, height)); + buffer_data = CreateCleanData(Length(width, height)); + + image = CreateBitmapImage(BW, image_data, width, height); + buffer = CreateBitmapImage(BW, buffer_data, width, height); + + CopyImageData(BW->bitmap.image, image, from_x, from_y, to_x, to_y, 0, 0); + CopyImageData(BW->bitmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0); + + BW->bitmap.zoom.image = BW->bitmap.image; + BW->bitmap.zoom.buffer = BW->bitmap.buffer; + BW->bitmap.zoom.at_x = from_x; + BW->bitmap.zoom.at_y = from_y; + BW->bitmap.zoom.fold = BW->bitmap.fold; + BW->bitmap.zoom.changed = BW->bitmap.changed; + BW->bitmap.zoom.hot = BW->bitmap.hot; + BW->bitmap.zoom.grid = BW->bitmap.grid; + + BW->bitmap.image = image; + BW->bitmap.buffer = buffer; + BW->bitmap.width = width; + BW->bitmap.height = height; + BW->bitmap.changed = False; + BW->bitmap.hot.x -= from_x; + BW->bitmap.hot.y -= from_y; + BW->bitmap.mark.from_x = NotSet; + BW->bitmap.mark.from_y = NotSet; + BW->bitmap.mark.to_x = NotSet; + BW->bitmap.mark.to_y = NotSet; + BW->bitmap.zooming = True; + BW->bitmap.grid = True; /* potencially true, could use a resource here */ + + FixHotSpot(BW); + + Resize((Widget)BW); + if (BW->core.visible) + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); +} + + +void +BWRescale(Widget w, Dimension width, Dimension height) +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *image, *buffer; + char *buffer_data; + + if (BW->bitmap.zooming) + ZoomOut(BW); + + image = ScaleBitmapImage(BW, BW->bitmap.image, + (double) width / (double) BW->bitmap.image->width, + (double) height / (double) BW->bitmap.image->height); + + buffer_data = CreateCleanData(Length(image->width, image->height)); + buffer = CreateBitmapImage(BW, buffer_data, + (Dimension) image->width, + (Dimension) image->height); + + TransferImageData(BW->bitmap.buffer, buffer); + + DestroyBitmapImage(&BW->bitmap.image); + DestroyBitmapImage(&BW->bitmap.buffer); + + BW->bitmap.image = image; + BW->bitmap.buffer = buffer; + BW->bitmap.width = image->width; + BW->bitmap.height = image->height; + + FixHotSpot(BW); + FixMark(BW); + + Resize((Widget)BW); + if (BW->core.visible) + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); +} + +Boolean +BWQueryZooming(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return BW->bitmap.zooming; +} + + +static void +ResizeGrid(BitmapWidget BW, Dimension width, Dimension height) +{ + XImage *image, *buffer; + char *image_data, *buffer_data; + + if (BW->bitmap.zooming) + ZoomOut(BW); + + image_data = CreateCleanData(Length(width, height)); + buffer_data = CreateCleanData(Length(width, height)); + + image = CreateBitmapImage(BW, image_data, width, height); + buffer = CreateBitmapImage(BW, buffer_data, width, height); + + TransferImageData(BW->bitmap.image, image); + TransferImageData(BW->bitmap.buffer, buffer); + + DestroyBitmapImage(&BW->bitmap.image); + DestroyBitmapImage(&BW->bitmap.buffer); + + BW->bitmap.image = image; + BW->bitmap.buffer = buffer; + BW->bitmap.width = width; + BW->bitmap.height = height; + + FixHotSpot(BW); + FixMark(BW); +} + +void +BWResize(Widget w, Dimension width, Dimension height) +{ + BitmapWidget BW = (BitmapWidget) w; + + ResizeGrid(BW, width, height); + + Resize((Widget)BW); + if (BW->core.visible) + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); +} + +static void +Destroy(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + XFreeGC(XtDisplay(w), BW->bitmap.drawing_gc); + XFreeGC(XtDisplay(w), BW->bitmap.highlighting_gc); + XFreeGC(XtDisplay(w), BW->bitmap.frame_gc); + XFreeGC(XtDisplay(w), BW->bitmap.axes_gc); + BWRemoveAllRequests(w); + + XtFree(BW->bitmap.filename); + XtFree(BW->bitmap.basename); +} + + +static void +Resize(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + Dimension squareW, squareH; + + squareW = max(1, ((int)BW->core.width - 2 * (int)BW->bitmap.margin) / + (int)BW->bitmap.width); + squareH = max(1, ((int)BW->core.height - 2 * (int)BW->bitmap.margin) / + (int)BW->bitmap.height); + + if (BW->bitmap.proportional) + BW->bitmap.squareW = BW->bitmap.squareH = min(squareW, squareH); + else { + BW->bitmap.squareW = squareW; + BW->bitmap.squareH = squareH; + } + + BW->bitmap.horizOffset = max((Position)BW->bitmap.margin, + (Position)(BW->core.width - + BW->bitmap.width * + BW->bitmap.squareW) / 2); + BW->bitmap.vertOffset = max((Position)BW->bitmap.margin, + (Position)(BW->core.height - + BW->bitmap.height * + BW->bitmap.squareH) / 2); + + BW->bitmap.grid &= ((BW->bitmap.squareW > BW->bitmap.grid_tolerance) && + (BW->bitmap.squareH > BW->bitmap.grid_tolerance)); +} + +/* ARGSUSED */ +static void +Redisplay(Widget w, XEvent *event, Region region) +{ + BitmapWidget BW = (BitmapWidget) w; + + if(event->type == Expose + && + BW->core.visible) + if (BW->bitmap.stipple_change_expose_event == False) + Refresh(BW, + event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); +} + +void +BWClip(Widget w, Position x, Position y, Dimension width, Dimension height) +{ + Position from_x, from_y, + to_x, to_y; + BitmapWidget BW = (BitmapWidget) w; + XRectangle rectangle; + + from_x = InBitmapX(BW, x); + from_y = InBitmapY(BW, y); + to_x = InBitmapX(BW, x + width); + to_y = InBitmapY(BW, y + height); + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + from_x = max(0, from_x); + from_y = max(0, from_y); + to_x = min(BW->bitmap.width - 1, to_x); + to_y = min(BW->bitmap.height - 1, to_y); + + rectangle.x = InWindowX(BW, from_x); + rectangle.y = InWindowY(BW, from_y); + rectangle.width = InWindowX(BW, to_x + 1) - InWindowX(BW, from_x); + rectangle.height = InWindowY(BW, to_y + 1) - InWindowY(BW, from_y); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.highlighting_gc, + 0, 0, + &rectangle, 1, + Unsorted); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.drawing_gc, + 0, 0, + &rectangle, 1, + Unsorted); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.frame_gc, + 0, 0, + &rectangle, 1, + Unsorted); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.axes_gc, + 0, 0, + &rectangle, 1, + Unsorted); +} + +void +BWUnclip(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + XRectangle rectangle; + + rectangle.x = InWindowX(BW, 0); + rectangle.y = InWindowY(BW, 0); + rectangle.width = InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0); + rectangle.height = InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.highlighting_gc, + 0, 0, + &rectangle, 1, + Unsorted); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.drawing_gc, + 0, 0, + &rectangle, 1, + Unsorted); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.frame_gc, + 0, 0, + &rectangle, 1, + Unsorted); + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.axes_gc, + 0, 0, + &rectangle, 1, + Unsorted); +} + +static void +Refresh(BitmapWidget BW, Position x, Position y, + Dimension width, Dimension height) +{ + XRectangle rectangle; + + rectangle.x = min(x, InWindowX(BW, InBitmapX(BW, x))); + rectangle.y = min(y, InWindowY(BW, InBitmapY(BW, y))); + rectangle.width = max(x + width, + InWindowX(BW, InBitmapX(BW, x + width)+1)) - rectangle.x; + rectangle.height = max(y + height, + InWindowY(BW, InBitmapY(BW, y + height)+1)) - rectangle.y; + + XClearArea(XtDisplay(BW), XtWindow(BW), + rectangle.x, rectangle.y, + rectangle.width, rectangle.height, + False); + + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.frame_gc, + 0, 0, + &rectangle, 1, + Unsorted); + + XDrawRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1, + InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, + InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1); + + BWClip((Widget) BW, x, y, width, height); + + BWRedrawGrid((Widget) BW, x, y, width, height); + + BWRedrawSquares((Widget) BW, x, y, width, height); + + BWRedrawMark((Widget) BW); + BWRedrawHotSpot((Widget) BW); + BWRedrawAxes((Widget) BW); + BWUnclip((Widget) BW); +} + +Boolean +BWQueryGrid(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return BW->bitmap.grid; +} + +void +BWSwitchGrid(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + BW->bitmap.grid ^= TRUE; + BWDrawGrid(w, + 0, 0, + BW->bitmap.image->width - 1, BW->bitmap.image->height - 1); +} + +void +BWGrid(Widget w, Boolean _switch) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.grid != _switch) + BWSwitchGrid(w); +} + +Boolean +BWQueryDashed(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return (BW->bitmap.dashed); +} + +void +BWSwitchDashed(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + XRectangle rectangle; + + BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1); + + rectangle.x = 0; + rectangle.y = 0; + rectangle.width = BW->core.width; + rectangle.height = BW->core.height; + + XSetClipRectangles(XtDisplay(BW), + BW->bitmap.frame_gc, + 0, 0, + &rectangle, 1, + Unsorted); + + XDrawRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1, + InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, + InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1); + + BW->bitmap.dashed ^= True; + XSetFillStyle(XtDisplay(BW), BW->bitmap.frame_gc, + (BW->bitmap.dashed ? FillStippled : FillSolid)); + + XDrawRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1, + InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, + InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1); + + BWUnclip(w); + + BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1); +} + +void +BWDashed(Widget w, Boolean _switch) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.dashed != _switch) + BWSwitchDashed(w); +} + +static Boolean +SetValues(Widget old, Widget request, Widget new, + ArgList args, Cardinal *num_args) /* ARGSUSED */ +{ + BitmapWidget oldbw = (BitmapWidget) old; + BitmapWidget newbw = (BitmapWidget) new; + Boolean resize = False; + Boolean redisplay = False; + +#define NE(field) (oldbw->field != newbw->field) + + if (NE(bitmap.grid)) + BWSwitchGrid(old); + + if (NE(bitmap.dashed)) + BWSwitchDashed(old); + + if (NE(bitmap.axes)) + BWSwitchAxes(old); + + if (NE(bitmap.stippled)) + BWSwitchStippled(old); + + if (NE(bitmap.proportional)) + resize = True; + + if (NE(bitmap.filename) || NE(bitmap.basename) || NE(bitmap.size)) + BWChangeNotify(old); + + if (NE(bitmap.filename)) { + if (newbw->bitmap.filename) { + XtFree(oldbw->bitmap.filename); + newbw->bitmap.filename = XtNewString(newbw->bitmap.filename); + } + else + newbw->bitmap.filename = oldbw->bitmap.filename; + } + + if (NE(bitmap.basename)) { + if (newbw->bitmap.basename) { + XtFree(oldbw->bitmap.basename); + newbw->bitmap.basename = XtNewString(newbw->bitmap.basename); + } + else + newbw->bitmap.basename = oldbw->bitmap.basename; + } + + if (NE(bitmap.size)) { + Dimension width, height; + + if (BWParseSize(newbw->bitmap.size, &width, &height)) { + ResizeGrid(newbw, width, height); + resize = True; + } + } + + if (NE(bitmap.margin) || + NE(bitmap.grid_tolerance) || + NE(bitmap.squareW) || + NE(bitmap.squareH) || + NE(core.height) || + NE(core.width)) + resize = True; + + if (NE(bitmap.hot.x) || NE(bitmap.hot.y)) + BWSetHotSpot(old, newbw->bitmap.hot.x, newbw->bitmap.hot.y); + + if (NE(bitmap.foreground_pixel) || NE(core.background_pixel)) { + XSetForeground(XtDisplay(new), + newbw->bitmap.drawing_gc, + newbw->bitmap.foreground_pixel + ^ + newbw->core.background_pixel); + redisplay = True; + } + + if (NE(bitmap.frame_pixel) || NE(core.background_pixel)) { + XSetForeground(XtDisplay(new), + newbw->bitmap.frame_gc, + newbw->bitmap.frame_pixel + ^ + newbw->core.background_pixel); + redisplay = True; + } + + if (NE(bitmap.dashes)) { + XSetStipple(XtDisplay(new), + newbw->bitmap.frame_gc, + newbw->bitmap.dashes); + redisplay = True; + } + + if (NE(bitmap.highlight_pixel) || NE(core.background_pixel)) { + RedrawStippled(newbw); + XSetForeground(XtDisplay(new), + newbw->bitmap.highlighting_gc, + newbw->bitmap.highlight_pixel + ^ + newbw->core.background_pixel); + RedrawStippled(newbw); + } + + if (NE(bitmap.stipple)) { + RedrawStippled(newbw); + XSetStipple(XtDisplay(new), + newbw->bitmap.highlighting_gc, + newbw->bitmap.stipple); + RedrawStippled(newbw); + } + + if (resize) Resize((Widget)newbw); + + return (redisplay || resize); + +#undef NE +} + +Boolean +BWQueryProportional(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + return (BW->bitmap.proportional); +} + +void +BWSwitchProportional(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.proportional ^= True; + + Resize((Widget)BW); + if (BW->core.visible) + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, + BW->core.width, BW->core.height, + True); +} + +#if 0 +void +BWProportional(Widget w, Boolean _switch) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.proportional != _switch) + BWSwitchProportional(w); +} +#endif + +void +BWTPaste(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + BitmapWidget BW = (BitmapWidget) w; + + BWRequestSelection(w, event->xbutton.time, TRUE); + + if (!BWQueryStored(w)) + return; + + BWEngageRequest(w, RestoreRequest, False, + (char *)&(event->xbutton.state), sizeof(int)); + + OnePointHandler(w, + (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status, + event, NULL); +} + +void +BWTMark(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + BitmapWidget BW = (BitmapWidget) w; + + BWEngageRequest(w, MarkRequest, False, + (char *)&(event->xbutton.state), sizeof(int)); + TwoPointsHandler(w, + (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status, + event, NULL); + +} + +void +BWTMarkAll(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + BWMarkAll(w); + + BWGrabSelection(w, event->xkey.time); +} + +void +BWTUnmark(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ + BWUnmark(w); +} + +/*****************************************************************************/ diff --git a/bitmap/Bitmap.h b/bitmap/Bitmap.h new file mode 100644 index 0000000..c6166d7 --- /dev/null +++ b/bitmap/Bitmap.h @@ -0,0 +1,286 @@ +/* $Xorg: Bitmap.h,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/Bitmap.h,v 1.4 2001/06/12 09:45:53 alanh Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + + +#ifndef _Bitmap_h +#define _Bitmap_h + +/**************************************************************** + * + * Bitmap widget + * + ****************************************************************/ + +#include + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + foreground Foredround Pixel XtDefaultForeground + highlight Highlight Pixel XtDefaultForeground + frame Frame Pixel XtDefaultForeground + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + mappedWhenManaged MappedWhenManaged Boolean True + resize Resize Boolean True + sensitive Sensitive Boolean True + width Width Dimension 0 + height Height Dimension 0 + size Size String 32x32 + squareWidht SquareWidht Dimension 16 + squareHeight SquareHeight Dimension 16 + x Position Position 320 + y Position Position 320 + xHot XHot Position NotSet + yHot YHot Position NotSet + margin Margin Dimension 16 + grid Grid Boolean True + gridTolerance GridTolerance Dimension 8 + dashed Dashed Boolean True + dashes Dashes Bitmap XtUnspecifiedPixmap + stippled Stippled Boolean True + stipple Stipple Bitmap XtUnspecifiedPixmap + proportional Proportional Boolean True + axes Axes Boolean True + button1Function Button1Function ButtonFunction Set + button2Function Button2Function ButtonFunction Invert + button3Function Button3Function ButtonFunction Clear + button4Function Button4Function ButtonFunction Invert + button5Function Button5Function ButtonFunction Invert + filename Filename String None + basename Basename String None +*/ + +/* define any special resource names here that are not in */ + +#define XtNbitmapResource "bitmapResource" +#define XtNstipple "stipple" +#define XtNstippled "stippled" +#define XtNdashes "dashes" +#define XtNdashed "dashed" +#define XtNgrid "grid" +#define XtNgridTolerance "gridTolerance" +#define XtNaxes "axes" +#define XtNbitmapSize "bitmapSize" +#define XtNsize "size" +#define XtNsquareWidth "squareWidth" +#define XtNsquareHeight "squareHeight" +#define XtNxHot "xHot" +#define XtNyHot "yHot" +#define XtNbutton1Function "button1Function" +#define XtNbutton2Function "button2Function" +#define XtNbutton3Function "button3Function" +#define XtNbutton4Function "button4Function" +#define XtNbutton5Function "button5Function" +#define XtNfilename "filename" +#define XtNbasename "basename" +#define XtNmouseForeground "mouseForeground" +#define XtNmouseBackground "mouseBackground" +#define XtNframe "frame" +#define XtNmargin "margin" +#define XtNproportional "proportional" + +#define XtCBitmapResource "BitmapResource" +#define XtCHighlight "Highlight" +#define XtCStipple "Stipple" +#define XtCStippled "Stippled" +#define XtCDashes "Dashes" +#define XtCDashed "Dashed" +#define XtCGrid "Grid" +#define XtCGridTolerance "GridTolerance" +#define XtCAxes "Axes" +#define XtBitmapSize "BitmapSize" +#define XtCSize "Size" +#define XtCSquareWidth "SquareWidth" +#define XtCSquareHeight "SquareHeight" +#define XtCXHot "XHot" +#define XtCYHot "YHot" +#define XtCButton1Function "Button1Function" +#define XtCButton2Function "Button2Function" +#define XtCButton3Function "Button3Function" +#define XtCButton4Function "Button4Function" +#define XtCButton5Function "Button5Function" +#define XtCFilename "Filename" +#define XtCBasename "Basename" +#define XtCFrame "Frame" +#ifndef XtCMargin +#define XtCMargin "Margin" +#endif +#define XtCProportional "Proportional" + +#define XtRButtonFunction "ButtonFunction" + +/* bitmap defines */ + +#define NotSet -1 +#define Clear 0 +#define Set 1 +#define Invert 2 +#define Highlight 3 +#define On True +#define Off False + +#define XtClear "clear" +#define XtSet "set" +#define XtInvert "invert" + +#define MarkRequest "MarkRequest" +#define StoreRequest "StoreRequest" +#define RestoreRequest "RestoreRequest" +#define CopyRequest "CopyRequest" +#define MoveRequest "MoveRequest" +#define PointRequest "PointRequest" +#define LineRequest "LineRequest" +#define CurveRequest "CurveRequest" +#define RectangleRequest "RectangleRequest" +#define FilledRectangleRequest "FilledRectangleRequest" +#define CircleRequest "CircleRequest" +#define FilledCircleRequest "FilledCircleRequest" +#define FloodFillRequest "FloodFillRequest" +#define HotSpotRequest "HotSpotRequest" +#define ZoomInRequest "ZoomInRequest" +#define PasteRequest "PasteRequest" +#define ImmediateCopyRequest "ImmediateCopyRequest" +#define ImmediateMoveRequest "ImmediateMoveRequest" + +/* bitmap exports */ + +typedef struct _BWRequestRec BWRequestRec; +typedef char *BWRequest; + +/* declare specific BitmapWidget class and instance datatypes */ + +typedef struct _BitmapClassRec *BitmapWidgetClass; +typedef struct _BitmapRec *BitmapWidget; +/* declare the class constant */ + +extern WidgetClass bitmapWidgetClass; + +extern Boolean BWEngageRequest(Widget w, BWRequest name, Boolean trap, + XtPointer call_data, Cardinal call_data_size); +extern Boolean BWTerminateRequest(Widget w, Boolean cont); + +extern void BWUp ( Widget w ); +extern void BWDown ( Widget w ); +extern void BWLeft ( Widget w ); +extern void BWRight ( Widget w ); +extern void BWRotateRight ( Widget w ); +extern void BWRotateLeft ( Widget w ); +extern void BWSwitchGrid ( Widget w ); +extern void BWGrid ( Widget w, Boolean _switch ); +extern void BWSwitchDashed ( Widget w ); +extern void BWDashed ( Widget w, Boolean _switch ); +extern void BWSwitchAxes ( Widget w ); +extern void BWAxes ( Widget w, Boolean _switch ); +extern void BWRedrawAxes( Widget w ); +extern void BWDrawLine ( Widget w, Position from_x, Position from_y, Position to_x, Position to_y, int value ); +extern void BWDrawRectangle ( Widget w, Position from_x, Position from_y, Position to_x, Position to_y, int value ); +extern void BWDrawFilledRectangle ( Widget w, Position from_x, Position from_y, Position to_x, Position to_y, int value ); +extern void BWDrawCircle ( Widget w, Position origin_x, Position origin_y, Position point_x, Position point_y, int value ); +extern void BWDrawFilledCircle ( Widget w, Position origin_x, Position origin_y, Position point_x, Position point_y, int value ); +extern void BWFloodFill ( Widget w, Position x, Position y, int value ); +extern void BWMark ( Widget w, Position from_x, Position from_y, Position to_x, Position to_y ); +extern void BWMarkAll ( Widget w ); +extern void BWUnmark ( Widget w ); +extern void BWSelect ( Widget w, Position from_x, Position from_y, Position to_x, Position to_y, Time btime ); +extern void BWStore ( Widget w ); +extern void BWStoreToBuffer ( Widget w ); +extern void BWUndo ( Widget w ); +extern void BWResize ( Widget w, Dimension width, Dimension height ); +extern void BWClip ( Widget w, Position x, Position y, Dimension width, Dimension height ); +extern void BWUnclip ( Widget w ); +extern void BWGrabSelection ( Widget w, Time btime ); +extern void BWRequestSelection ( Widget w, Time btime, Boolean wait ); +extern void BWSetChanged ( Widget w ); +extern Boolean BWQueryChanged ( Widget w ); +extern int BWReadFile ( Widget w, String filename, String basename ); +extern int BWWriteFile ( Widget w, String filename, String basename ); +extern String BWUnparseStatus ( Widget w ); +extern String BWGetFilename ( Widget w, String *str ); +extern String BWGetBasename ( Widget w, String *str ); +extern void BWChangeBasename ( Widget w, String str ); +extern void BWRemoveAllRequests ( Widget w ); +extern void BWClearHotSpot ( Widget w ); +extern Boolean BWQueryMarked ( Widget w ); +extern void BWFold ( Widget w ); +extern void BWClear ( Widget w ); +extern void BWSet ( Widget w ); +extern void BWInvert ( Widget w ); +extern void BWFlipHoriz ( Widget w ); +extern void BWFlipVert ( Widget w ); +extern void BWClearMarked ( Widget w ); +extern Boolean BWAddRequest ( Widget w, BWRequest name, Boolean trap, XtPointer call_data, Cardinal call_data_size ); +extern void BWChangeNotify ( Widget w ); +extern Pixmap BWGetUnzoomedPixmap ( Widget w ); +extern void BWClearChanged ( Widget w ); +extern Boolean BWQueryStored ( Widget w ); +extern Boolean BWQueryStippled ( Widget w ); +extern void BWSwitchStippled ( Widget w ); +extern void BWRedrawMark ( Widget w ); +extern Boolean BWQueryAxes ( Widget w ); +extern void BWHighlightAxes ( Widget w ); +extern String BWGetFilepath ( Widget w, String *str ); +extern void BWZoomOut ( Widget w ); +extern void BWZoomMarked ( Widget w ); +extern void BWRescale ( Widget w, Dimension width, Dimension height ); +extern Boolean BWQueryZooming ( Widget w ); +extern void BWRedrawGrid ( Widget w, Position x, Position y, Dimension width, Dimension height ); +extern void BWRedrawSquares ( Widget w, Position x, Position y, Dimension width, Dimension height ); +extern void BWRedrawHotSpot ( Widget w ); +extern void BWSetHotSpot(Widget w, Position x, Position y); +extern Boolean BWQueryGrid ( Widget w ); +extern Boolean BWQueryDashed ( Widget w ); +extern Boolean BWQueryProportional ( Widget w ); +extern void BWSwitchProportional ( Widget w ); +extern void BWDrawGrid ( Widget w, Position from_x, Position from_y, Position to_x, Position to_y ); +extern void BWChangeFilename ( Widget w, String str ); +extern Boolean BWParseSize ( String size, Dimension *width, Dimension *height ); +extern Boolean BWQuerySelection ( Widget w, Time btime ); +extern int BWStoreFile ( Widget w, String filename, String *basename ); +extern void BWNotify ( Widget w, XtActionProc proc ); +extern void BWTMark ( Widget w, XEvent *event, String *params, Cardinal *num_params ); +extern void BWTMarkAll ( Widget w, XEvent *event, String *params, Cardinal *num_params ); +extern void BWTUnmark ( Widget w, XEvent *event, String *params, Cardinal *num_params ); +extern void BWTPaste ( Widget w, XEvent *event, String *params, Cardinal *num_params ); +extern void BWDebug ( Widget w, XEvent *event, String *params, Cardinal *num_params ); +extern void BWAbort ( Widget w ); +extern Boolean BWRemoveRequest ( Widget w ); +extern void BWRedraw ( Widget w ); +extern Pixmap BWGetPixmap( Widget w ); + +#endif /* _Bitmap_h */ + + diff --git a/bitmap/BitmapP.h b/bitmap/BitmapP.h new file mode 100644 index 0000000..acd3f4a --- /dev/null +++ b/bitmap/BitmapP.h @@ -0,0 +1,211 @@ +/* $Xorg: BitmapP.h,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/BitmapP.h,v 1.3 2001/01/17 23:44:51 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + + + +#ifndef _BitmapP_h +#define _BitmapP_h + +#define bit int + +#include "Bitmap.h" +#include "Requests.h" +#include + +typedef struct { + Atom *targets; + Cardinal num_targets; + BWRequestRec *requests; + Cardinal num_requests; + BWRequestRec *request[100]; + +} BitmapClassPart; + +/* Full class record declaration */ +typedef struct _BitmapClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + BitmapClassPart bitmap_class; +} BitmapClassRec; + +extern BitmapClassRec bitmapClassRec; + +typedef void (*EngageProc)(Widget, BWStatus *, XtPointer, int *); +typedef void (*TerminateProc)( Widget, BWStatus *, XtPointer); +typedef void (*RemoveProc)(Widget w, BWStatus *, XtPointer); + +/**********/ +struct _BWRequestRec { + char *name; + int status_size; + EngageProc engage; + XtPointer engage_client_data; + TerminateProc terminate; + XtPointer terminate_client_data; + RemoveProc remove; + XtPointer remove_client_data; +} ; + +typedef struct { + Position from_x, from_y, + to_x, to_y; +} BWArea; + +typedef struct { + BWRequestRec *request; + XtPointer status; + Boolean trap; + XtPointer call_data; +} BWRequestStack; + +typedef struct { + XImage *image, *buffer; + XPoint hot; + Position at_x, at_y; + Boolean fold; + Boolean grid; + Boolean changed; +} BWZoom; + +typedef struct { + Boolean own; + Boolean limbo; +} BWSelection; + +/* New fields for the Bitmap widget record */ +typedef struct { + /* resources */ + Pixel foreground_pixel; + Pixel highlight_pixel; + Pixel frame_pixel; + Pixmap stipple; + Boolean stippled; + Boolean proportional; + Boolean grid; + Dimension grid_tolerance; + Pixmap dashes; + Boolean dashed; + Boolean axes; + Boolean resize; + Dimension margin, squareW, squareH, width, height; + XPoint hot; + int button_function[5]; + String filename, basename; + /* private state */ + String size; + Position horizOffset, vertOffset; + XtActionProc notify; + BWRequestStack *request_stack; + Cardinal cardinal, current; + /*Boolean trapping;*/ + XImage *image, *buffer, *storage; + XPoint buffer_hot; + BWArea mark, buffer_mark; + GC drawing_gc; + GC highlighting_gc; + GC frame_gc; + GC axes_gc; + Boolean changed; + Boolean fold; + Boolean zooming; + BWZoom zoom; + XtPointer *value; + char status[80]; + BWSelection selection; + Boolean stipple_change_expose_event; +} BitmapPart; + +/* Full instance record declaration */ +typedef struct _BitmapRec { + CorePart core; + SimplePart simple; + BitmapPart bitmap; +} BitmapRec; + +/* Private functions */ + +#define Length(width, height)\ + (((int)(width) + 7) / 8 * (height)) + +#define InBitmapX(BW, x)\ + (Position)(min((Position)((Dimension)(max(BW->bitmap.horizOffset,x) -\ + BW->bitmap.horizOffset) /\ + BW->bitmap.squareW), BW->bitmap.width - 1)) + +#define InBitmapY(BW, y)\ + (Position)(min((Position)((Dimension)(max(BW->bitmap.vertOffset, y) -\ + BW->bitmap.vertOffset) /\ + BW->bitmap.squareH), BW->bitmap.height - 1)) + +#define InWindowX(BW, x)\ + (Position) (BW->bitmap.horizOffset + ((x) * BW->bitmap.squareW)) + +#define InWindowY(BW, y)\ + (Position) (BW->bitmap.vertOffset + ((y) * BW->bitmap.squareH)) + +#define GetPixmap(BW, image)\ + XCreateBitmapFromData(XtDisplay(BW), XtWindow(BW),\ + image->data, image->width, image->height) + + +#define QuerySet(x, y) (((x) != NotSet) && ((y) != NotSet)) + +#define bit int + +#define QueryZero(x, y) (((x) == 0) || ((y) == 0)) + +#define Swap(x, y) {Position t; t = x; x = y; y = t;} + +#define QuerySwap(x, y) if(x > y) Swap(x, y) + +#define QueryInBitmap(BW, x, y)\ + (((x) >= 0) && ((x) < BW->bitmap.image->width) &&\ + ((y) >= 0) && ((y) < BW->bitmap.image->height)) + +#define Value(BW, button) (BW->bitmap.button_function[button - 1]) + +#define CreateCleanData(length) XtCalloc(length, sizeof(char)) +XImage *CreateBitmapImage(BitmapWidget BW, char *data, Dimension width, Dimension height); +void DestroyBitmapImage(XImage **image); +void TransferImageData(XImage *source, XImage *destination); +void CopyImageData(XImage *source, XImage *destination, + Position from_x, Position from_y, + Position to_x, Position to_y, + Position at_x, Position at_y); +XImage *GetImage(BitmapWidget BW, Pixmap pixmap); +XImage *ConvertToBitmapImage(BitmapWidget BW, XImage *image); +XImage *ScaleBitmapImage(BitmapWidget BW, XImage *src, + double scale_x, double scale_y); + +#endif /* _BitmapP_h */ diff --git a/bitmap/COPYING b/bitmap/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/bitmap/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/bitmap/CutPaste.c b/bitmap/CutPaste.c new file mode 100644 index 0000000..cf0ac78 --- /dev/null +++ b/bitmap/CutPaste.c @@ -0,0 +1,207 @@ +/* $Xorg: CutPaste.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: CutPaste.c,v 1.4 2001/12/14 20:00:40 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#include +#include +#include +#include "BitmapP.h" + +#include +#include + +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#define max(x, y) (((x) > (y)) ? (x) : (y)) + + +extern Boolean DEBUG; + +/***************************************************************************** + * Cut and Paste * + *****************************************************************************/ + +/* ARGSUSED */ +static Boolean +ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, + XtPointer *val_ret, unsigned long *length, int *format) +{ + XPointer *value = (XPointer *)val_ret; + BitmapWidget BW = (BitmapWidget) w; + Pixmap *pixmap; + char *data; + XImage *image; + Dimension width, height; + + switch (*target) { + +/* XA_TARGETS undefined ?!? + + case XA_TARGETS: + *type = XA_ATOM; + *value = (XPointer) bitmapClassRec.bitmap_class.targets; + *length = bitmapClassRec.bitmap_class.num_targets; + *format = 32; + return True; + +*/ + + case XA_BITMAP: + case XA_PIXMAP: + if (BWQueryMarked(w)) { + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + data = CreateCleanData(Length(width, height)); + image = CreateBitmapImage(BW, data, width, height); + CopyImageData(BW->bitmap.image, image, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 0, 0); + pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap)); + *pixmap = GetPixmap(BW, image); + DestroyBitmapImage(&image); + } + else if (BWQueryStored(w)) { + pixmap = (Pixmap *) XtMalloc(sizeof(Pixmap)); + *pixmap = GetPixmap(BW, BW->bitmap.storage); + } + else return False; + *type = XA_PIXMAP; + *value = (XPointer) pixmap; + *length = 1; + *format = 32; + return True; + + default: + return False; + } +} + +/* ARGSUSED */ +static void +LoseSelection(Widget w, Atom selection) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (DEBUG) + fprintf(stderr, "Lost Selection\n"); + BW->bitmap.selection.own = False; + + BWUnmark(w); +} + +/* ARGSUSED */ +static void +SelectionDone(Widget w, Atom *selection, Atom *target) +{ +/* Done Automatically ?!? + + BitmapWidget BW = (BitmapWidget) w; + + if (*target != XA_TARGETS) + XtFree(BW->bitmap.value); + +*/ +} + +void +BWGrabSelection(Widget w, Time btime) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.selection.own = XtOwnSelection(w, XA_PRIMARY, btime, + ConvertSelection, + (XtLoseSelectionProc)LoseSelection, + SelectionDone); + if (DEBUG && BW->bitmap.selection.own) + fprintf(stderr, "Own the selection\n"); +} + + +/* ARGSUSED */ +static void +SelectionCallback(Widget w, XtPointer cldat, Atom *selection, Atom *type, + XtPointer val, unsigned long *length, int *format) +{ + XPointer value = (XPointer)val; + BitmapWidget BW = (BitmapWidget) w; + Pixmap *pixmap; + + switch (*type) { + + case XA_BITMAP: + case XA_PIXMAP: + DestroyBitmapImage(&BW->bitmap.storage); + pixmap = (Pixmap *) value; + BW->bitmap.storage = GetImage(BW, *pixmap); + XFree((char *)pixmap); + break; + + default: + XtWarning(" selection request failed. BitmapWidget"); + break; + } + + BW->bitmap.selection.limbo = FALSE; +} + +void +BWRequestSelection(Widget w, Time btime, Boolean wait) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.selection.own) + BWStore(w); + else { + XtGetSelectionValue(w, XA_PRIMARY, XA_PIXMAP, + SelectionCallback, NULL, btime); + + BW->bitmap.selection.limbo = TRUE; + + if (wait) + while (BW->bitmap.selection.limbo) { + XEvent event; + XtNextEvent(&event); + XtDispatchEvent(&event); + } + } +} + +/* ARGSUSED */ +/* Returns true if there is a transferable selection */ +Boolean +BWQuerySelection(Widget w, Time btime) +{ +/* To be written. XA_TARGETS to be used. So far undefined ?!? */ + + return True; +} +/*****************************************************************************/ diff --git a/bitmap/Dashes b/bitmap/Dashes new file mode 100644 index 0000000..e81aa02 --- /dev/null +++ b/bitmap/Dashes @@ -0,0 +1,4 @@ +#define Dashes_width 2 +#define Dashes_height 2 +static char Dashes_bits[] = { + 0x01, 0x02}; diff --git a/bitmap/Dialog.c b/bitmap/Dialog.c new file mode 100644 index 0000000..03979f3 --- /dev/null +++ b/bitmap/Dialog.c @@ -0,0 +1,202 @@ +/* $Xorg: Dialog.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/Dialog.c,v 1.3 2001/01/17 23:44:51 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#include +#include +#include +#include +#include +#include + +#include "Dialog.h" + +#define min(x, y) (((x) < (y)) ? (x) : (y)) +#define max(x, y) (((x) > (y)) ? (x) : (y)) + + +static void SetDialogButton(Widget w, XEvent *event, + String *argv, Cardinal *argc); + +static XtActionsRec actions_table[] = { + {"set-dialog-button", SetDialogButton}, +}; + +static DialogButton dialog_buttons[] = { + {"yes", Yes}, + {"no", No}, + {"maybe", Maybe}, + {"okay", Okay}, + {"abort", Abort}, + {"cancel", Cancel}, + {"retry", Retry}, +}; + +static unsigned long selected; + +/* ARGSUSED */ +static void +SetSelected(Widget w, XtPointer clientData, XtPointer callData) /* ARGSUSED */ +{ + String name = (String)clientData; + int i; + + for (i = 0; i < XtNumber(dialog_buttons); i++) + if (!strcmp(dialog_buttons[i].name, name)) + selected |= dialog_buttons[i].flag; +} + +/* ARGSUSED */ +static void +SetDialogButton(Widget w, /* not used */ + XEvent *event, /* not used */ + String *argv, + Cardinal *argc) +{ + char button_name[80]; + XtPointer dummy = NULL; + int i; + + for (i = 0; i < *argc; i++) { + XmuCopyISOLatin1Lowered (button_name, argv[i]); + SetSelected(w, button_name, dummy); + } +} + +static Boolean firstTime = True; + +Dialog +CreateDialog(Widget top_widget, String name, unsigned long options) +{ + int i; + Dialog popup; + + popup = (Dialog) XtMalloc(sizeof(_Dialog)); + + if (popup) { + if (firstTime) { + XtAddActions(actions_table, XtNumber(actions_table)); + firstTime = False; + } + popup->top_widget = top_widget; + popup->shell_widget = XtCreatePopupShell(name, + transientShellWidgetClass, + top_widget, NULL, 0); + popup->dialog_widget = XtCreateManagedWidget("dialog", + dialogWidgetClass, + popup->shell_widget, + NULL, 0); + for (i = 0; i < XtNumber(dialog_buttons); i++) + if (options & dialog_buttons[i].flag) + XawDialogAddButton(popup->dialog_widget, + dialog_buttons[i].name, + SetSelected, dialog_buttons[i].name); + popup->options = options; + return popup; + } + else + return NULL; +} + +void +PopdownDialog(Dialog popup, String *answer) +{ + if (answer) + *answer = XawDialogGetValueString(popup->dialog_widget); + + XtPopdown(popup->shell_widget); +} + +unsigned long +PopupDialog(Dialog popup, String message, String suggestion, + String *answer, XtGrabKind grab) +{ + Position popup_x, popup_y, top_x, top_y; + Dimension popup_width, popup_height, top_width, top_height, border_width; + int n; + Arg wargs[4]; + + n = 0; + XtSetArg(wargs[n], XtNlabel, message); n++; + XtSetArg(wargs[n], XtNvalue, suggestion); n++; + XtSetValues(popup->dialog_widget, wargs, n); + + XtRealizeWidget(popup->shell_widget); + + n = 0; + XtSetArg(wargs[n], XtNx, &top_x); n++; + XtSetArg(wargs[n], XtNy, &top_y); n++; + XtSetArg(wargs[n], XtNwidth, &top_width); n++; + XtSetArg(wargs[n], XtNheight, &top_height); n++; + XtGetValues(popup->top_widget, wargs, n); + + n = 0; + XtSetArg(wargs[n], XtNwidth, &popup_width); n++; + XtSetArg(wargs[n], XtNheight, &popup_height); n++; + XtSetArg(wargs[n], XtNborderWidth, &border_width); n++; + XtGetValues(popup->shell_widget, wargs, n); + + popup_x = max(0, + min(top_x + ((Position)top_width - (Position)popup_width) / 2, + (Position)DisplayWidth(XtDisplay(popup->shell_widget), + DefaultScreen(XtDisplay(popup->shell_widget))) - + (Position)popup_width - 2 * (Position)border_width)); + popup_y = max(0, + min(top_y + ((Position)top_height - (Position)popup_height) / 2, + (Position)DisplayHeight(XtDisplay(popup->shell_widget), + DefaultScreen(XtDisplay(popup->shell_widget))) - + (Position)popup_height - 2 * (Position)border_width)); + n = 0; + XtSetArg(wargs[n], XtNx, popup_x); n++; + XtSetArg(wargs[n], XtNy, popup_y); n++; + XtSetValues(popup->shell_widget, wargs, n); + + selected = None; + + XtPopup(popup->shell_widget, grab); + XWarpPointer(XtDisplay(popup->shell_widget), + XtWindow(popup->top_widget), + XtWindow(popup->shell_widget), + 0, 0, top_width, top_height, + popup_width / 2, popup_height / 2); + + while ((selected & popup->options) == None) { + XEvent event; + XtNextEvent(&event); + XtDispatchEvent(&event); + } + + PopdownDialog(popup, answer); + + return (selected & popup->options); +} diff --git a/bitmap/Dialog.h b/bitmap/Dialog.h new file mode 100644 index 0000000..ff70789 --- /dev/null +++ b/bitmap/Dialog.h @@ -0,0 +1,57 @@ +/* $Xorg: Dialog.h,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/Dialog.h,v 1.3 2001/01/17 23:44:51 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + + +/*#define None 0*/ +#define Yes 1<<1 +#define No 1<<2 +#define Maybe 1<<3 /* :-) */ +#define Okay 1<<4 +#define Abort 1<<5 +#define Cancel 1<<6 +#define Retry 1<<7 + +typedef struct { + Widget top_widget, shell_widget, dialog_widget; + unsigned long options; +} _Dialog, *Dialog; + +typedef struct { + String name; + unsigned long flag; +} DialogButton; + +extern Dialog CreateDialog(Widget, String, unsigned long); +extern unsigned long PopupDialog(Dialog, String, String, String *, XtGrabKind); +extern void PopdownDialog(Dialog, String *); diff --git a/bitmap/Down b/bitmap/Down new file mode 100644 index 0000000..9790e27 --- /dev/null +++ b/bitmap/Down @@ -0,0 +1,13 @@ +#define Down_width 30 +#define Down_height 30 +static char Down_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x18, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0xf0, 0xb8, 0xe3, 0x01, 0xf0, 0x59, 0xf3, 0x01, + 0xb0, 0xbb, 0xbb, 0x01, 0x70, 0x5f, 0xdf, 0x01, 0xe0, 0xbe, 0xef, 0x00, + 0xc0, 0x5d, 0x77, 0x00, 0x80, 0xab, 0x3a, 0x00, 0x00, 0x57, 0x1d, 0x00, + 0x00, 0xae, 0x0e, 0x00, 0x00, 0x5c, 0x07, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00}; diff --git a/bitmap/Excl b/bitmap/Excl new file mode 100644 index 0000000..b172389 --- /dev/null +++ b/bitmap/Excl @@ -0,0 +1,17 @@ +#define Excl_width 40 +#define Excl_height 32 +static char Excl_bits[] = { + 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x00, + 0x00, 0x00, 0x80, 0xc3, 0x01, 0x00, 0x00, 0xc0, 0x99, 0x03, 0x00, 0x00, + 0xc0, 0x34, 0x03, 0x00, 0x00, 0xe0, 0x6a, 0x07, 0x00, 0x00, 0x70, 0x76, + 0x0e, 0x00, 0x00, 0x70, 0x6a, 0x0e, 0x00, 0x00, 0x38, 0x76, 0x1c, 0x00, + 0x00, 0x18, 0x6a, 0x18, 0x00, 0x00, 0x1c, 0x76, 0x38, 0x00, 0x00, 0x0e, + 0x6a, 0x70, 0x00, 0x00, 0x06, 0x76, 0x60, 0x00, 0x00, 0x07, 0x6a, 0xe0, + 0x00, 0x80, 0x03, 0x76, 0xc0, 0x01, 0x80, 0x03, 0x6a, 0xc0, 0x01, 0xc0, + 0x01, 0x76, 0x80, 0x03, 0xc0, 0x00, 0x6a, 0x00, 0x03, 0xe0, 0x00, 0x34, + 0x00, 0x07, 0x70, 0x00, 0x18, 0x00, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x0e, + 0x38, 0x00, 0x3c, 0x00, 0x1c, 0x1c, 0x00, 0x76, 0x00, 0x38, 0x1c, 0x00, + 0x6a, 0x00, 0x38, 0x0e, 0x00, 0x76, 0x00, 0x70, 0x0e, 0x00, 0x3c, 0x00, + 0x70, 0x1e, 0x00, 0x00, 0x00, 0x78, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xfc, + 0xff, 0xff, 0xff, 0x3f}; diff --git a/bitmap/FlipHoriz b/bitmap/FlipHoriz new file mode 100644 index 0000000..a72da3d --- /dev/null +++ b/bitmap/FlipHoriz @@ -0,0 +1,13 @@ +#define FlipHoriz_width 30 +#define FlipHoriz_height 30 +static char FlipHoriz_bits[] = { + 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1d, 0x00, + 0x00, 0x80, 0x3b, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xee, 0x00, + 0x00, 0x00, 0xdc, 0x01, 0xc0, 0xff, 0xbf, 0x03, 0xe0, 0xff, 0x5f, 0x07, + 0xb0, 0xaa, 0xaa, 0x0e, 0x58, 0x55, 0x55, 0x1d, 0xac, 0xaa, 0xaa, 0x0e, + 0xfe, 0xff, 0x5f, 0x07, 0xff, 0xff, 0xbf, 0x03, 0x6b, 0x00, 0xdc, 0x01, + 0x77, 0x00, 0xee, 0x00, 0x6b, 0x00, 0x77, 0x00, 0x77, 0x80, 0x3b, 0x00, + 0x6b, 0x80, 0x1d, 0x00, 0x77, 0x80, 0x0f, 0x00, 0x6b, 0x80, 0x07, 0x00, + 0xff, 0x1f, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xac, 0x06, 0x00, 0x00, + 0x58, 0x03, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, + 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/FlipVert b/bitmap/FlipVert new file mode 100644 index 0000000..f5df65b --- /dev/null +++ b/bitmap/FlipVert @@ -0,0 +1,13 @@ +#define FlipVert_width 30 +#define FlipVert_height 30 +static char FlipVert_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x75, 0x00, 0x00, + 0xe0, 0xea, 0x00, 0x00, 0x70, 0xd5, 0x01, 0x00, 0xb8, 0xaa, 0x03, 0x00, + 0xdc, 0x75, 0x07, 0x00, 0xee, 0xfb, 0x0e, 0x00, 0xf7, 0xf5, 0x1d, 0x00, + 0xbb, 0xbb, 0x1b, 0x00, 0x9f, 0x35, 0x1f, 0x00, 0x8f, 0x3b, 0x1e, 0x00, + 0x80, 0x35, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x35, 0x20, 0x08, + 0x80, 0x3b, 0x60, 0x0c, 0x80, 0x35, 0xe0, 0x0e, 0x80, 0x3b, 0xe0, 0x0f, + 0x80, 0x35, 0x60, 0x0d, 0x80, 0x3b, 0xe0, 0x0e, 0x80, 0xf5, 0x7f, 0x0d, + 0x00, 0xfb, 0xff, 0x06, 0x00, 0xb6, 0x6a, 0x03, 0x00, 0x7c, 0xf5, 0x01, + 0x00, 0xb8, 0xea, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xe0, 0x3f, 0x00}; diff --git a/bitmap/Fold b/bitmap/Fold new file mode 100644 index 0000000..ea59a19 --- /dev/null +++ b/bitmap/Fold @@ -0,0 +1,13 @@ +#define Fold_width 30 +#define Fold_height 30 +static char Fold_bits[] = { + 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x57, 0xf5, 0xab, 0x3a, + 0xab, 0xff, 0x7f, 0x35, 0xd7, 0x3f, 0xff, 0x3a, 0xab, 0x03, 0x70, 0x35, + 0x57, 0x07, 0xb8, 0x3a, 0xbb, 0x0e, 0x5c, 0x37, 0x7f, 0x1d, 0xae, 0x3f, + 0xfb, 0x3a, 0xd7, 0x37, 0xdf, 0xf5, 0xeb, 0x3e, 0x9b, 0xeb, 0x75, 0x36, + 0x1f, 0xd7, 0x3a, 0x3e, 0x1f, 0xae, 0x1d, 0x3e, 0x0e, 0xfc, 0x0e, 0x1c, + 0x0e, 0xdc, 0x0f, 0x1c, 0x1f, 0x6e, 0x1d, 0x3e, 0x1f, 0xd7, 0x3a, 0x3e, + 0x9b, 0xeb, 0x75, 0x36, 0xdf, 0xf5, 0xeb, 0x3e, 0xfb, 0x3a, 0xd7, 0x37, + 0x7f, 0x1d, 0xae, 0x3f, 0xbb, 0x0e, 0x5c, 0x37, 0x57, 0x07, 0xb8, 0x3a, + 0xab, 0x03, 0x70, 0x35, 0xd7, 0x3f, 0xff, 0x3a, 0xab, 0xff, 0x7f, 0x35, + 0x57, 0xf5, 0xab, 0x3a, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f}; diff --git a/bitmap/Graphics.c b/bitmap/Graphics.c new file mode 100644 index 0000000..991c753 --- /dev/null +++ b/bitmap/Graphics.c @@ -0,0 +1,1575 @@ +/* $Xorg: Graphics.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/Graphics.c,v 1.5 2001/01/17 23:44:51 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#include +#include +#include +#include "BitmapP.h" +#include "Bitmap.h" +#include "Requests.h" + +#include +#include + +#ifndef abs +#define abs(x) (((x) > 0) ? (x) : -(x)) +#endif +#define min(x, y) (((int)(x) < (int)(y)) ? (x) : (y)) +#define max(x, y) (((int)(x) > (int)(y)) ? (x) : (y)) +#ifndef rint +#define rint(x) floor(x + 0.5) +#endif + +/*****************************************************************************\ + * Graphics * +\*****************************************************************************/ + +#define GetBit(image, x, y)\ + ((bit)((*(image->data + (x) / 8 + (y) * image->bytes_per_line) &\ + (1 << ((x) % 8))) ? 1 : 0)) + +#if 0 +bit +BWGetBit(Widget w, Position x, Position y) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QueryInBitmap(BW, x, y)) + return GetBit(BW->bitmap.image, x, y); + else + return NotSet; +} +#endif + +#define InvertBit(image, x, y)\ + (*(image->data + (x) / 8 + (y) * image->bytes_per_line) ^=\ + (bit) (1 << ((x) % 8))) + + +#define SetBit(image, x, y)\ + (*(image->data + (x) / 8 + (y) * image->bytes_per_line) |=\ + (bit) (1 << ((x) % 8))) + +#define ClearBit(image, x, y)\ + (*(image->data + (x) / 8 + (y) * image->bytes_per_line) &=\ + (bit)~(1 << ((x) % 8))) + + +#define HighlightSquare(BW, x, y)\ + XFillRectangle(XtDisplay(BW), XtWindow(BW),\ + BW->bitmap.highlighting_gc,\ + InWindowX(BW, x), InWindowY(BW, y),\ + BW->bitmap.squareW, BW->bitmap.squareH) +/* +void +HighlightSquare(BitmapWidget BW, Position x, Position y) +{ + XFillRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.highlighting_gc, + InWindowX(BW, x), InWindowY(BW, y), + BW->bitmap.squareW, BW->bitmap.squareH); +} +*/ + +#define DrawSquare(BW, x, y)\ + XFillRectangle(XtDisplay(BW), XtWindow(BW),\ + BW->bitmap.drawing_gc,\ + InWindowX(BW, x), InWindowY(BW, y),\ + BW->bitmap.squareW, BW->bitmap.squareH) + +/* +void +DrawSquare(BitmapWidget BW, Position x, Position y) +{ + XFillRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.drawing_gc, + InWindowX(BW, x), InWindowY(BW, y), + BW->bitmap.squareW, BW->bitmap.squareH); +} +*/ + +#define InvertPoint(BW, x, y)\ + {InvertBit(BW->bitmap.image, x, y); DrawSquare(BW, x, y);} + +#define DrawPoint(BW, x, y, value)\ + if (GetBit(BW->bitmap.image, x, y) != value)\ + InvertPoint(BW, x, y) + +void +BWDrawPoint(Widget w, Position x, Position y, bit value) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QueryInBitmap(BW, x, y)) { + if (value == Highlight) + HighlightSquare(BW, x, y); + else + DrawPoint(BW, x, y, value); + } +} + +static XPoint * +HotSpotShape(BitmapWidget BW, Position x, Position y) +{ + static XPoint points[5]; + + points[0].x = InWindowX(BW, x); + points[0].y = InWindowY(BW, y + 1.0/2); + points[1].x = InWindowX(BW, x + 1.0/2); + points[1].y = InWindowY(BW, y + 1); + points[2].x = InWindowX(BW, x + 1); + points[2].y = InWindowY(BW, y + 1.0/2); + points[3].x = InWindowX(BW, x + 1.0/2); + points[3].y = InWindowY(BW, y); + points[4].x = InWindowX(BW, x); + points[4].y = InWindowY(BW, y + 1.0/2); + + return points; +} + +#define DrawHotSpot(BW, x, y)\ + XFillPolygon(XtDisplay(BW), XtWindow(BW), BW->bitmap.drawing_gc,\ + HotSpotShape(BW, x, y), 5, Convex, CoordModeOrigin) + +#define HighlightHotSpot(BW, x, y)\ + XFillPolygon(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc,\ + HotSpotShape(BW, x, y), 5, Convex, CoordModeOrigin) + +/* +XImage *CreateBitmapImage(); +void DestroyBitmapImage(); +*/ + +void +BWRedrawHotSpot(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) + DrawHotSpot(BW, BW->bitmap.hot.x, BW->bitmap.hot.y); +} + +void +BWClearHotSpot(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { + DrawHotSpot(BW, BW->bitmap.hot.x, BW->bitmap.hot.y); + BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet; + } +} + +void +BWDrawHotSpot(Widget w, Position x, Position y, int value) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QueryInBitmap(BW, x, y)) { + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) && + ((BW->bitmap.hot.x == x) && (BW->bitmap.hot.y == y))) { + if ((value == Clear) || (value == Invert)) { + BWClearHotSpot(w); + } + } + else + if ((value == Set) || (value == Invert)) { + BWClearHotSpot(w); + DrawHotSpot(BW, x, y); + BW->bitmap.hot.x = x; + BW->bitmap.hot.y = y; + } + + if (value == Highlight) + HighlightHotSpot(BW, x, y); + } +} + +void +BWSetHotSpot(Widget w, Position x, Position y) +{ + if (QuerySet(x, y)) + BWDrawHotSpot(w, x, y, Set); + else + BWClearHotSpot(w); +} + +/* high level procedures */ + +void +BWRedrawSquares(Widget w, + Position x, Position y, + Dimension width, Dimension height) +{ + BitmapWidget BW = (BitmapWidget) w; + Position from_x = InBitmapX(BW, x); + Position from_y = InBitmapY(BW, y); + Position to_x = InBitmapX(BW, x + width); + Position to_y = InBitmapY(BW, y + height); + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + from_x = max(0, from_x); + from_y = max(0, from_y); + to_x = min(BW->bitmap.image->width - 1, to_x); + to_y = min(BW->bitmap.image->height - 1, to_y); + + for (x = from_x; x <= to_x; x++) + for (y = from_y; y <= to_y; y++) + if (GetBit(BW->bitmap.image, x, y)) DrawSquare(BW, x, y); +} + +void +BWDrawGrid(Widget w, + Position from_x, Position from_y, + Position to_x, Position to_y) +{ + BitmapWidget BW = (BitmapWidget) w; + int i; + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + from_x = max(0, from_x); + from_y = max(0, from_y); + to_x = min(BW->bitmap.image->width - 1, to_x); + to_y = min(BW->bitmap.image->height - 1, to_y); + + for(i = from_x + (from_x == 0); i <= to_x; i++) + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, i), InWindowY(BW, from_y), + InWindowX(BW, i), InWindowY(BW, to_y + 1)); + + for(i = from_y + (from_y == 0); i <= to_y; i++) + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.frame_gc, + InWindowX(BW, from_x), InWindowY(BW, i), + InWindowX(BW, to_x + 1), InWindowY(BW, i)); +} + + +void +BWRedrawGrid(Widget w, + Position x, Position y, + Dimension width, Dimension height) +{ + BitmapWidget BW = (BitmapWidget) w; + Position from_x = InBitmapX(BW, x); + Position from_y = InBitmapY(BW, y); + Position to_x = InBitmapX(BW, x + width); + Position to_y = InBitmapY(BW, y + height); + + if (BW->bitmap.grid) + BWDrawGrid(w, from_x, from_y, to_x, to_y); +} + +void +BWDrawLine(Widget w, + Position from_x, Position from_y, + Position to_x, Position to_y, int value) +{ + Position i; + register double x, y; + double dx, dy, delta; + + dx = to_x - from_x; + dy = to_y - from_y; + x = from_x + 0.5; + y = from_y + 0.5; + delta = max(abs(dx), abs(dy)); + if (delta > 0) { + dx /= delta; + dy /= delta; + for(i = 0; i <= delta; i++) { + BWDrawPoint(w, (Position) x, (Position) y, value); + x += dx; + y += dy; + } + } + else + BWDrawPoint(w, from_x, from_y, value); +} + +void +BWBlindLine(Widget w, + Position from_x, Position from_y, + Position to_x, Position to_y, int value) +{ + Position i; + register double x, y; + double dx, dy, delta; + + dx = to_x - from_x; + dy = to_y - from_y; + x = from_x + 0.5; + y = from_y + 0.5; + delta = max(abs(dx), abs(dy)); + if (delta > 0) { + dx /= delta; + dy /= delta; + x += dx; + y += dy; + for(i = 1; i <= delta; i++) { + BWDrawPoint(w, (Position) x, (Position) y, value); + x += dx; + y += dy; + } + } + else + BWDrawPoint(w, from_x, from_y, value); +} + +void +BWDrawRectangle(Widget w, + Position from_x, Position from_y, + Position to_x, Position to_y, int value) +{ + register Position i; + Dimension delta, width, height; + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + + width = to_x - from_x; + height = to_y - from_y; + + delta = max(width, height); + + if (!QueryZero(width, height)) { + for (i = 0; (int)i < (int)delta; i++) { + if ((int)i < (int)width) { + BWDrawPoint(w, from_x + i, from_y, value); + BWDrawPoint(w, to_x - i, to_y, value); + } + if ((int)i < (int)height) { + BWDrawPoint(w, from_x, to_y - i, value); + BWDrawPoint(w, to_x, from_y + i, value); + } + } + } + else + BWDrawLine(w, + from_x, from_y, + to_x, to_y, value); +} + +void +BWDrawFilledRectangle(Widget w, + Position from_x, Position from_y, + Position to_x, Position to_y, int value) +{ + register Position x, y; + + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + + for (x = from_x; x <= to_x; x++) + for (y = from_y; y <= to_y; y++) + BWDrawPoint(w, x, y, value); +} + +void +BWDrawCircle(Widget w, + Position origin_x, Position origin_y, + Position point_x, Position point_y, int value) +{ + register Position i, delta; + Dimension dx, dy, half; + double radius; + + dx = abs(point_x - origin_x); + dy = abs(point_y - origin_y); + radius = sqrt((double) ((int)dx * (int)dx + (int)dy * (int)dy)); + if (radius < 1.0) { + BWDrawPoint(w, origin_x, origin_y, value); + } + else { + BWDrawPoint(w, origin_x - (Position) floor(radius), origin_y, value); + BWDrawPoint(w, origin_x + (Position) floor(radius), origin_y, value); + BWDrawPoint(w, origin_x, origin_y - (Position) floor(radius), value); + BWDrawPoint(w, origin_x, origin_y + (Position) floor(radius), value); + } + half = radius / sqrt(2.0); + for(i = 1; (int)i <= (int)half; i++) { + delta = sqrt(radius * radius - i * i); + BWDrawPoint(w, origin_x - delta, origin_y - i, value); + BWDrawPoint(w, origin_x - delta, origin_y + i, value); + BWDrawPoint(w, origin_x + delta, origin_y - i, value); + BWDrawPoint(w, origin_x + delta, origin_y + i, value); + if (i != delta) { + BWDrawPoint(w, origin_x - i, origin_y - delta, value); + BWDrawPoint(w, origin_x - i, origin_y + delta, value); + BWDrawPoint(w, origin_x + i, origin_y - delta, value); + BWDrawPoint(w, origin_x + i, origin_y + delta, value); + } + } +} + +void +BWDrawFilledCircle(Widget w, + Position origin_x, Position origin_y, + Position point_x, Position point_y, int value) +{ + register Position i, j, delta; + Dimension dx, dy; + double radius; + + dx = abs(point_x - origin_x); + dy = abs(point_y - origin_y); + radius = sqrt((double) ((int)dx * (int)dx + (int)dy * (int)dy)); + for(j = origin_x - (Position) floor(radius); + j <= origin_x + (Position) floor(radius); j++) + BWDrawPoint(w, j, origin_y, value); + for(i = 1; i <= (Position) floor(radius); i++) { + delta = sqrt(radius * radius - i * i); + for(j = origin_x - delta; j <= origin_x + delta; j++) { + BWDrawPoint(w, j, origin_y - i, value); + BWDrawPoint(w, j, origin_y + i, value); + } + } +} + +#define QueryFlood(BW, x, y, value)\ + ((GetBit(BW->bitmap.image, x, y) !=\ + (value & 1)) && QueryInBitmap(BW, x, y)) + +#define Flood(BW, x, y, value)\ + {if (value == Highlight) HighlightSquare(BW, x, y);\ + else InvertPoint(BW, x, y);} + +/* +static void +FloodLoop(BitmapWidget BW, Position x, Position y, int value) +{ + if (QueryFlood(BW, x, y, value)) { + Flood(BW, x, y, value); + FloodLoop(BW, x, y - 1, value); + FloodLoop(BW, x - 1, y, value); + FloodLoop(BW, x, y + 1, value); + FloodLoop(BW, x + 1, y, value); + } +} +*/ + +static void +FloodLoop(BitmapWidget BW, Position x, Position y, int value) +{ + Position save_x, save_y, x_left, x_right; + + if (QueryFlood(BW, x, y, value)) + Flood(BW, x, y, value) + + + save_x = x; + save_y = y; + + x++; + while (QueryFlood(BW, x, y, value)) { + Flood(BW, x, y, value); + x++; + } + x_right = --x; + + x = save_x; + x--; + while (QueryFlood(BW, x, y, value)) { + Flood(BW, x, y, value); + x--; + } + x_left = ++x; + + + x = x_left; + y = save_y; + y++; + + while (x <= x_right) { + Boolean flag = False; + Position x_enter; + + while (QueryFlood(BW, x, y, value) && (x <= x_right)) { + flag = True; + x++; + } + + if (flag) { + if ((x == x_right) && QueryFlood(BW, x, y, value)) + FloodLoop(BW, x, y, value); + else + FloodLoop(BW, x - 1, y, value); + } + + x_enter = x; + + while (!QueryFlood(BW, x, y, value) && (x < x_right)) + x++; + + if (x == x_enter) x++; + } + + x = x_left; + y = save_y; + y--; + + while (x <= x_right) { + Boolean flag = False; + Position x_enter; + + while (QueryFlood(BW, x, y, value) && (x <= x_right)) { + flag = True; + x++; + } + + if (flag) { + if ((x == x_right) && QueryFlood(BW, x, y, value)) + FloodLoop(BW, x, y, value); + else + FloodLoop(BW, x - 1, y, value); + } + + x_enter = x; + + while (!QueryFlood(BW, x, y, value) && (x < x_right)) + x++; + + if (x == x_enter) x++; + } +} + +void +BWFloodFill(Widget w, Position x, Position y, int value) +{ + BitmapWidget BW = (BitmapWidget) w; + int pixel; + + pixel = GetBit(BW->bitmap.image, x, y); + + if (value == Invert) + FloodLoop(BW, x, y, (pixel ? Clear : Set)); + else if (value != pixel) + FloodLoop(BW, x, y, value); +} + +#define QueryHotInMark(BW)\ + ((BW->bitmap.hot.x == max(BW->bitmap.mark.from_x,\ + min(BW->bitmap.hot.x, BW->bitmap.mark.to_x)))\ + &&\ + (BW->bitmap.hot.y == max(BW->bitmap.mark.from_y,\ + min(BW->bitmap.hot.y, BW->bitmap.mark.to_y)))) + +void +BWUp(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, up, down=0; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_y - from_y) == 0) + return; + + for(x = from_x; x <= to_x; x++) { + first = up = GetBit(BW->bitmap.image, x, to_y); + for(y = to_y - 1; y >= from_y; y--) { + down = GetBit(BW->bitmap.image, x, y); + if (up != down) + InvertPoint(BW, x, y); + up =down; + } + if(first != down) + InvertPoint(BW, x, to_y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.hot.x, + (BW->bitmap.hot.y - 1 + BW->bitmap.image->height) % + BW->bitmap.image->height); + +} + +void +BWDown(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, down, up=0; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_y - from_y) == 0) + return; + + for(x = from_x; x <= to_x; x++) { + first = down = GetBit(BW->bitmap.image, x, from_y); + for(y = from_y + 1; y <= to_y; y++) { + up = GetBit(BW->bitmap.image, x, y); + if (down != up) + InvertPoint(BW, x, y); + down = up; + } + if(first != up) + InvertPoint(BW, x, from_y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.hot.x, + (BW->bitmap.hot.y + 1) % BW->bitmap.image->height); +} + +void +BWLeft(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, left, right=0; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_x - from_x) == 0) + return; + + for(y = from_y; y <= to_y; y++) { + first = left = GetBit(BW->bitmap.image, to_x, y); + for(x = to_x - 1; x >= from_x; x--) { + right = GetBit(BW->bitmap.image, x, y); + if (left != right) + InvertPoint(BW, x, y); + left = right; + } + if(first != right) + InvertPoint(BW, to_x, y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + (BW->bitmap.hot.x - 1 + BW->bitmap.image->width) % + BW->bitmap.image->width, + BW->bitmap.hot.y); +} + +void +BWRight(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + bit first, right, left=0; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + if ((to_x - from_x) == 0) + return; + + for(y = from_y; y <= to_y; y++) { + first = right = GetBit(BW->bitmap.image, from_x, y); + for(x = from_x + 1; x <= to_x; x++) { + left = GetBit(BW->bitmap.image, x, y); + if (right != left) + InvertPoint(BW, x, y); + right = left; + } + if(first != left) + InvertPoint(BW, from_x, y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + (BW->bitmap.hot.x + 1) % BW->bitmap.image->width, + BW->bitmap.hot.y); +} + +/* void TransferImageData(); */ + +void +BWFold(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y, new_x, new_y; + Dimension horiz, vert; + char *storage_data; + XImage *storage; + + storage_data = CreateCleanData(Length(BW->bitmap.image->width, + BW->bitmap.image->height)); + + storage = CreateBitmapImage(BW, storage_data, + (Dimension) BW->bitmap.image->width, + (Dimension) BW->bitmap.image->height); + + TransferImageData(BW->bitmap.image, storage); + + BW->bitmap.fold ^= True; + horiz = (BW->bitmap.image->width + BW->bitmap.fold) / 2; + vert = (BW->bitmap.image->height + BW->bitmap.fold) / 2; + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) { + new_x = (int)(x + horiz) % (int)BW->bitmap.image->width; + new_y = (int)(y + vert) % (int)BW->bitmap.image->height; + if(GetBit(BW->bitmap.image, new_x, new_y) != + GetBit(storage, x, y)) + InvertPoint(BW, new_x, new_y); + } + + DestroyBitmapImage(&storage); + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) + BWSetHotSpot(w, + (Position) + ((int)(BW->bitmap.hot.x+horiz) + %(int)BW->bitmap.image->width), + (Position) + ((int)(BW->bitmap.hot.y+vert) + %(int)BW->bitmap.image->height) + ); +} + + +void +BWClear(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + int i, length; + + length = Length(BW->bitmap.image->width, BW->bitmap.image->height); + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) + if (GetBit(BW->bitmap.image, x, y)) + DrawSquare(BW, x, y); + + for (i = 0; i < length; i++) + BW->bitmap.image->data[i] = 0; + +} + +void +BWSet(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + int i, length; + + length = Length(BW->bitmap.image->width, BW->bitmap.image->height); + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) + if (!GetBit(BW->bitmap.image, x, y)) + DrawSquare(BW, x, y); + + for (i = 0; i < length; i++) + BW->bitmap.image->data[i] = (char)255; + +} + +void +BWRedraw(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + XClearArea(XtDisplay(BW), XtWindow(BW), + 0, 0, BW->core.width, BW->core.height, + True); +} + +void +BWInvert(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + int i, length; + + length = Length(BW->bitmap.image->width, BW->bitmap.image->height); + + XFillRectangle(XtDisplay(BW), XtWindow(BW), + BW->bitmap.drawing_gc, + InWindowX(BW, 0), InWindowY(BW, 0), + InWindowX(BW, BW->bitmap.image->width) - InWindowX(BW, 0), + InWindowY(BW, BW->bitmap.image->height) - InWindowY(BW, 0)); + + for (i = 0; i < length; i++) + BW->bitmap.image->data[i] ^= 255; +} + +void +BWFlipHoriz(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + Position from_x, from_y, to_x, to_y; + float half; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + half = (float) (to_y - from_y) / 2.0 + 0.5; + + if (half == 0.0) + return; + + for (x = from_x; x <= to_x; x++) + for (y = 0; y < half; y++) + if (GetBit(BW->bitmap.image, x, from_y + y) != + GetBit(BW->bitmap.image, x, to_y - y)) { + InvertPoint(BW, x, from_y + y); + InvertPoint(BW, x, to_y - y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.hot.x, + BW->bitmap.image->height - 1 - BW->bitmap.hot.y); +} + +void +BWFlipVert(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + register Position x, y; + Position from_x, from_y, to_x, to_y; + float half; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + half = (float) (to_x - from_x) / 2.0 + 0.5; + + if (half == 0) + return; + + for (y = from_y; y <= to_y; y++) + for (x = 0; x < half; x++) + if (GetBit(BW->bitmap.image, from_x + x, y) != + GetBit(BW->bitmap.image, to_x - x, y)) { + InvertPoint(BW, from_x + x, y); + InvertPoint(BW, to_x - x, y); + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) + BWSetHotSpot(w, + BW->bitmap.image->width - 1 - BW->bitmap.hot.x, + BW->bitmap.hot.y); +} + + +void +BWRotateRight(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y, delta, shift, tmp; + Position half_width, half_height; + XPoint hot; + bit quad1, quad2, quad3, quad4; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + half_width = floor((to_x - from_x) / 2.0 + 0.5); + half_height = floor((to_y - from_y ) / 2.0 + 0.5); + shift = min((Position)(to_x - from_x), (Position)(to_y - from_y )) % 2; + delta = min((Position) half_width, (Position) half_height) - shift; + + for (x = 0; x <= delta; x++) { + for (y = 1 - shift; y <= delta; y++) { + quad1 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + quad2 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + quad3 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + quad4 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + + if (quad1 != quad2) + InvertPoint(BW, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + if (quad2 != quad3) + InvertPoint(BW, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + if (quad3 != quad4) + InvertPoint(BW, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + if (quad4 != quad1) + InvertPoint(BW, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + } + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) { + hot.x = BW->bitmap.hot.x - half_width; + hot.y = BW->bitmap.hot.y - half_height; + if (hot.x >= 0) hot.x += shift; + if (hot.y >= 0) hot.y += shift; + tmp = hot.x; + hot.x = - hot.y; + hot.y = tmp; + if (hot.x > 0) hot.x -= shift; + if (hot.y > 0) hot.y -= shift; + hot.x += half_width; + hot.y += half_height; + if (QueryInBitmap(BW, hot.x, hot.y)) + BWSetHotSpot(w, hot.x, hot.y); + } + +} + +void +BWRotateLeft(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y,delta, shift, tmp; + Position half_width, half_height; + XPoint hot; + bit quad1, quad2, quad3, quad4; + Position from_x, from_y, to_x, to_y; + + if (BWQueryMarked(w)) { + from_x = BW->bitmap.mark.from_x; + from_y = BW->bitmap.mark.from_y; + to_x = BW->bitmap.mark.to_x; + to_y = BW->bitmap.mark.to_y; + } + else { + from_x = 0; + from_y = 0; + to_x = BW->bitmap.width - 1; + to_y = BW->bitmap.height - 1; + } + + half_width = floor((to_x - from_x) / 2.0 + 0.5); + half_height = floor((to_y - from_y ) / 2.0 + 0.5); + shift = min((Position)(to_x - from_x), (Position)(to_y - from_y )) % 2; + delta = min((Position) half_width, (Position) half_height) - shift; + + for (x = 0; x <= delta; x++) { + for (y = 1 - shift; y <= delta; y++) { + quad1 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + quad2 = GetBit(BW->bitmap.image, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + quad3 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + quad4 = GetBit(BW->bitmap.image, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + + if (quad1 != quad4) + InvertPoint(BW, + from_x + (Position)half_width + x, + from_y + (Position)half_height + y); + if (quad2 != quad1) + InvertPoint(BW, + from_x + (Position)half_width + y, + from_y + (Position)half_height - shift - x); + if (quad3 != quad2) + InvertPoint(BW, + from_x + (Position)half_width - shift - x, + from_y + (Position)half_height - shift - y); + if (quad4 != quad3) + InvertPoint(BW, + from_x + (Position)half_width - shift - y, + from_y + (Position)half_height + x); + } + } + + if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) + && + !BWQueryMarked(w)) { + hot.x = BW->bitmap.hot.x - half_width; + hot.y = BW->bitmap.hot.y - half_height; + if (hot.x >= 0) hot.x += shift; + if (hot.y >= 0) hot.y += shift; + tmp = hot.x; + hot.x = hot.y; + hot.y = - tmp; + if (hot.x > 0) hot.x -= shift; + if (hot.y > 0) hot.y -= shift; + hot.x += half_width; + hot.y += half_height; + if (QueryInBitmap(BW, hot.x, hot.y)) + BWSetHotSpot(w, hot.x, hot.y); + } +} + + +void +CopyImageData(XImage *source, XImage *destination, + Position from_x, Position from_y, + Position to_x, Position to_y, + Position at_x, Position at_y) +{ + Position x, y, delta_x, delta_y; + + delta_x = to_x - from_x + 1; + delta_y = to_y - from_y + 1; + + for (x = 0; x < delta_x; x++) + for (y = 0; y < delta_y; y++) + if (GetBit(source, from_x + x, from_y + y)) + SetBit(destination, at_x + x, at_y + y); + else + ClearBit(destination, at_x + x, at_y + y); +} + +XImage * +ConvertToBitmapImage(BitmapWidget BW, XImage *image) +{ + XImage *bitmap_image; + char *data; + Position x, y; + + data = CreateCleanData(Length(image->width, image->height)); + bitmap_image = CreateBitmapImage(BW, data, + (Dimension) image->width, + (Dimension) image->height); + + for (x = 0; x < min(image->width, bitmap_image->width); x++) + for (y = 0; y < min(image->height, bitmap_image->height); y++) + if ((XGetPixel(image, x, y) != 0) != GetBit(bitmap_image, x, y)) + InvertBit(bitmap_image, x, y); + + return bitmap_image; +} + +void +TransferImageData(XImage *source, XImage *destination) +{ + Position x, y; + + for (x = 0; x < min(source->width, destination->width); x++) + for (y = 0; y < min(source->height, destination->height); y++) + if (GetBit(source, x, y) != GetBit(destination, x, y)) + InvertBit(destination, x, y); +} + +void +BWStore(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + Dimension width, height; + char *storage_data; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + + DestroyBitmapImage(&BW->bitmap.storage); + + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + + storage_data = CreateCleanData(Length(width, height)); + + BW->bitmap.storage = CreateBitmapImage(BW, + storage_data, + width, height); + + CopyImageData(BW->bitmap.image, BW->bitmap.storage, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + 0, 0); + } +} + +void +BWClearMarked(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) + BWDrawFilledRectangle(w, + BW->bitmap.mark.from_x, + BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, + BW->bitmap.mark.to_y, + Clear); +} + + +void +BWDragMarked(Widget w, Position at_x, Position at_y) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) + BWDrawRectangle(w, + at_x, at_y, + at_x + BW->bitmap.mark.to_x - BW->bitmap.mark.from_x, + at_y + BW->bitmap.mark.to_y - BW->bitmap.mark.from_y, + Highlight); +} + +void +BWDragStored(Widget w, Position at_x, Position at_y) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.storage) + BWDrawRectangle(w, + at_x, at_y, + at_x + BW->bitmap.storage->width - 1, + at_y + BW->bitmap.storage->height - 1, + Highlight); +} + +static void +DrawImageData(BitmapWidget BW, XImage *image, + Position at_x, Position at_y, int value) +{ + Position x, y; + Boolean C, S, I, H; + bit A, B; + + C = value == Clear; + S = value == Set; + I = value == Invert; + H = value == Highlight; + + for (x = 0; x < image->width; x++) + for (y = 0; y < image->height; y++) { + A = GetBit(image, x, y); + B = GetBit(BW->bitmap.image, at_x + x, at_y + y); + if ((A & C) | ((A | B) & S) | ((A ^ B) & I) | ((A | B) & H)) + value = (A & H) ? Highlight : Set; + else + value = Clear; + BWDrawPoint((Widget) BW, + at_x + x, at_y + y, + value); + } +} + +void +BWRestore(Widget w, Position at_x, Position at_y, int value) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.storage) { + DrawImageData(BW, BW->bitmap.storage, at_x, at_y, value); + /*DestroyBitmapImage(&BW->bitmap.storage);*/ + } +} + +void +BWCopy(Widget w, Position at_x, Position at_y, int value) +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *storage; + char *storage_data; + Dimension width, height; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + + storage_data = CreateCleanData(Length(width, height)); + + storage = CreateBitmapImage(BW, storage_data, width, height); + + CopyImageData(BW->bitmap.image, storage, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + 0, 0); + + DrawImageData(BW, storage, at_x, at_y, value); + + DestroyBitmapImage(&storage); + } +} + +/* void BWMark(); */ + +void +BWMove(Widget w, Position at_x, Position at_y, int value) +{ + BitmapWidget BW = (BitmapWidget) w; + XImage *storage; + char *storage_data; + Dimension width, height; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + + width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; + height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; + + storage_data = CreateCleanData(Length(width, height)); + + storage = CreateBitmapImage(BW, storage_data, width, height); + + CopyImageData(BW->bitmap.image, storage, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + 0, 0); + + BWDrawFilledRectangle(w, + BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, + BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, + Clear); + + DrawImageData(BW, storage, at_x, at_y, value); + + BWMark(w, at_x, at_y, + at_x + BW->bitmap.mark.to_x - BW->bitmap.mark.from_x, + at_y + BW->bitmap.mark.to_y - BW->bitmap.mark.from_y); + + DestroyBitmapImage(&storage); + } +} + +void +BWRedrawMark(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) + XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.from_y), + InWindowX(BW, BW->bitmap.mark.to_x + 1) - + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.to_y + 1) - + InWindowY(BW, BW->bitmap.mark.from_y)); +} + +void +BWStoreToBuffer(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + memmove( BW->bitmap.buffer->data, BW->bitmap.image->data, + Length(BW->bitmap.image->width, BW->bitmap.image->height)); + + BW->bitmap.buffer_hot = BW->bitmap.hot; + BW->bitmap.buffer_mark = BW->bitmap.mark; +} + +void +BWUnmark(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BW->bitmap.buffer_mark = BW->bitmap.mark; + + if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { + XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.from_y), + InWindowX(BW, BW->bitmap.mark.to_x + 1) - + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.to_y + 1) - + InWindowY(BW, BW->bitmap.mark.from_y)); + + BW->bitmap.mark.from_x = BW->bitmap.mark.from_y = NotSet; + BW->bitmap.mark.to_x = BW->bitmap.mark.to_y = NotSet; + } +} + +void +BWMark(Widget w, Position from_x, Position from_y, + Position to_x, Position to_y) +{ + BitmapWidget BW = (BitmapWidget) w; + + BWUnmark(w); + + if (QuerySet(from_x, from_y)) { + if ((from_x == to_x) && (from_y == to_y)) { + /* + BW->bitmap.mark.from_x = 0; + BW->bitmap.mark.from_y = 0; + BW->bitmap.mark.to_x = BW->bitmap.image->width - 1; + BW->bitmap.mark.to_y = BW->bitmap.image->height - 1; + */ + return; + } + else { + QuerySwap(from_x, to_x); + QuerySwap(from_y, to_y); + from_x = max(0, from_x); + from_y = max(0, from_y); + to_x = min(BW->bitmap.image->width - 1, to_x); + to_y = min(BW->bitmap.image->height - 1, to_y); + + BW->bitmap.mark.from_x = from_x; + BW->bitmap.mark.from_y = from_y; + BW->bitmap.mark.to_x = to_x; + BW->bitmap.mark.to_y = to_y; + } + + XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.from_y), + InWindowX(BW, BW->bitmap.mark.to_x + 1) - + InWindowX(BW, BW->bitmap.mark.from_x), + InWindowY(BW, BW->bitmap.mark.to_y +1) - + InWindowY(BW, BW->bitmap.mark.from_y)); + } +} + +void +BWMarkAll(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + BWMark(w, 0, 0, BW->bitmap.image->width - 1, BW->bitmap.image->height - 1); +} + +void +BWUndo(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + Position x, y; + char *tmp_data; + XPoint tmp_hot; + BWArea tmp_mark; + + tmp_data = BW->bitmap.image->data; + BW->bitmap.image->data = BW->bitmap.buffer->data; + BW->bitmap.buffer->data = tmp_data; + + tmp_hot = BW->bitmap.hot; + tmp_mark = BW->bitmap.mark; + + for (x = 0; x < BW->bitmap.image->width; x++) + for (y = 0; y < BW->bitmap.image->height; y++) + if (GetBit(BW->bitmap.image, x, y) != GetBit(BW->bitmap.buffer, x, y)) + DrawSquare(BW, x, y); + + BWSetHotSpot(w, BW->bitmap.buffer_hot.x, BW->bitmap.buffer_hot.y); +/* + BWMark(w, BW->bitmap.buffer_mark.from_x, BW->bitmap.buffer_mark.from_y, + BW->bitmap.buffer_mark.to_x, BW->bitmap.buffer_mark.to_y); +*/ + BW->bitmap.buffer_hot = tmp_hot; + BW->bitmap.buffer_mark= tmp_mark; + +} + +void +BWHighlightAxes(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, 0), + InWindowY(BW, 0), + InWindowX(BW, BW->bitmap.width), + InWindowY(BW, BW->bitmap.height)); + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, BW->bitmap.width), + InWindowY(BW, 0), + InWindowX(BW, 0), + InWindowY(BW, BW->bitmap.height)); + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, 0), + InWindowY(BW, (float)BW->bitmap.height / 2.0), + InWindowX(BW, BW->bitmap.width), + InWindowY(BW, (float)BW->bitmap.height / 2.0)); + XDrawLine(XtDisplay(BW), XtWindow(BW), + BW->bitmap.axes_gc, + InWindowX(BW, (float)BW->bitmap.width / 2.0), + InWindowY(BW, 0), + InWindowX(BW, (float)BW->bitmap.width / 2.0), + InWindowY(BW, BW->bitmap.height)); +} + +typedef struct { + Position *x, *y; + Dimension *width, *height; +} Table; + +XImage * +ScaleBitmapImage(BitmapWidget BW, XImage *src, + double scale_x, double scale_y) +{ + char *data; + XImage *dst; + Table table; + Position x, y, w, h; + Dimension width, height; + bit pixel; + + width = max(rint(scale_x * src->width), 1); + height = max(rint(scale_y * src->height), 1); + + data = CreateCleanData(Length(width, height)); + dst = CreateBitmapImage(BW, data, width, height); + + /* + * It would be nice to check if width or height < 1.0 and + * average the skipped pixels. But, it is slow as it is now. + */ + if (scale_x == 1.0 && scale_y == 1.0) + memmove( dst->data, src->data, Length(width, height)); + else { + table.x = (Position *) XtMalloc(sizeof(Position) * src->width); + table.y = (Position *) XtMalloc(sizeof(Position) * src->height); + table.width = (Dimension *) XtMalloc(sizeof(Dimension) * src->width); + table.height = (Dimension *) XtMalloc(sizeof(Dimension) * src->height); + + for (x = 0; x < src->width; x++) { + table.x[x] = rint(scale_x * x); + table.width[x] = rint(scale_x * (x + 1)) - rint(scale_x * x); + } + for (y = 0; y < src->height; y++) { + table.y[y] = rint(scale_y * y); + table.height[y] = rint(scale_y * (y + 1)) - rint(scale_y * y); + } + + for (x = 0; x < src->width; x++) + for (y = 0; y < src->height; y++) { + pixel = GetBit(src, x, y); + for (w = 0; (int)w < (int)table.width[x]; w++) + for (h = 0; (int)h < (int)table.height[y]; h++) + if (pixel) SetBit(dst, + table.x[x] + w, + table.y[y] + h); + } + + XtFree((char *)table.x); + XtFree((char *)table.y); + XtFree((char *)table.width); + XtFree((char *)table.height); + } + + return (dst); +} + +/*****************************************************************************/ diff --git a/bitmap/Handlers.c b/bitmap/Handlers.c new file mode 100644 index 0000000..796f6fd --- /dev/null +++ b/bitmap/Handlers.c @@ -0,0 +1,678 @@ +/* $Xorg: Handlers.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: Handlers.c,v 1.4 2001/12/14 20:00:41 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#include +#include +#include "BitmapP.h" + +#include +#include + +#define min(x, y) (((int)(x) < (int)(y)) ? (x) : (y)) +#define max(x, y) (((int)(x) > (int)(y)) ? (x) : (y)) + +#include "Requests.h" + +extern Boolean DEBUG; + +/***************************************************************************** + * Handlers * + *****************************************************************************/ + +#define QueryInSquare(BW, x, y, square_x, square_y)\ + ((InBitmapX(BW, x) == (square_x)) &&\ + (InBitmapY(BW, y) == (square_y))) + + +static void +DragOnePointHandler(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *cont) /* ARGSUSED */ +{ + BWStatus *status = (BWStatus *)client_data; + BitmapWidget BW = (BitmapWidget) w; + + if (DEBUG) + fprintf(stderr, "D1PH "); + + switch (event->type) { + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->at_x, status->at_y)) { + BWStoreToBuffer(w); + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + status->success = status->draw ? True : False; + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, status->value); + } + break; + + case ButtonRelease: + if (QuerySet(status->at_x, status->at_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + status->success = status->draw ? True : False; + /* SUPPRESS 701 */ + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->at_x, status->at_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->at_x, status->at_y)) { + status->at_x = InBitmapX(BW, event->xmotion.x); + status->at_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, status->value); + } + } + break; + + } +} + +void +DragOnePointEngage(Widget w, + BWStatus *status, + XtPointer draw, + int *state) +{ + + status->at_x = NotSet; + status->at_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragOnePointHandler, (XtPointer)status); +} + +/* ARGSUSED */ +void +DragOnePointTerminate(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success) { + BWChangeNotify(w); + BWSetChanged(w); + } + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragOnePointHandler, (XtPointer)status); + +} + +void +OnePointHandler(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *cont) /* ARGSUSED */ +{ + BWStatus *status = (BWStatus *)client_data; + BitmapWidget BW = (BitmapWidget) w; + + if (DEBUG) + fprintf(stderr, "1PH "); + + switch (event->type) { + + case Expose: + if (QuerySet(status->at_x, status->at_y)) { + BWClip(w, event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + + BWUnclip(w); + } + break; + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->at_x, status->at_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + } + break; + + case ButtonRelease: + if (QuerySet(status->at_x, status->at_y)) { + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->at_x = InBitmapX(BW, event->xbutton.x); + status->at_y = InBitmapY(BW, event->xbutton.y); + status->success = True; + + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->at_x, status->at_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->at_x, status->at_y)) { + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + status->at_x = InBitmapX(BW, event->xmotion.x); + status->at_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + } + } + break; + } +} + +void +OnePointEngage(Widget w, + BWStatus *status, + XtPointer draw, + int *state) +{ + status->at_x = NotSet; + status->at_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); +} + +#if 0 +void +OnePointImmediateEngage(Widget w, + BWStatus *status, + XtPointer draw, + int *state) +{ + status->at_x = 0; + status->at_y = 0; + status->draw = draw; + status->success = False; + status->state = *state; + + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); +} +#endif + +void +OnePointTerminate(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success && draw) { + BWStoreToBuffer(w); + (*(DrawOnePointProc)draw)(w, + status->at_x, status->at_y, + status->value); + BWChangeNotify(w); + BWSetChanged(w); + } + else + if (QuerySet(status->at_x, status->at_y)) + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); +} + +void +OnePointTerminateTransparent(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success && draw) + (*(DrawOnePointProc)draw)(w, + status->at_x, status->at_y, + status->value); + else + if (QuerySet(status->at_x, status->at_y)) + if (status->draw) + (*(DrawOnePointProc)status->draw)(w, + status->at_x, status->at_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, OnePointHandler, (XtPointer)status); + +} + + +void +TwoPointsHandler(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *cont) /* ARGSUSED */ +{ + BitmapWidget BW = (BitmapWidget) w; + BWStatus *status = (BWStatus *)client_data; + if (DEBUG) + fprintf(stderr, "2PH "); + + switch (event->type) { + + case Expose: + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) { + BWClip(w, event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + BWUnclip(w); + } + break; + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->from_x, status->from_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->from_x = InBitmapX(BW, event->xbutton.x); + status->from_y = InBitmapY(BW, event->xbutton.y); + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + } + break; + + case ButtonRelease: + if (QuerySet(status->from_x, status->from_y)) { + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + status->success = True; + + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->from_x, status->from_y)) { + if (QuerySet(status->to_x, status->to_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->to_x, status->to_y)) { + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + status->to_x = InBitmapX(BW, event->xmotion.x); + status->to_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + } + } + else { + status->to_x = InBitmapX(BW, event->xmotion.x); + status->to_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + } + } + break; + } +} + +void +TwoPointsEngage(Widget w, + BWStatus *status, + XtPointer draw, + int *state) +{ + + status->from_x = NotSet; + status->from_y = NotSet; + status->to_x = NotSet; + status->to_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +void +TwoPointsTerminate(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success && draw) { + BWStoreToBuffer(w); + (*(DrawTwoPointProc)draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->value); + BWChangeNotify(w); + BWSetChanged(w); + } + else + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +void +TwoPointsTerminateTransparent(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success && draw) + (*(DrawTwoPointProc)draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->value); + else + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +void +TwoPointsTerminateTimed(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success && draw) + (*(DrawTwoPointProc)draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->btime); + else + if (QuerySet(status->from_x, status->from_y) && + QuerySet(status->to_x, status->to_y)) + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, Highlight); + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | + ExposureMask | PointerMotionMask, + FALSE, TwoPointsHandler, (XtPointer)status); +} + +/* ARGSUSED */ +void +Interface(Widget w, + BWStatus *status, + XtPointer action) +{ + (*(InterfaceProc)action)(w); +} + +void +Paste(Widget w, + Position at_x, + Position at_y, + int value) +{ + BitmapWidget BW = (BitmapWidget) w; + BWStatus *my_status; + BWRequest request; + + my_status = (BWStatus *) + BW->bitmap.request_stack[BW->bitmap.current].status; + + my_status->draw = NULL; + + request = (BWRequest) + BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data; + + BWTerminateRequest(w, FALSE); + + if ((at_x == max(BW->bitmap.mark.from_x, min(at_x, BW->bitmap.mark.to_x))) + && + (at_y == max(BW->bitmap.mark.from_y, min(at_y, BW->bitmap.mark.to_y)))) { + + BWStatus *status; + + if (DEBUG) + fprintf(stderr, "Prepaste request: %s\n", request); + + BWEngageRequest(w, request, False, (char *)&(my_status->state), sizeof(int)); + + status = (BWStatus *) + BW->bitmap.request_stack[BW->bitmap.current].status; + + status->at_x = at_x; + status->at_y = at_y; + status->value = value; + (*(DrawOnePointProc)status->draw) (w, at_x, at_y, Highlight); + } + else { + + BWStatus *status; + + BWEngageRequest(w, MarkRequest, False, (char *)&(my_status->state), sizeof(int)); + + status = (BWStatus *) + BW->bitmap.request_stack[BW->bitmap.current].status; + + status->from_x = status->to_x = at_x; + status->from_y = status->to_y = at_y; + status->value = value; + (*(DrawTwoPointProc)status->draw) (w, at_x, at_y, at_x, at_y, Highlight); + } +} + + +void +DragTwoPointsHandler(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *cont) /* ARGSUSED */ +{ + BitmapWidget BW = (BitmapWidget) w; + BWStatus *status = (BWStatus *)client_data; + + if (DEBUG) + fprintf(stderr, "D2PH "); + + switch (event->type) { + + case ButtonPress: + if (event->xbutton.state != status->state) return; + if (!QuerySet(status->from_x, status->from_y)) { + BWStoreToBuffer(w); + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->from_x = InBitmapX(BW, event->xbutton.x); + status->from_y = InBitmapY(BW, event->xbutton.y); + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + status->success = status->draw ? True : False; + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, status->value); + } + break; + + case ButtonRelease: + if (QuerySet(status->from_x, status->from_y)) { + status->value = Value(BW, event->xbutton.button); + status->btime = event->xbutton.time; + status->from_x = status->to_x; + status->from_y = status->to_y; + status->to_x = InBitmapX(BW, event->xbutton.x); + status->to_y = InBitmapY(BW, event->xbutton.y); + status->success = True; + + BWTerminateRequest(w, TRUE); + } + break; + + case MotionNotify: + if (QuerySet(status->from_x, status->from_y)) { + if (QuerySet(status->to_x, status->to_y)) { + if (!QueryInSquare(BW, event->xmotion.x, event->xmotion.y, + status->to_x, status->to_y)) { + status->from_x = status->to_x; + status->from_y = status->to_y; + status->to_x = InBitmapX(BW, event->xmotion.x); + status->to_y = InBitmapY(BW, event->xmotion.y); + if (status->draw) + (*(DrawTwoPointProc)status->draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, status->value); + } + } + } + break; + } +} + +void +DragTwoPointsEngage(Widget w, + BWStatus *status, + XtPointer draw, + int *state) +{ + + status->from_x = NotSet; + status->from_y = NotSet; + status->to_x = NotSet; + status->to_y = NotSet; + status->draw = draw; + status->success = False; + status->state = *state; + + XtAddEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragTwoPointsHandler, (XtPointer)status); +} + +void +DragTwoPointsTerminate(Widget w, + BWStatus *status, + XtPointer draw) +{ + + if (status->success && draw) { + if ((status->from_x != status->to_x) + || + (status->from_y != status->to_y)) + (*(DrawTwoPointProc)draw)(w, + status->from_x, status->from_y, + status->to_x, status->to_y, + status->value); + BWChangeNotify(w); + BWSetChanged(w); + } + + XtRemoveEventHandler(w, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + FALSE, DragTwoPointsHandler, (XtPointer)status); +} + +/*****************************************************************************/ diff --git a/bitmap/INSTALL b/bitmap/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/bitmap/Left b/bitmap/Left new file mode 100644 index 0000000..5c7f141 --- /dev/null +++ b/bitmap/Left @@ -0,0 +1,13 @@ +#define Left_width 30 +#define Left_height 30 +static char Left_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x1d, 0x00, 0x00, + 0xe0, 0x0e, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0xb8, 0xff, 0xff, 0x1f, + 0x5c, 0xff, 0xff, 0x0f, 0xae, 0xaa, 0xaa, 0x06, 0x57, 0x55, 0x55, 0x03, + 0xae, 0xaa, 0xaa, 0x06, 0x5c, 0xff, 0xff, 0x0f, 0xb8, 0xff, 0xff, 0x1f, + 0x70, 0x07, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0xc0, 0x1d, 0x00, 0x00, + 0x80, 0x3b, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, + 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/NEWS b/bitmap/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/bitmap/README b/bitmap/README new file mode 100644 index 0000000..e69de29 diff --git a/bitmap/ReqMach.c b/bitmap/ReqMach.c new file mode 100644 index 0000000..7d7328e --- /dev/null +++ b/bitmap/ReqMach.c @@ -0,0 +1,263 @@ +/* $Xorg: ReqMach.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: ReqMach.c,v 1.4 2001/12/14 20:00:41 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#include +#include +#include +#include +#include "BitmapP.h" + +#include +#include + +extern Boolean DEBUG; + +/*****************************************************************************\ + * Request Machine: stacks up and handles requests from application calls. * +\*****************************************************************************/ + +/* + * Searches for a request record of a request specified by its name. + * Returns a pointer to the record or NULL if the request was not found. + */ +static BWRequestRec * +FindRequest(BWRequest name) +{ + int i; + + for (i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++) + if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name)) + return &bitmapClassRec.bitmap_class.requests[i]; + + return NULL; +} + +/* + * Adds a request to the request stack and does proper initializations. + * Returns TRUE if the request was found and FALSE otherwise. + */ +Boolean +BWAddRequest(Widget w, BWRequest name, Boolean trap, + XtPointer call_data, Cardinal call_data_size) +{ + BitmapWidget BW = (BitmapWidget) w; + BWRequestRec *request; + + request = FindRequest(name); + if(request) { + if (DEBUG) + fprintf(stderr, "Adding... Cardinal: %d\n", BW->bitmap.cardinal + 1); + + BW->bitmap.request_stack = (BWRequestStack *) + XtRealloc((char *)BW->bitmap.request_stack, + (++BW->bitmap.cardinal + 1) * sizeof(BWRequestStack)); + + BW->bitmap.request_stack[BW->bitmap.cardinal].request = request; + BW->bitmap.request_stack[BW->bitmap.cardinal].status = + XtMalloc(request->status_size); + BW->bitmap.request_stack[BW->bitmap.cardinal].trap = trap; + BW->bitmap.request_stack[BW->bitmap.cardinal].call_data = + XtMalloc(call_data_size); + memmove( BW->bitmap.request_stack[BW->bitmap.cardinal].call_data, + call_data, + call_data_size); + + return True; + } + else { + XtWarning("bad request name. BitmapWidget"); + return False; + } +} + +/* + * Engages the request designated by the current parameter. + * Returnes TRUE if the request has an engage function and FALSE otherwise. + */ +static Boolean +Engage(BitmapWidget BW, Cardinal current) +{ + BW->bitmap.current = current; + + if (DEBUG) + fprintf(stderr, "Request: %s\n", + BW->bitmap.request_stack[current].request->name); + + if (BW->bitmap.request_stack[current].request->engage) { + (*BW->bitmap.request_stack[current].request->engage) + ((Widget) BW, + BW->bitmap.request_stack[current].status, + BW->bitmap.request_stack[current].request->engage_client_data, + BW->bitmap.request_stack[current].call_data); + return True; + } + else + return False; +} + +/* Boolean BWTerminateRequest(); + Boolean BWRemoveRequest(); */ + +/* + * Scans down the request stack removing all requests untill it finds + * one to be trapped. + */ +static void +TrappingLoop(BitmapWidget BW) +{ + + if (DEBUG) + fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current); + if ((BW->bitmap.current > 0) + && + (!BW->bitmap.request_stack[BW->bitmap.current--].trap)) { + BWRemoveRequest((Widget) BW); + TrappingLoop(BW); + } + else + if (BW->bitmap.cardinal > 0) { + if (DEBUG) + fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1); + if(!Engage(BW, ++BW->bitmap.current)) + BWTerminateRequest((Widget) BW, True); + } +} +/* + * Terimantes the current request and continues with next request if con = TRUE + * Returnes TRUE if there is any number of requests left on the stack. + */ +Boolean +BWTerminateRequest(Widget w, Boolean cont) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.current > 0) { + if (DEBUG) + fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current); + if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate) + (*BW->bitmap.request_stack[BW->bitmap.current].request->terminate) + (w, + BW->bitmap.request_stack[BW->bitmap.current].status, + BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data); + + if (cont) { + if (BW->bitmap.current == BW->bitmap.cardinal) + TrappingLoop(BW); + else { + if (DEBUG) + fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1); + if (!Engage(BW, ++BW->bitmap.current)) + BWTerminateRequest(w, True); + } + } + else + BW->bitmap.current = 0; + } + + return BW->bitmap.current; +} + +/* + * Simple interface to BWTerminateRequest that takes only a widget. + */ +void +BWAbort(Widget w) +{ + BWTerminateRequest(w, True); +} + +/* + * Removes the top request from the request stack. If the request is active + * it will terminate it. + * Returns TRUE if the number of requests left on the stack != 0. + */ +Boolean +BWRemoveRequest(Widget w) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BW->bitmap.cardinal > 0) { + if (DEBUG) + fprintf(stderr, "Removing... Cardinal: %d\n", BW->bitmap.cardinal); + if (BW->bitmap.current == BW->bitmap.cardinal) + BWTerminateRequest(w, False); + + if (BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove) + (*BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove) + (w, + BW->bitmap.request_stack[BW->bitmap.cardinal].status, + BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove_client_data); + + XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].status); + XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].call_data); + BW->bitmap.request_stack = (BWRequestStack *) + XtRealloc((char *)BW->bitmap.request_stack, + (--BW->bitmap.cardinal + 1) * sizeof(BWRequestStack)); + + return True; + } + else + return False; +} + +void +BWRemoveAllRequests(Widget w) +{ + while (BWRemoveRequest(w)) {/* removes all requests from the stack */} +} + +/* + * Adds the request to the stack and performs engaging ritual. + * Returns TRUE if the request was found, FALSE otherwise. + */ +Boolean +BWEngageRequest(Widget w, BWRequest name, Boolean trap, + XtPointer call_data, Cardinal call_data_size) +{ + BitmapWidget BW = (BitmapWidget) w; + + if (BWAddRequest(w, name, trap, call_data, call_data_size)) { + BWTerminateRequest(w, False); + if (DEBUG) + fprintf(stderr, "Engaging... Cardinal: %d\n", BW->bitmap.cardinal); + if (!Engage(BW, BW->bitmap.cardinal)) + BWTerminateRequest(w, True); + + return True; + } + else + return False; +} + +/************************* End of the Request Machine ************************/ diff --git a/bitmap/Requests.h b/bitmap/Requests.h new file mode 100644 index 0000000..abc6713 --- /dev/null +++ b/bitmap/Requests.h @@ -0,0 +1,87 @@ +/* $Xorg: Requests.h,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1989, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/Requests.h,v 1.4 2001/01/17 23:44:51 dawes Exp $ */ + +/* + * Author: Davor Matic, MIT X Consortium + */ + +#ifndef _Requests_h +#define _Requests_h + +typedef int (*DrawOnePointProc)(Widget, Position, Position, int); +typedef int (*DrawTwoPointProc)(Widget, Position, Position, + Position, Position, int); +typedef int (*InterfaceProc)(Widget); + +typedef struct { + Boolean success; + Position at_x, at_y; + Position from_x, from_y, + to_x, to_y; + XtPointer draw; + int value; + Time btime; + int state; +} BWStatus; + +extern void OnePointEngage ( Widget w, BWStatus *status, XtPointer draw, int *state ); +extern void OnePointTerminate ( Widget w, BWStatus *status, XtPointer draw ); +extern void OnePointTerminateTransparent ( Widget w, BWStatus *status, XtPointer draw ); +extern void DragOnePointEngage ( Widget w, BWStatus *status, XtPointer draw, int *state ); +extern void DragOnePointTerminate ( Widget w, BWStatus *status, XtPointer client_data ); +extern void TwoPointsEngage ( Widget w, BWStatus *status, XtPointer draw, int *state ); +extern void TwoPointsTerminate ( Widget w, BWStatus *status, XtPointer draw ); +extern void TwoPointsTerminateTransparent ( Widget w, BWStatus *status, XtPointer draw ); +extern void TwoPointsTerminateTimed ( Widget w, BWStatus *status, XtPointer draw ); +extern void DragTwoPointsEngage ( Widget w, BWStatus *status, XtPointer draw, int *state ); +extern void DragTwoPointsTerminate ( Widget w, BWStatus *status, XtPointer draw ); +extern void Interface ( Widget w, BWStatus *status, XtPointer action ); +extern void Paste ( Widget w, Position at_x, Position at_y, int value ); + +extern void BWDragMarked(Widget w, Position at_x, Position at_y); +extern void BWDragStored(Widget w, Position at_x, Position at_y); +extern void BWCopy(Widget w, Position at_x, Position at_y, int value); +extern void BWMove(Widget w, Position at_x, Position at_y, int value); +extern void BWRestore(Widget w, Position at_x, Position at_y, int value); +extern void BWDrawPoint(Widget w, Position x, Position y, bit value); +extern void BWBlindLine(Widget w, Position from_x, Position from_y, + Position to_x, Position to_y, int value); +extern void BWDrawHotSpot(Widget w, Position x, Position y, int value); +extern void BWZoomIn(Widget w, Position from_x, Position from_y, + Position to_x, Position to_y); + +extern void OnePointHandler(Widget w, XtPointer client_data, + XEvent *event, Boolean *cont); +extern void TwoPointsHandler(Widget w, XtPointer client_data, + XEvent *event, Boolean *cont); +extern void DragTwoPointsHandler(Widget w, XtPointer client_data, + XEvent *event, Boolean *cont); + +#endif /* _Requests_h */ diff --git a/bitmap/Right b/bitmap/Right new file mode 100644 index 0000000..d751a5f --- /dev/null +++ b/bitmap/Right @@ -0,0 +1,13 @@ +#define Right_width 30 +#define Right_height 30 +static char Right_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, + 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x1d, 0x00, 0x00, 0x80, 0x3b, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xdc, 0x01, + 0xff, 0xff, 0xbf, 0x03, 0xfe, 0xff, 0x5f, 0x07, 0xac, 0xaa, 0xaa, 0x0e, + 0x58, 0x55, 0x55, 0x1d, 0xac, 0xaa, 0xaa, 0x0e, 0xfe, 0xff, 0x5f, 0x07, + 0xff, 0xff, 0xbf, 0x03, 0x00, 0x00, 0xdc, 0x01, 0x00, 0x00, 0xee, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x80, 0x1d, 0x00, + 0x00, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/RotateLeft b/bitmap/RotateLeft new file mode 100644 index 0000000..c4d4b14 --- /dev/null +++ b/bitmap/RotateLeft @@ -0,0 +1,13 @@ +#define RotateLeft_width 30 +#define RotateLeft_height 30 +static char RotateLeft_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, + 0x00, 0x6e, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, + 0xc0, 0x1d, 0x00, 0x00, 0xe0, 0x0e, 0x00, 0x00, 0x70, 0xff, 0x0f, 0x00, + 0xb8, 0xfe, 0x1f, 0x00, 0x5c, 0x55, 0x35, 0x00, 0xae, 0xaa, 0x6a, 0x00, + 0x5c, 0x55, 0xd5, 0x00, 0xb8, 0xfe, 0xff, 0x01, 0x70, 0xff, 0xff, 0x03, + 0xe0, 0x0e, 0x58, 0x03, 0xc0, 0x1d, 0xb8, 0x03, 0x80, 0x3b, 0x58, 0x03, + 0x00, 0x77, 0xb8, 0x03, 0x00, 0x6e, 0x58, 0x03, 0x00, 0x7c, 0xb8, 0x03, + 0x00, 0x78, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, + 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x18, 0x03, + 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/RotateRight b/bitmap/RotateRight new file mode 100644 index 0000000..d54f3c7 --- /dev/null +++ b/bitmap/RotateRight @@ -0,0 +1,13 @@ +#define RotateRight_width 30 +#define RotateRight_height 30 +static char RotateRight_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, + 0x00, 0x80, 0x1d, 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0x00, 0x77, 0x00, + 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xdc, 0x01, 0x00, 0xfc, 0xbf, 0x03, + 0x00, 0xfe, 0x5f, 0x07, 0x00, 0xab, 0xaa, 0x0e, 0x80, 0x55, 0x55, 0x1d, + 0xc0, 0xaa, 0xaa, 0x0e, 0xe0, 0xff, 0x5f, 0x07, 0xf0, 0xff, 0xbf, 0x03, + 0xb0, 0x06, 0xdc, 0x01, 0x70, 0x07, 0xee, 0x00, 0xb0, 0x06, 0x77, 0x00, + 0x70, 0x87, 0x3b, 0x00, 0xb0, 0x86, 0x1d, 0x00, 0x70, 0x87, 0x0f, 0x00, + 0xb0, 0x86, 0x07, 0x00, 0x70, 0x07, 0x00, 0x00, 0xb0, 0x06, 0x00, 0x00, + 0xf0, 0x07, 0x00, 0x00, 0x70, 0x07, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, + 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/Stipple b/bitmap/Stipple new file mode 100644 index 0000000..d412e65 --- /dev/null +++ b/bitmap/Stipple @@ -0,0 +1,4 @@ +#define Stipple_width 2 +#define Stipple_height 2 +static char Stipple_bits[] = { + 0x01, 0x00}; diff --git a/bitmap/Term b/bitmap/Term new file mode 100644 index 0000000..19ec399 --- /dev/null +++ b/bitmap/Term @@ -0,0 +1,14 @@ +#define Term_width 32 +#define Term_height 32 +static char Term_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x04, 0x00, 0x00, 0x20, + 0xe4, 0xff, 0xff, 0x27, 0x14, 0x00, 0x00, 0x28, 0x14, 0x80, 0x01, 0x28, + 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, + 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x01, 0x28, 0x14, 0x80, 0x00, 0x28, + 0x14, 0x80, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, + 0x14, 0x00, 0x00, 0x28, 0x14, 0x80, 0x00, 0x28, 0x14, 0x00, 0x00, 0x28, + 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xf8, 0xff, 0xff, 0x1f, + 0xfe, 0xff, 0xff, 0x7f, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, + 0x02, 0x00, 0xc0, 0x5f, 0x02, 0x00, 0x00, 0x40, 0xfa, 0xff, 0xff, 0x5f, + 0xae, 0xaa, 0xaa, 0x6a, 0x56, 0x55, 0x55, 0x55, 0xab, 0xaa, 0xaa, 0xea, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/Up b/bitmap/Up new file mode 100644 index 0000000..423103f --- /dev/null +++ b/bitmap/Up @@ -0,0 +1,13 @@ +#define Up_width 30 +#define Up_height 30 +static char Up_bits[] = { + 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x5c, 0x07, 0x00, 0x00, 0xae, 0x0e, 0x00, + 0x00, 0x57, 0x1d, 0x00, 0x80, 0xab, 0x3a, 0x00, 0xc0, 0x5d, 0x77, 0x00, + 0xe0, 0xbe, 0xef, 0x00, 0x70, 0x5f, 0xdf, 0x01, 0xb0, 0xbb, 0xbb, 0x01, + 0xf0, 0x59, 0xf3, 0x01, 0xf0, 0xb8, 0xe3, 0x01, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, + 0x00, 0xb8, 0x03, 0x00, 0x00, 0x58, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x58, 0x03, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xb8, 0x03, 0x00, + 0x00, 0x18, 0x03, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/bitmap/atobm.c b/bitmap/atobm.c new file mode 100644 index 0000000..f63a956 --- /dev/null +++ b/bitmap/atobm.c @@ -0,0 +1,296 @@ +/* $Xorg: atobm.c,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ */ +/* + +Copyright 1988, 1993, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/bitmap/atobm.c,v 3.4 2001/07/25 15:05:12 dawes Exp $ */ + +/* + * atobm - ascii to bitmap filter + * Author: Jim Fulton, MIT X Consortium + */ + +#include +#include +#include +#include + +char *ProgramName; + +static void doit(FILE *fp, char *filename, char *chars, + int xhot, int yhot, char *name); + +static void +usage (void) +{ + fprintf (stderr, "usage: %s [-options ...] [filename]\n\n", + ProgramName); + fprintf (stderr, + "where options include:\n"); + fprintf (stderr, + " -chars cc chars to use for 0 and 1 bits, respectively\n"); + fprintf (stderr, + " -name variable name to use in bitmap file\n"); + fprintf (stderr, + " -xhot number x position of hotspot\n"); + fprintf (stderr, + " -yhot number y position of hotspot\n"); + fprintf (stderr, "\n"); + exit (1); +} + + +static char * +cify_name (char *name) +{ + int length = name ? strlen (name) : 0; + int i; + + for (i = 0; i < length; i++) { /* strncpy (result, begin, length); */ + char c = name[i]; + if (!((isascii(c) && isalnum(c)) || c == '_')) name[i] = '_'; + } + return name; +} + +static char * +StripName(char *name) +{ + char *begin = strrchr(name, '/'); + char *end, *result; + int length; + + begin = (begin ? begin+1 : name); + end = strchr(begin, '.'); /* change to strrchr to allow longer names */ + length = (end ? (end - begin) : strlen (begin)); + result = (char *) malloc (length + 1); + strncpy (result, begin, length); + result [length] = '\0'; + return (result); +} + +int +main (int argc, char *argv[]) +{ + int i; + int xhot = -1, yhot = -1; + char *filename = NULL; + char *chars = "-#"; + char *name = NULL; + FILE *fp; + + ProgramName = argv[0]; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (arg[0] == '-') { + switch (arg[1]) { + case '\0': + filename = NULL; + continue; + case 'c': + if (++i >= argc) usage (); + chars = argv[i]; + continue; + case 'n': + if (++i >= argc) usage (); + name = argv[i]; + continue; + case 'x': + if (++i >= argc) usage (); + xhot = atoi (argv[i]); + continue; + case 'y': + if (++i >= argc) usage (); + yhot = atoi (argv[i]); + continue; + default: + usage (); + } + } else { + filename = arg; + } + } + + if (strlen (chars) != 2) { + fprintf (stderr, + "%s: bad character list \"%s\", must have exactly 2 characters\n", + ProgramName, chars); + exit (1); + } + + if (filename) { + fp = fopen (filename, "r"); + if (!fp) { + fprintf (stderr, "%s: unable to open file \"%s\".\n", + ProgramName, filename); + exit (1); + } + } else { + fp = stdin; + } + + if (!name) name = filename ? StripName (filename) : ""; + cify_name (name); + doit (fp, filename, chars, xhot, yhot, name); + + if (filename) (void) fclose (fp); + exit (0); +} + + +static void +doit (FILE *fp, + char *filename, + char *chars, + int xhot, int yhot, + char *name) +{ + int i, j; + int last_character; + char buf[BUFSIZ]; + char *cp, *newline; + int width = 0, height = 0; + int len; + int removespace = (((isascii(chars[0]) && isspace(chars[0])) || + (isascii(chars[1]) && isspace(chars[1]))) ? 0 : 1); + int lineno = 0; + int bytes_per_scanline = 0; + struct _scan_list { + int allocated; + int used; + unsigned char *scanlines; + struct _scan_list *next; + } *head = NULL, *slist = NULL; + static unsigned char masktable[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + int padded = 0; + +#define NTOALLOC 16 +#define NewSList() \ + slist = (struct _scan_list *) calloc (1, sizeof *slist); \ + if (!slist) { \ + fprintf (stderr, "%s: unable to allocate scan list\n", \ + ProgramName); \ + return; \ + } \ + slist->allocated = NTOALLOC * bytes_per_scanline; \ + slist->scanlines = (unsigned char *) calloc(slist->allocated, 1); \ + if (!slist->scanlines) { \ + fprintf (stderr, "%s: unable to allocate char array\n", \ + ProgramName); \ + return; \ + } \ + slist->used = 0; \ + slist->next = NULL; + + while (1) { + buf[0] = '\0'; + lineno++; + if (fgets (buf, sizeof buf, fp) == NULL) break; + + cp = buf; + if (removespace) { + for (cp = buf; *cp && isascii(*cp) && isspace(*cp); cp++) ; + } + if (*cp == '\n' || !*cp) continue; /* empty line */ + + newline = strchr(cp, '\n'); + if (!newline) { + fprintf (stderr, "%s: line %d too long.\n", + ProgramName, lineno); + return; + } + + if (removespace) { + for (; --newline > cp && isascii(*newline) && isspace(*newline); ); + newline++; + } + + if (newline == cp + 1) continue; + + *newline = '\0'; + len = strlen (cp); + + if (width == 0) { + width = len; + padded = ((width & 7) != 0); + bytes_per_scanline = (len + 7) / 8; + NewSList (); + head = slist; + } else if (width != len) { + fprintf (stderr, + "%s: line %d is %d characters wide instead of %d\n", + ProgramName, lineno, len, width); + return; + } + + if (slist->used + 1 >= slist->allocated) { + struct _scan_list *old = slist; + NewSList (); + old->next = slist; + } + + /* okay, parse the line and stick values into the scanline array */ + for (i = 0; i < width; i++) { + int ind = (i & 7); + int on = 0; + + if (cp[i] == chars[1]) { + on = 1; + } else if (cp[i] != chars[0]) { + fprintf (stderr, "%s: bad character '%c' on line %d\n", + ProgramName, cp[i], lineno); + } + + if (on) slist->scanlines[slist->used] |= masktable[ind]; + if (ind == 7) slist->used++; + } + if (padded) slist->used++; + height++; + } + + printf ("#define %s_width %d\n", name, width); + printf ("#define %s_height %d\n", name, height); + if (xhot >= 0) printf ("#define %s_x_hot %d\n", name, xhot); + if (yhot >= 0) printf ("#define %s_y_hot %d\n", name, yhot); + printf ("\n"); + printf ("static unsigned char %s_bits[] = {\n", name); + + j = 0; + last_character = height * bytes_per_scanline - 1; + for (slist = head; slist; slist = slist->next) { + for (i = 0; i < slist->used; i++) { + printf (" 0x%02x", slist->scanlines[i]); + if (j != last_character) putchar (','); + if ((j % 12) == 11) putchar ('\n'); + j++; + } + } + printf (" };\n"); + return; +} diff --git a/bitmap/bitmap.icon b/bitmap/bitmap.icon new file mode 100644 index 0000000..53105c7 --- /dev/null +++ b/bitmap/bitmap.icon @@ -0,0 +1,14 @@ +#define bitmap_width 32 +#define bitmap_height 32 +static char bitmap_bits[] = { + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xf8, 0xfd, 0xff, 0xff, 0xfb, + 0x85, 0x08, 0x23, 0xfa, 0x95, 0x28, 0x23, 0xfa, 0x95, 0x29, 0x67, 0xfa, + 0xb5, 0x69, 0x67, 0xfa, 0xb5, 0x69, 0x67, 0xfa, 0xb5, 0x69, 0x67, 0xfa, + 0x85, 0x09, 0x67, 0xfa, 0xfd, 0xff, 0xff, 0xfb, 0x85, 0x18, 0x21, 0xfa, + 0x95, 0x18, 0x25, 0xfa, 0x95, 0x39, 0x65, 0xfa, 0xb5, 0x39, 0x6d, 0xfa, + 0xb5, 0x39, 0x6d, 0xfa, 0xb5, 0x39, 0x6d, 0xfa, 0x85, 0x39, 0x61, 0xfa, + 0xfd, 0xff, 0xff, 0xfb, 0x45, 0x18, 0xf9, 0xfb, 0x45, 0x19, 0xe1, 0xfb, + 0x4d, 0x39, 0xd3, 0xfb, 0x4d, 0x3b, 0xab, 0xfb, 0x4d, 0x3b, 0x57, 0xfb, + 0x4d, 0x3b, 0xaf, 0xfa, 0x4d, 0x38, 0x5f, 0xfd, 0xfd, 0xff, 0xbf, 0xfa, + 0x01, 0x00, 0x40, 0xf5, 0xff, 0xff, 0xff, 0xea, 0xff, 0xff, 0xff, 0xe5, + 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff}; diff --git a/bitmap/bitmap.man b/bitmap/bitmap.man new file mode 100644 index 0000000..afcf516 --- /dev/null +++ b/bitmap/bitmap.man @@ -0,0 +1,661 @@ +.\" $Xorg: bitmap.man,v 1.4 2001/02/09 02:05:28 xorgcvs Exp $ +.\" Copyright 1993, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/bitmap/bitmap.man,v 1.7 2001/12/14 20:00:41 dawes Exp $ +.\" +.TH BITMAP 1 __xorgversion__ +.SH NAME +bitmap, bmtoa, atobm \- bitmap editor and converter utilities for the X Window System +.SH SYNOPSIS +.B bitmap +[ +.I \-options +\&.\|.\|. ] [ +.I filename +] [ +.I basename +] +.sp +.B bmtoa +[ +.B \-chars +\&.\|.\|. ] [ +.I filename +] +.sp +.B atobm +[ +.B \-chars +.I cc +] [ +.B \-name +.I variable +] [ +.B \-xhot +.I number +] [ +.B \-yhot +.I number +] [ +.I filename +] +.SH DESCRIPTION +The \fIbitmap\fP program is a rudimentary tool for creating or editing +rectangular images made up of 1's and 0's. Bitmaps are used in X for +defining clipping regions, cursor shapes, icon shapes, and tile and +stipple patterns. +.PP +The \fIbmtoa\fP and \fIatobm\fP filters convert \fIbitmap\fP files (FILE +FORMAT) to and from ASCII strings. They are most commonly used to +quickly print out bitmaps and to generate versions for including in text. +.SH COMMAND LINE OPTIONS +\fIBitmap\fP supports the standard X Toolkit command line arguments +(see \fIX\fP(1)). The following additional arguments are supported as well. +.TP 4 +.B \-size\fI WIDTHxHEIGHT\fP +Specifies size of the grid in squares. +.TP 4 +.B \-sw\fI dimension\fP +Specifies the width of squares in pixels. +.TP 4 +.B \-sh\fI dimension\fP +Specifies the height of squares in pixels. +.TP 4 +.B \-gt\fI dimension\fP +Grid tolerance. If the square dimensions fall below the specified +value, grid will be automatically turned off. +.TP 4 +.B \-grid, +grid +./&.B \-grid\fI on/off\fP +Turns on or off the grid lines. +.TP 4 +.B \-axes, +axes +./&./&.B \-axes\fI on/off\fP +Turns on or off the major axes. +.TP 4 +.B \-dashed, +dashed +./&.B \-dashed\fI on/off\fP +Turns on or off dashing for the frame and grid lines. +.TP 4 +.B \-stippled, +stippled +./&.B \-stippled\fI on/off\fP +Turns on or off stippling of highlighted squares. +.TP 4 +.B \-proportional, +proportional\fI +./&.B \-proportional\fI on/off\fP +Turns proportional mode on or off. If proportional mode is on, +square width is equal to square height. If proportional mode is +off,\fI bitmap\fP will use the smaller square dimension, if they +were initially different. +.TP 4 +.B \-dashes\fI filename\fP +Specifies the bitmap to be used as a stipple for dashing. +.TP 4 +.B \-stipple\fI filename\fP +Specifies the bitmap to be used as a stipple for highlighting. +.TP 4 +.B \-hl\fI color\fP +Specifies the color used for highlighting. +.TP 4 +.B \-fr\fI color\fP +Specifies the color used for the frame and grid lines. +.TP 4 +.B filename +Specifies the bitmap to be initially loaded into the program. +If the file does not exist,\fI bitmap\fP will assume it is a new file. +.TP 4 +.B basename +Specifies the basename to be used in the C code output file. +If it is different than the basename in the working file,\fI bitmap\fP +will change it when saving the file. +.PP +\fIBmtoa\fP accepts the following option: +.TP 4 +.B \-chars \fIcc\fP +This option specifies the pair of characters to use in the string version +of the bitmap. The first character is used for 0 bits and the second character +is used for 1 bits. The default is to use dashes (\-) for 0's and sharp signs +(#) for 1's. +.PP +\fIAtobm\fP accepts the following options: +.TP 4 +.B \-chars \fIcc\fP +This option specifies the pair of characters to use when converting string +bitmaps into arrays of numbers. The first character represents a 0 bit and +the second character represents a 1 bit. The default is to use dashes (\-) +for 0's and sharp signs (#) for 1's. +.TP 4 +.B \-name \fIvariable\fP +This option specifies the variable name to be used when writing out the +bitmap file. The default is to use the basename of the \fIfilename\fP command +line argument or leave it blank if the standard input is read. +.TP 4 +.B \-xhot \fInumber\fP +This option specifies the X coordinate of the hotspot. Only positive values +are allowed. By default, no hotspot information is included. +.TP 4 +.B \-yhot \fInumber\fP +This option specifies the Y coordinate of the hotspot. Only positive values +are allowed. By default, no hotspot information is included. +.SH USAGE +\fIBitmap\fP displays grid in which each square represents a single +bit in the picture being edited. Actual size of the bitmap image, as +it would appear normaly and inverted, can be obtained by pressing\fB +Meta-I\fP key. You are free to move the image popup out of the way to +continue editing. Pressing the left mouse button in the popup window +or\fB Meta-I\fP again will remove the real size bitmap image. +.PP +If the bitmap is to be used for defining a cursor, one of the squares +in the images may be designated as the hot spot. This determines +where the cursor is actually pointing. For cursors with sharp tips +(such as arrows or fingers), this is usually at the end of the tip; +for symmetric cursors (such as crosses or bullseyes), this is usually +at the center. +.PP +Bitmaps are stored as small C code fragments suitable for including in +applications. They provide an array of bits as well as symbolic +constants giving the width, height, and hot spot (if specified) that +may be used in creating cursors, icons, and tiles. +.SH EDITING +To edit a bitmap image simply click on one of the buttons with drawing +commands (\fBPoint, Curve, Line, Rectangle,\fP etc.) and move the +pointer into the bitmap grid window. Press one of the buttons on your +mouse and the appropriate action will take place. You can either set, +clear or invert the gird squares. Setting a grid square corresponds +to setting a bit in the bitmap image to 1. Clearing a grid square +corresponds to setting a bit in the bitmap image to 0. Inverting a +grid square corresponds to changing a bit in the bitmap image from 0 to +1 or 1 to 0, depending what its previous state was. The +default behavior of mouse buttons is as specified below. +.sp +.nf + MouseButton1 Set + MouseButton2 Invert + MouseButton3 Clear + MouseButton4 Clear + MouseButton5 Clear +.fi +.sp +This default behavior can be changed by setting the button function +resources. An example is provided below. +.sp +.nf + bitmap*button1Function: Set + bitmap*button2Function: Clear + bitmap*button3Function: Invert + etc. +.fi +.sp +The button function applies to all drawing commands, including copying, +moving and pasting, flood filling and setting the hot spot. +.SH DRAWING COMMANDS +Here is the list of drawing commands accessible through the +buttons at the left side of the application's window. Some commands +can be aborted by pressing A inside the bitmap window, allowing the +user to select different guiding points where applicable. +.TP 4 +.B Clear +This command clears all bits in the bitmap image. The grid squares +will be set to the background color. Pressing C inside the bitmap +window has the same effect. +.TP 4 +.B Set +This command sets all bits in the bitmap image. The grid squares +will be set to the foreground color. Pressing S inside the bitmap +window has the same effect. +.TP 4 +.B Invert +This command inverts all bits in the bitmap image. The grid squares +will be inverted appropriately. Pressing I inside the bitmap window +has the same effect. +.TP 4 +.B Mark +This command is used to mark an area of the grid by dragging out a +rectangular shape in the highlighting color. Once the area is marked, +it can be operated on by a number of commands (see \fBUp, Down, Left, +Right, Rotate, Flip, Cut,\fP etc.) Only one marked area can be present +at any time. If you attempt to mark another area, the old mark will +vanish. The same effect can be achieved by pressing\fB +Shift-MouseButton1\fP and dragging out a rectangle in the grid window. +Pressing\fB Shift-MouseButton2\fP will mark the entire grid area. +.TP 4 +.B Unmark +This command will cause the marked area to vanish. The same effect can +be achieved by pressing\fB Shift-MouseButton3\fP. +.TP 4 +.B Copy +This command is used to copy an area of the grid from one location to +another. If there is no marked grid area displayed,\fB Copy\fP +behaves just like\fB Mark\fP described above. Once there is a marked +grid area displayed in the highlighting color, this command has two +alternative behaviors. If you click a mouse button inside the marked +area, you will be able to drag the rectangle that represents the +marked area to the desired location. After you release the mouse +button, the area will be copied. If you click outside the marked +area,\fB Copy\fP will assume that you wish to mark a different region of +the bitmap image, thus it will behave like\fB Mark\fP again. +.TP 4 +.B Move +This command is used to move an area of the grid from one location to +another. Its behavior resembles the behavior of\fB Copy\fP command, +except that the marked area will be moved instead of copied. +.TP 4 +.B Flip Horizontally +This command will flip the bitmap image with respect to the horizontal axes. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing H inside the bitmap window has the +same effect. +.TP 4 +.B Up +This command moves the bitmap image one pixel up. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing UpArrow inside the bitmap window has the +same effect. +.TP 4 +.B Flip Vertically +This command will flip the bitmap image with respect to the vertical axes. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing V inside the bitmap window has the +same effect. +.TP 4 +.B Left +This command moves the bitmap image one pixel to the left. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing LeftArrow inside the bitmap window has +the same effect. +.TP 4 +.B Fold +This command will fold the bitmap image so that the opposite corners +become adjacent. This is useful when creating bitmap images for +tiling. Pressing F inside the bitmap window has the same effect. +.TP 4 +.B Right +This command moves the bitmap image one pixel to the right. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing RightArrow inside the bitmap window +has the same effect. +.TP 4 +.B Rotate Left +This command rotates the bitmap image 90 degrees to the left (counter +clockwise.) +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing L inside the bitmap window has the +same effect. +.TP 4 +.B Down +This command moves the bitmap image one pixel down. +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing DownArrow inside the bitmap window +has the same effect. +.TP 4 +.B Rotate Right +This command rotates the bitmap image 90 degrees to the right (clockwise.) +If a marked area of the grid is highlighted, it will operate only +inside the marked area. Pressing R inside the bitmap window has the +same effect. +.TP 4 +.B Point +This command will change the grid squares underneath the mouse pointer if +a mouse button is being pressed down. If you drag the mouse button +continuously, the line may not be continuous, depending on the speed of your +system and frequency of mouse motion events. +.TP 4 +.B Curve +This command will change the grid squares underneath the mouse pointer if +a mouse button is being pressed down. If you drag the mouse button +continuously, it will make sure that the line is continuous. If your system +is slow or\fI bitmap\fP receives very few mouse motion events, it might +behave quite strangely. +.TP 4 +.B Line +This command will change the gird squares in a line between two squares. +Once you press a mouse button in the grid window,\fI bitmap\fP will +highlight the line from the square where the mouse button was initially +pressed to the square where the mouse pointer is located. By releasing the +mouse button you will cause the change to take effect, and the highlighted +line will disappear. +.TP 4 +.B Rectangle +This command will change the gird squares in a rectangle between two squares. +Once you press a mouse button in the grid window,\fI bitmap\fP will +highlight the rectangle from the square where the mouse button was initially +pressed to the square where the mouse pointer is located. By releasing the +mouse button you will cause the change to take effect, and the highlighted +rectangle will disappear. +.TP 4 +.B Filled Rectangle +This command is identical to\fB Rectangle\fP, except at the end the +rectangle will be filled rather than outlined. +.TP 4 +.B Circle +This command will change the gird squares in a circle between two squares. +Once you press a mouse button in the grid window,\fI bitmap\fP will +highlight the circle from the square where the mouse button was initially +pressed to the square where the mouse pointer is located. By releasing the +mouse button you will cause the change to take effect, and the highlighted +circle will disappear. +.TP 4 +.B Filled Circle +This command is identical to\fB Circle\fP, except at the end the +circle will be filled rather than outlined. +.TP 4 +.B Flood Fill +This command will flood fill the connected area underneath the mouse +pointer when you click on the desired square. Diagonally adjacent +squares are not considered to be connected. +.TP 4 +.B Set Hot Spot +This command designates one square in the grid as the hot spot if this +bitmap image is to be used for defining a cursor. Pressing a mouse button +in the desired square will cause a diamond shape to be displayed. +.TP 4 +.B Clear Hot Spot +This command removes any designated hot spot from the bitmap image. +.TP 4 +.B Undo +This command will undo the last executed command. It has depth one, +that is, pressing\fB Undo\fP after\fB Undo\fP will undo itself. +.SH FILE MENU +The File menu commands can be accessed by pressing the File button and +selecting the appropriate menu entry, or by pressing Ctrl key with +another key. These commands deal with files and global bitmap +parameters, such as size, basename, filename etc. +.TP 4 +.B New +This command will clear the editing area and prompt for the name of +the new file to be edited. It will not load in the new file. +.TP 4 +.B Load +This command is used to load a new bitmap file into the bitmap editor. +If the current image has not been saved, user will be asked whether to +save or ignore the changes. The editor can edit only one file at a +time. If you need interactive editing, run a number of editors and +use cut and paste mechanism as described below. +.TP 4 +.B Insert +This command is used to insert a bitmap file into the image +being currently edited. After being prompted for the filename, +click inside the grid window and drag the outlined rectangle to the +location where you want to insert the new file. +.TP 4 +.B Save +This command will save the bitmap image. It will not prompt for the +filename unless it is said to be . If you leave the filename +undesignated or \-, the output will be piped to stdout. +.TP 4 +.B Save As +This command will save the bitmap image after prompting for a new +filename. It should be used if you want to change the filename. +.TP 4 +.B Resize +This command is used to resize the editing area to the new number of +pixels. The size should be entered in the WIDTHxHEIGHT format. The +information in the image being edited will not be lost unless the new +size is smaller that the current image size. The editor was not +designed to edit huge files. +.TP 4 +.B Rescale +This command is used to rescale the editing area to the new width and +height. The size should be entered in the WIDTHxHEIGHT format. It will +not do antialiasing and information will be lost if you rescale to the +smaller sizes. Feel free to add you own algorithms for better rescaling. +.TP 4 +.B Filename +This command is used to change the filename without changing the basename +nor saving the file. If you specify \- for a filename, the output will +be piped to stdout. +.TP 4 +.B Basename +This command is used to change the basename, if a different one from +the specified filename is desired. +.TP 4 +.B Quit +\This command will terminate the bitmap application. If the file was +not saved, user will be prompted and asked whether to save the image +or not. This command is preferred over killing the process. +.SH EDIT MENU +The Edit menu commands can be accessed by pressing the Edit button and +selecting the appropriate menu entry, or by pressing Meta key with +another key. These commands deal with editing facilities such as +grid, axes, zooming, cut and paste, etc. +.TP 4 +.B Image +This command will display the image being edited and its inverse in its +actual size in a separate window. The window can be moved away to continue +with editing. Pressing the left mouse button in the image window will +cause it to disappear from the screen. +.TP 4 +.B Grid +This command controls the grid in the editing area. If the grid spacing +is below the value specified by gridTolerance resource (8 by default), +the grid will be automatically turned off. It can be enforced by explicitly +activating this command. +.TP 4 +.B Dashed +This command controls the stipple for drawing the grid lines. The stipple +specified by dashes resource can be turned on or off by activating this +command. +.TP 4 +.B Axes +This command controls the highlighting of the main axes of the image +being edited. The actual lines are not part of the image. They are +provided to aid user when constructing symmetrical images, or whenever +having the main axes highlighted helps your editing. +.TP 4 +.B Stippled +This command controls the stippling of the highlighted areas of the +bitmap image. The stipple specified by stipple resource can be turned on +or off by activating this command. +.TP 4 +.B Proportional +This command controls the proportional mode. If the proportional mode +is on, width and height of all image squares are forced to be equal, +regardless of the proportions of the bitmap window. +.TP 4 +.B Zoom +This command controls the zoom mode. If there is a marked area of the +image already displayed, bitmap will automatically zoom into it. Otherwise, +user will have to highlight an area to be edited in the zoom mode and +bitmap will automatically switch into it. One can use all the editing +commands and other utilities in the zoom mode. When you zoom out, undo +command will undo the whole zoom session. +.TP 4 +.B Cut +This commands cuts the contents of the highlighted image area into the +internal cut and paste buffer. +.TP 4 +.B Copy +This command copies the contents of the highlighted image area into the +internal cut and paste buffer. +.TP 4 +.B Paste +This command will check if there are any other bitmap applications with +a highlighted image area, or if there is something in the internal cut +and paste buffer and copy it to the image. To place the copied image, +click in the editing window and drag the outlined image to the position +where you want to place i, and then release the button. +.SH CUT AND PASTE +Bitmap supports two cut and paste mechanisms; the internal cut and +paste and the global X selection cut and paste. The internal cut and +paste is used when executing copy and move drawing commands and also +cut and copy commands from the edit menu. The global X selection cut +and paste is used whenever there is a highlighted area of a bitmap +image displayed anywhere on the screen. To copy a part of image from +another bitmap editor simply highlight the desired area by using the +Mark command or pressing the shift key and dragging the area with the +left mouse button. When the selected area becomes highlighted, any +other applications (such as xterm, etc.) that use primary selection +will discard their selection values and unhighlight the appropriate +information. Now, use the Paste command for the Edit menu or control +mouse button to copy the selected part of image into another (or the +same) bitmap application. If you attempt to do this without a visible +highlighted image area, the bitmap will fall back to the internal cut +and paste buffer and paste whatever was there stored at the moment. +.SH WIDGETS +Below is the widget structure of the \fIbitmap\fP +application. Indentation indicates hierarchical structure. The +widget class name is given first, followed by the widget instance +name. All widgets except the bitmap widget are from the standard +Athena widget set. +.sp +.nf + Bitmap bitmap + TransientShell image + Box box + Label normalImage + Label invertedImage + TransientShell input + Dialog dialog + Command okay + Command cancel + TransientShell error + Dialog dialog + Command abort + Command retry + TransientShell qsave + Dialog dialog + Command yes + Command no + Command cancel + Paned parent + Form formy + MenuButton fileButton + SimpleMenu fileMenu + SmeBSB new + SmeBSB load + SmeBSB insert + SmeBSB save + SmeBSB saveAs + SmeBSB resize + SmeBSB rescale + SmeBSB filename + SmeBSB basename + SmeLine line + SmeBSB quit + MenuButton editButton + SimpleMenu editMenu + SmeBSB image + SmeBSB grid + SmeBSB dashed + SmeBSB axes + SmeBSB stippled + SmeBSB proportional + SmeBSB zoom + SmeLine line + SmeBSB cut + SmeBSB copy + SmeBSB paste + Label status + Pane pane + Bitmap bitmap + Form form + Command clear + Command set + Command invert + Toggle mark + Command unmark + Toggle copy + Toggle move + Command flipHoriz + Command up + Command flipVert + Command left + Command fold + Command right + Command rotateLeft + Command down + Command rotateRight + Toggle point + Toggle curve + Toggle line + Toggle rectangle + Toggle filledRectangle + Toggle circle + Toggle filledCircle + Toggle floodFill + Toggle setHotSpot + Command clearHotSpot + Command undo +.fi +.SH COLORS +If you would like bitmap to be viewable in color, include the following +in the #ifdef COLOR section of the file you read with xrdb: +.sp 1 +*customization: \-color +.sp 1 +.br +This will cause bitmap to pick up the colors in the app-defaults color +customization file: +.sp 1 + __apploaddir__/Bitmap-color +.sp 1 +.fi +.SH BITMAP WIDGET +Bitmap widget is a stand-alone widget for editing raster images. It +is not designed to edit large images, although it may be used in that +purpose as well. It can be freely incorporated with other +applications and used as a standard editing tool. The following are +the resources provided by the bitmap widget. +.sp +.nf +Bitmap Widget + +Header file Bitmap.h +Class bitmapWidgetClass +Class Name Bitmap +Superclass Bitmap + + +All the Simple Widget resources plus .\|.\|. +.ta 1.6i 3.2i 4.8i + +Name Class Type Default Value + +foreground Foreground Pixel XtDefaultForeground +highlight Highlight Pixel XtDefaultForeground +framing Framing Pixel XtDefaultForeground +gridTolerance GridTolerance Dimension 8 +size Size String 32x32 +dashed Dashed Boolean True +grid Grid Boolean True +stippled Stippled Boolean True +proportional Proportional Boolean True +axes Axes Boolean False +squareWidth SquareWidth Dimension 16 +squareHeight SquareHeight Dimension 16 +margin Margin Dimension 16 +xHot XHot Position NotSet (\-1) +yHot YHot Position NotSet (\-1) +button1Function Button1Function DrawingFunction Set +button2Function Button2Function DrawingFunction Invert +button3Function Button3Function DrawingFunction Clear +button4Function Button4Function DrawingFunction Invert +button5Function Button5Function DrawingFunction Invert +filename Filename String None ("") +basename Basename String None ("") +.fi + +.SH AUTHOR +Davor Matic, MIT X Consortium diff --git a/bitmap/config.h.in b/bitmap/config.h.in new file mode 100644 index 0000000..424aa8e --- /dev/null +++ b/bitmap/config.h.in @@ -0,0 +1,25 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAS_MKSTEMP + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/bitmap/mkinstalldirs b/bitmap/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/bitmap/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/fstobdf/AUTHORS b/fstobdf/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/fstobdf/COPYING b/fstobdf/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/fstobdf/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/fstobdf/INSTALL b/fstobdf/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/fstobdf/Makefile.am b/fstobdf/Makefile.am new file mode 100644 index 0000000..48d10a8 --- /dev/null +++ b/fstobdf/Makefile.am @@ -0,0 +1,67 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = fstobdf + +fstobdf_CFLAGS = $(FSTOBDF_CFLAGS) +fstobdf_LDADD = $(FSTOBDF_LIBS) + +fstobdf_SOURCES = \ + chars.c \ + fstobdf.c \ + fstobdf.h \ + header.c \ + props.c + +appman_PRE = \ + fstobdf.man + + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/fstobdf/NEWS b/fstobdf/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/fstobdf/README b/fstobdf/README new file mode 100644 index 0000000..e69de29 diff --git a/fstobdf/config.h.in b/fstobdf/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/fstobdf/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/fstobdf/fstobdf.c b/fstobdf/fstobdf.c new file mode 100644 index 0000000..d21d654 --- /dev/null +++ b/fstobdf/fstobdf.c @@ -0,0 +1,137 @@ +/* $Xorg: fstobdf.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $ */ +/* + +Copyright 1990, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * 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, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL 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. + */ +/* $XFree86: xc/programs/fstobdf/fstobdf.c,v 1.6tsi Exp $ */ + +#include +#include +#include +#include "fstobdf.h" +static void +usage(char *progName) +{ + fprintf(stderr, "Usage: %s [-s ] -fn \n", + progName); + exit(0); +} + +static void +Fail(char *progName) +{ + fprintf(stderr, "%s: unable to dump font\n", progName); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + FSServer *fontServer; + Font fontID, + dummy; + FSBitmapFormat bitmapFormat; + FSXFontInfoHeader fontHeader; + FSPropInfo propInfo; + FSPropOffset *propOffsets; + unsigned char *propData; + + FILE *outFile; + char *fontName; + char *serverName; + int i; + + fontName = NULL; + serverName = NULL; + outFile = stdout; + + for (i = 1; i < argc; i++) { + if (!strncmp(argv[i], "-s", 2)) { + if (argv[++i]) + serverName = argv[i]; + else + usage(argv[0]); + } else if (!strncmp(argv[i], "-fn", 3)) { + if (argv[++i]) + fontName = argv[i]; + else + usage(argv[0]); + } + } + + if (fontName == NULL) + usage(argv[0]); + + fontServer = FSOpenServer(serverName); + if (!fontServer) { + char *sn = FSServerName(serverName); + if (sn) + fprintf(stderr, "%s: can't open font server \"%s\"\n", + argv[0], sn); + else + fprintf(stderr, "%s: No font server specified.\n", + argv[0]); + exit(0); + } + bitmapFormat = 0; + fontID = FSOpenBitmapFont(fontServer, bitmapFormat, (FSBitmapFormatMask) 0, + fontName, &dummy); + if (!fontID) { + printf("can't open font \"%s\"\n", fontName); + exit(0); + } + FSQueryXInfo(fontServer, fontID, &fontHeader, &propInfo, &propOffsets, + &propData); + + if (!EmitHeader(outFile, &fontHeader, &propInfo, propOffsets, propData)) + Fail(argv[0]); + if (!EmitProperties(outFile, &fontHeader, &propInfo, propOffsets, propData)) + Fail(argv[0]); + if (!EmitCharacters(outFile, fontServer, &fontHeader, fontID)) + Fail(argv[0]); + fprintf(outFile, "ENDFONT\n"); + + FSFree((char *) propOffsets); + FSFree((char *) propData); + exit (0); +} diff --git a/fstobdf/fstobdf.h b/fstobdf/fstobdf.h new file mode 100644 index 0000000..69d74d6 --- /dev/null +++ b/fstobdf/fstobdf.h @@ -0,0 +1,38 @@ +/* $XFree86: xc/programs/fstobdf/fstobdf.h,v 1.2 2001/08/27 17:41:01 dawes Exp $ */ +/* + * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#include + +extern Bool EmitHeader ( FILE *outFile, FSXFontInfoHeader *fontHeader, + FSPropInfo *propInfo, FSPropOffset *propOffsets, + unsigned char *propData ); +extern Bool EmitProperties ( FILE *outFile, FSXFontInfoHeader *fontHeader, + FSPropInfo *propInfo, FSPropOffset *propOffsets, + unsigned char *propData ); +extern Bool EmitCharacters ( FILE *outFile, FSServer *fontServer, + FSXFontInfoHeader *fontHeader, Font fontID ); + diff --git a/fstobdf/fstobdf.man b/fstobdf/fstobdf.man new file mode 100644 index 0000000..f76b009 --- /dev/null +++ b/fstobdf/fstobdf.man @@ -0,0 +1,64 @@ +.\" $Xorg: fstobdf.man,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $ +.\" Copyright 1990, Network Computing Devices +.\" Copyright 1990, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/fstobdf/fstobdf.man,v 1.6 2001/01/27 18:21:02 dawes Exp $ +.\" +.TH FSTOBDF 1 __xorgversion__ +.SH NAME +fstobdf \- generate BDF font from X font server +.SH SYNOPSIS +.B "fstobdf" +[ +.B \-server +.I server +] +.B \-fn +.I fontname +.SH DESCRIPTION +The \fIfstobdf\fP program reads a font from a font server and prints a BDF +file on the standard output that may be used to recreate the font. +This is useful in testing servers, debugging font metrics, and reproducing +lost BDF files. +.SH OPTIONS +.TP 8 +.B \-server \fIservername\fP +This option specifies the server from which the font should be read. +.TP 8 +.B \-fn \fIfontname\fP +This option specifies the font for which a BDF file should be generated. +.SH ENVIRONMENT +.TP 8 +.B FONTSERVER +default server to use +.SH "SEE ALSO" +xfs(1), bdftopcf(1), fslsfonts(1) +.SH AUTHOR +Olaf Brandt, Network Computing Devices +.br +Dave Lemke, Network Computing Devices +.br +.sp +Jim Fulton, MIT X Consortium diff --git a/fstobdf/header.c b/fstobdf/header.c new file mode 100644 index 0000000..7350b85 --- /dev/null +++ b/fstobdf/header.c @@ -0,0 +1,213 @@ +/* $Xorg: header.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $ */ +/* + +Copyright 1990, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * 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, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL 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. + */ +/* $XFree86: xc/programs/fstobdf/header.c,v 3.6 2001/07/25 15:05:13 dawes Exp $ */ + +#include +#include +#include +#include +#include "fstobdf.h" + +unsigned long pointSize; +unsigned long yResolution; + +static char *warning[] = +{ + "COMMENT ", + "COMMENT WARNING: This bdf file was generated from a font server using", + "COMMENT fstobdf. The resulting font is subject to the same copyright,", + "COMMENT license, and trademark restrictions as the original font. The", + "COMMENT authors and distributors of fstobdf disclaim all liability for", + "COMMENT misuse of the program or its output.", + "COMMENT ", + NULL +}; + +static char * +FindStringProperty(char *propName, + int *propLength, + FSPropInfo *propInfo, + FSPropOffset *propOffsets, + unsigned char *propData) +{ + FSPropOffset *propOffset; + int length; + int i; + + propOffset = &propOffsets[0]; + length = strlen(propName); + for (i = propInfo->num_offsets; i--; propOffset++) { + if (propOffset->type == PropTypeString) { + +#ifdef DEBUG + char pname[256]; + + memmove( pname, propData + propOffset->name.position, + propOffset->name.length); + pname[propOffset->name.length] = '\0'; + fprintf(stderr, "prop name: %s (len %d)\n", + pname, propOffset->name.length); +#endif + + if ((propOffset->name.length == length) && + !strncmp((char*)propData + propOffset->name.position, propName, length)) { + *propLength = propOffset->value.length; + return (char *)(propData + propOffset->value.position); + } + } + } + *propLength = 0; + return (NULL); +} + +static int +FindNumberProperty(char *propName, + unsigned long *propValue, + FSPropInfo *propInfo, + FSPropOffset *propOffsets, + unsigned char *propData) +{ + FSPropOffset *propOffset; + int i; + int length; + + propOffset = &propOffsets[0]; + length = strlen(propName); + for (i = propInfo->num_offsets; i--; propOffset++) { + if ((propOffset->type == PropTypeSigned) || + (propOffset->type == PropTypeUnsigned)) { + if ((propOffset->name.length == length) && + !strncmp((char*)propData + propOffset->name.position, propName, length)) { + *propValue = propOffset->value.position; + return (propOffset->type); + } + } + } + return (-1); +} + +/* + * EmitHeader - print STARTFONT, COMMENT lines, FONT, SIZE, and + * FONTBOUNDINGBOX lines + */ +Bool +EmitHeader(FILE *outFile, + FSXFontInfoHeader *fontHeader, + FSPropInfo *propInfo, + FSPropOffset *propOffsets, + unsigned char *propData) +{ + int len; + int type; + char *cp; + char **cpp; + unsigned long xResolution; + + fprintf(outFile, "STARTFONT 2.1\n"); + + /* + * find COPYRIGHT message and print it first, followed by warning + */ + cp = FindStringProperty("COPYRIGHT", &len, propInfo, propOffsets, + propData); + if (cp) { + fprintf(outFile, "COMMENT \nCOMMENT "); + fwrite(cp, 1, len, outFile); + fputc('\n', outFile); + } + for (cpp = warning; *cpp; cpp++) + fprintf(outFile, "%s\n", *cpp); + + /* + * FONT name + */ + cp = FindStringProperty("FONT", &len, propInfo, propOffsets, propData); + if (cp) { + fprintf(outFile, "FONT "); + fwrite(cp, 1, len, outFile); + fputc('\n', outFile); + } else { + fprintf(stderr, "unable to find FONT property\n"); + return (False); + } + + /* + * SIZE point xres yres + * + * Get XLFD values if possible, else fake it + */ + type = FindNumberProperty("RESOLUTION_X", &xResolution, propInfo, + propOffsets, propData); + if ((type != PropTypeUnsigned) && (type != PropTypeSigned)) + xResolution = 72; + + type = FindNumberProperty("RESOLUTION_Y", &yResolution, propInfo, + propOffsets, propData); + if ((type != PropTypeUnsigned) && (type != PropTypeSigned)) + yResolution = 72; + + type = FindNumberProperty("POINT_SIZE", &pointSize, propInfo, + propOffsets, propData); + if ((type == PropTypeUnsigned) || (type == PropTypeSigned)) + pointSize = (pointSize + 5) / 10; + else + pointSize = ((fontHeader->font_ascent + fontHeader->font_descent) + * 72) / yResolution; + + fprintf(outFile, "SIZE %lu %lu %lu\n", pointSize, xResolution, + yResolution); + + /* + * FONTBOUNDINGBOX width height xoff yoff + * + */ + fprintf(outFile, "FONTBOUNDINGBOX %d %d %d %d\n", + fontHeader->max_bounds.right - fontHeader->min_bounds.left, + fontHeader->max_bounds.ascent + fontHeader->max_bounds.descent, + fontHeader->min_bounds.left, + -fontHeader->max_bounds.descent); + return (True); +} diff --git a/fstobdf/mkinstalldirs b/fstobdf/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/fstobdf/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/fstobdf/props.c b/fstobdf/props.c new file mode 100644 index 0000000..29e3249 --- /dev/null +++ b/fstobdf/props.c @@ -0,0 +1,145 @@ +/* $Xorg: props.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $ */ +/* + +Copyright 1990, 1991, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * 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, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL 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. + */ +/* $XFree86: xc/programs/fstobdf/props.c,v 1.5 2001/01/17 23:44:54 dawes Exp $ */ + +#include +#include +#include "fstobdf.h" + +static char * +AddQuotes(unsigned char *string, int length) +{ + static unsigned char new[256] = "\""; + unsigned char *cp; + unsigned char *end; + + end = string + length; + for (cp = &new[1]; string < end; cp++, string++) { + *cp = *string; + if (*cp == '"') + *++cp = '"'; + } + *cp++ = '"'; + *cp = '\0'; + return (char *)(new); +} + +Bool +EmitProperties(FILE *outFile, + FSXFontInfoHeader *fontHeader, + FSPropInfo *propInfo, + FSPropOffset *propOffsets, + unsigned char *propData) +{ + int nProperties; + FSPropOffset *property; + Bool needDefaultChar; + Bool needFontAscent; + Bool needFontDescent; + + needDefaultChar = True; + needFontAscent = True; + needFontDescent = True; + + nProperties = propInfo->num_offsets; + for (property = &propOffsets[0]; nProperties--; property++) { + char *name; + int length; + + name = (char *)propData + property->name.position; + length = property->name.length; + + if ((length == 12) && (!strncmp(name, "DEFAULT_CHAR", 12))) + needDefaultChar = False; + else if ((length == 11) && (!strncmp(name, "FONT_ASCENT", 11))) + needFontAscent = False; + else if ((length == 12) && (!strncmp(name, "FONT_DESCENT", 12))) + needFontDescent = False; + } + + nProperties = propInfo->num_offsets; + fprintf(outFile, "STARTPROPERTIES %d\n", nProperties + + (needDefaultChar ? 1 : 0) + (needFontAscent ? 1 : 0) + + (needFontDescent ? 1 : 0)); + + for (property = &propOffsets[0]; nProperties--; property++) { + unsigned long value; + + /* Don't emit properties that are computed by bdftosnf */ + + fwrite(propData + property->name.position, 1, property->name.length, + outFile); + fputc(' ', outFile); + + value = property->value.position; + switch (property->type) { + case PropTypeString: + fprintf(outFile, "%s\n", AddQuotes(propData + value, + property->value.length)); + break; + case PropTypeUnsigned: + fprintf(outFile, "%lu\n", value); + break; + case PropTypeSigned: + fprintf(outFile, "%ld\n", value); + break; + default: + fprintf(stderr, "unknown property type\n"); + return (False); + } + } + if (needDefaultChar) { + fprintf(outFile, "DEFAULT_CHAR %lu\n", + (long) (fontHeader->default_char.high << 8) + | (fontHeader->default_char.low)); + } + if (needFontAscent) + fprintf(outFile, "FONT_ASCENT %d\n", fontHeader->font_ascent); + if (needFontDescent) + fprintf(outFile, "FONT_DESCENT %d\n", fontHeader->font_descent); + fprintf(outFile, "ENDPROPERTIES\n"); + return (True); +} diff --git a/xclock/AUTHORS b/xclock/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xclock/COPYING b/xclock/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xclock/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xclock/Clock.h b/xclock/Clock.h new file mode 100644 index 0000000..cf0744e --- /dev/null +++ b/xclock/Clock.h @@ -0,0 +1,149 @@ +/* +* $Xorg: Clock.h,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ +*/ + + +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +******************************************************************/ +/* $XFree86: xc/programs/xclock/Clock.h,v 1.11 2002/10/17 01:00:01 dawes Exp $ */ + +#ifndef _XawClock_h +#define _XawClock_h + +/*********************************************************************** + * + * Clock Widget + * + ***********************************************************************/ + +#include + +/* Parameters: + + Name Class RepType Default Value + ---- ----- ------- ------------- + twentyfour Boolean Boolean True + analog Boolean Boolean True + background Background Pixel white + backingStore BackingStore BackingStore default + border BorderColor Pixel Black + borderWidth BorderWidth Dimension 1 + chime Boolean Boolean False + destroyCallback Callback Pointer NULL + font Font XFontStruct* fixed + foreground Foreground Pixel black + hand Foreground Pixel black + height Height Dimension 164 + highlight Foreground Pixel black + mappedWhenManaged MappedWhenManaged Boolean True + padding Margin int 8 + utime Boolean Boolean False + update Interval int 60 (seconds) + width Width Dimension 164 + x Position Position 0 + y Position Position 0 + +*/ + +/* Resource names used to the clock widget */ + + /* color of hands */ +#define XtNhand "hands" + + + /* Boolean: 24-hour if TRUE */ +#define XtNtwentyfour "twentyfour" + + /* Boolean: digital if FALSE */ +#define XtNanalog "analog" + + /* Boolean: only hour/minute if TRUE */ +#define XtNbrief "brief" + + /* String: will be used as format arg to + "strftime" if not empty string */ +#define XtNstrftime "strftime" + + /* Boolean: show seconds since Epoch if TRUE */ +#define XtNutime "utime" + + /* Boolean: */ +#define XtNchime "chime" + + /* Int: amount of space around outside of clock */ +#define XtNpadding "padding" + + /* Boolean: use Render extension if TRUE */ +#define XtNrender "render" + + /* Boolean: use backing pixmap for double buffering */ +#define XtNbuffer "buffer" + + /* RenderColor: colors for various clock elements */ +#define XtNhourColor "hourColor" +#define XtNminuteColor "minuteColor" +#define XtNsecondColor "secondColor" +#define XtNmajorColor "majorColor" +#define XtNminorColor "minorColor" + +#define XtRXftColor "XftColor" + +#define XtNface "face" +#define XtCFace "Face" +#define XtRXftFont "XftFont" + + /* Boolean: use sharp rendering for Render polygons */ +#define XtNsharp "sharp" +#define XtCSharp "Sharp" + +typedef struct _ClockRec *ClockWidget; /* completely defined in ClockPrivate.h */ +typedef struct _ClockClassRec *ClockWidgetClass; /* completely defined in ClockPrivate.h */ + +extern WidgetClass clockWidgetClass; + +#endif /* _XawClock_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/xclock/ClockP.h b/xclock/ClockP.h new file mode 100644 index 0000000..6e83ba7 --- /dev/null +++ b/xclock/ClockP.h @@ -0,0 +1,170 @@ +/* +* $Xorg: ClockP.h,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ +*/ + + +/*********************************************************** + +Copyright 1987, 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +******************************************************************/ +/* $XFree86: xc/programs/xclock/ClockP.h,v 1.11 2002/10/17 01:00:01 dawes Exp $ */ + +#ifndef _XawClockP_h +#define _XawClockP_h + +#include /* Needed for struct tm. */ +#include "Clock.h" +#include +#ifdef XRENDER +#include +#include +#endif + +#define SEG_BUFF_SIZE 128 +#ifdef NO_I18N +#define ASCII_TIME_BUFLEN 32 /* big enough for 26 plus slop */ +#define STRFTIME_BUFF_SIZE 100 /* buffer for "strftime" option */ +#else +#define STRFTIME_BUFF_SIZE 256 /* should handle any locale */ +#endif + + + +/* New fields for the clock widget instance record */ +typedef struct { +#ifndef RENDER + Pixel fgpixel; /* color index for text */ +#endif + Pixel Hipixel; /* color index for Highlighting */ + Pixel Hdpixel; /* color index for hands */ + XFontStruct *font; /* font for text */ + GC myGC; /* pointer to GraphicsContext */ + GC EraseGC; /* eraser GC */ + GC HandGC; /* Hand GC */ + GC HighGC; /* Highlighting GC */ +/* start of graph stuff */ + int update; /* update frequence */ + Dimension radius; /* radius factor */ + int backing_store; /* backing store type */ + Boolean chime; + Boolean beeped; + Boolean analog; + Boolean brief; + Boolean twentyfour; + Boolean utime; + String strftime; + Boolean show_second_hand; + Dimension second_hand_length; + Dimension minute_hand_length; + Dimension hour_hand_length; + Dimension hand_width; + Dimension second_hand_width; + Position centerX; + Position centerY; + int numseg; + int padding; + XPoint segbuff[SEG_BUFF_SIZE]; + XPoint *segbuffptr; + XPoint *hour, *sec; + struct tm otm ; + XtIntervalId interval_id; + char prev_time_string[STRFTIME_BUFF_SIZE]; +#ifndef NO_I18N + XFontSet fontSet; /* font set for localized text */ + Boolean utf8; +#endif +#ifdef XRENDER + XftColor fg_color; + XftColor hour_color; + XftColor min_color; + XftColor sec_color; + XftColor major_color; + XftColor minor_color; + XftFont *face; + XRenderPictFormat *mask_format; + + Boolean render; + Boolean sharp; + Boolean can_polygon; + Boolean buffer; + XftDraw *draw; + Picture picture; + Picture fill_picture; + Pixmap pixmap; + XRectangle damage; + XDouble x_scale; + XDouble x_off; + XDouble y_scale; + XDouble y_off; +#endif + } ClockPart; + +#ifdef XRENDER +#define ClockFgPixel(c) ((c)->clock.fg_color.pixel) +#else +#define ClockFgPixel(c) ((c)->clock.fgpixel) +#endif + +/* Full instance record declaration */ +typedef struct _ClockRec { + CorePart core; + SimplePart simple; + ClockPart clock; + } ClockRec; + +/* New fields for the Clock widget class record */ +typedef struct {int dummy;} ClockClassPart; + +/* Full class record declaration. */ +typedef struct _ClockClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + ClockClassPart clock_class; + } ClockClassRec; + +/* Class pointer. */ +extern ClockClassRec clockClassRec; + +#endif /* _XawClockP_h */ diff --git a/xclock/INSTALL b/xclock/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xclock/NEWS b/xclock/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xclock/README b/xclock/README new file mode 100644 index 0000000..e69de29 diff --git a/xclock/XClock.ad b/xclock/XClock.ad new file mode 100644 index 0000000..971ae2d --- /dev/null +++ b/xclock/XClock.ad @@ -0,0 +1 @@ +XClock.input: false diff --git a/xclock/clmask.bit b/xclock/clmask.bit new file mode 100644 index 0000000..afeb014 --- /dev/null +++ b/xclock/clmask.bit @@ -0,0 +1,27 @@ +#define clock_mask_width 48 +#define clock_mask_height 48 +static unsigned char clock_mask_bits[] = { + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, + 0x00, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00}; diff --git a/xclock/clock.bit b/xclock/clock.bit new file mode 100644 index 0000000..5e9ab18 --- /dev/null +++ b/xclock/clock.bit @@ -0,0 +1,29 @@ +#define clock_width 48 +#define clock_height 48 +#define clock_x_hot -1 +#define clock_y_hot -1 +static unsigned char clock_bits[] = { + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xf8, 0x87, 0xf1, 0x0f, 0x00, 0x00, 0xfc, 0x80, 0x81, 0x1f, 0x00, + 0x00, 0x3e, 0x80, 0x01, 0x3e, 0x00, 0x00, 0x9f, 0x01, 0xc0, 0x7c, 0x00, + 0x80, 0x8f, 0x01, 0xc0, 0xf8, 0x00, 0xc0, 0x07, 0x00, 0x00, 0xf0, 0x01, + 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x03, + 0xf0, 0x00, 0x00, 0x40, 0x80, 0x07, 0xf0, 0x06, 0x00, 0xe0, 0xb0, 0x07, + 0x78, 0x06, 0x00, 0xf0, 0x30, 0x0f, 0x78, 0x00, 0x00, 0x78, 0x00, 0x0f, + 0x78, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x3c, 0x00, 0x00, 0x1e, 0x00, 0x1e, + 0x3c, 0x00, 0x00, 0x0f, 0x00, 0x1e, 0x3c, 0x00, 0x80, 0x07, 0x00, 0x1e, + 0x3c, 0x00, 0xc0, 0x03, 0x00, 0x7e, 0xfc, 0x01, 0xc0, 0x03, 0xc0, 0x7f, + 0xfc, 0x01, 0x80, 0x07, 0xc0, 0x7f, 0x3c, 0x00, 0x00, 0x0f, 0x00, 0x7e, + 0x3c, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x1e, + 0x7c, 0x00, 0x00, 0x08, 0x00, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x78, 0x06, 0x00, 0x00, 0x30, 0x0f, 0xf0, 0x06, 0x00, 0x00, 0xb0, 0x07, + 0xf0, 0x00, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x01, 0x00, 0x00, 0xc0, 0x03, + 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x01, 0xc0, 0x07, 0x00, 0x00, 0xf0, 0x01, + 0x80, 0x8f, 0x01, 0xc0, 0xf8, 0x00, 0x00, 0x9f, 0x01, 0xc0, 0x7c, 0x00, + 0x00, 0x3e, 0x80, 0x01, 0x3e, 0x00, 0x00, 0xfc, 0x80, 0x81, 0x1f, 0x00, + 0x00, 0xf8, 0x87, 0xf1, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f, 0x00, 0x00}; diff --git a/xclock/config.h.in b/xclock/config.h.in new file mode 100644 index 0000000..11f525c --- /dev/null +++ b/xclock/config.h.in @@ -0,0 +1,34 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION + +/* Define to use Xft2 library */ +#undef XFREE86_FT2 + +/* Define to use XkbStdBell */ +#undef XKB + +/* Define to use X Render Extension */ +#undef XRENDER diff --git a/xclock/mkinstalldirs b/xclock/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xclock/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xclock/xclock.man b/xclock/xclock.man new file mode 100644 index 0000000..5b68678 --- /dev/null +++ b/xclock/xclock.man @@ -0,0 +1,264 @@ +.\" $Xorg: xclock.man,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ +.\" Copyright 1988, 1994, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/xclock/xclock.man,v 1.15 2003/07/04 16:24:30 eich Exp $ +.\" +.TH XCLOCK 1 __xorgversion__ +.SH NAME +xclock \- analog / digital clock for X +.SH SYNOPSIS +.ta 8n +\fBxclock\fP [ \fB\-help\fP ] [ \fB\-analog\fP ] [ \fB\-digital\fP ] +[ \fB\-brief\fP ] [ \fB\-chime\fP ] [ \fB\-hd\fP \fIcolor\fP ] +[ \fB\-hl\fP \fIcolor\fP ] [ \fB\-update\fP \fIseconds\fP ] +[ \fB\-strftime\fP \fIformat\fP ] +[ \fB\-padding\fP \fInumber\fP ] +[ \fB\-norender\fP ] +[ \fB\-render\fP ] +[ \fB\-sharp\fP ] +[ \fB\-face\fP \fIpattern\fP ] +.SH DESCRIPTION +The +.I xclock +program displays the time in analog or digital form. The time is continuously +updated at a frequency which may be specified by the user. +.SH OPTIONS +.I Xclock +accepts all of the standard X Toolkit command line options along with the +additional options listed below: +.TP 8 +.B \-help +This option indicates that a brief summary of the allowed options should be +printed on the standard error. +.TP 8 +.B \-analog +This option indicates that a conventional 12 hour clock face with tick marks +and hands should be used. This is the default. +.TP 8 +\fB\-digital\fP or \fB\-d\fP +This option indicates that a 24 hour digital clock should be used. +.TP 8 +\fB\-brief\fP +This option indicates that the digital clock should only display the hours +and minutes fields. The default is to show the full time and date information. +.TP 8 +\fB\-utime\fP or \fB\-d\fP +This option indicates that a digital clock should display seconds since +the Epoch (in format '970012340 seconds since Epoch' instead of a standard +24-hour time. +.TP 8 +.B \-strftime \fIformat\fP +This option allows an strftime(3) format string to be specified for the +digital clock's display. +.TP 8 +.B \-twelve +This option indicates that a digital clock should display the time in +twelve hour format. +.TP 8 +.B \-twentyfour +This option indicates that a digital clock should display the time in +twenty-four hour format. This is the default when a digital clock is used. +.TP 8 +.B \-chime +This option indicates that the clock should chime +once on the half hour and twice on the hour. +.TP 8 +\fB\-hands\fP \fIcolor\fP (or \fB\-hd\fP \fIcolor\fP) +This option specifies the color of the hands on an analog clock. The default +is \fIblack\fP. +This option is effectively ignored when Xrender is in use. +.TP 8 +\fB\-highlight\fP \fIcolor\fP (or \fB\-hl\fP \fIcolor\fP) +This option specifies the color of the edges of the hands on an analog clock, +and is only useful on color displays. The default is \fIblack\fP. +This option is effectively ignored when Xrender is in use. +.TP 8 +.B \-update \fIseconds\fP +This option specifies the frequency in seconds at which \fIxclock\fP +should update its display. If the clock is obscured and then exposed, +it will be updated immediately. A value of 30 seconds or less will enable a +second hand on an analog clock. The default is 60 seconds. +.TP 8 +.B \-padding \fInumber\fP +This option specifies the width in pixels of the padding +between the window border and clock text or picture. The default is 10 +on a digital clock and 8 on an analog clock. +.TP 8 +.B \-render +This option tells \fIxclock\fP to use the Xrender extension to draw an +anti-aliased face. This is the default if \fIxclock\fP has been +compiled with Xrender support. +Note that the color selection options and resources used when Xrender is +in effect differ from the standard options. +.TP 8 +.B \-norender +This option turns off the use of Xrender to draw the clock. +.TP 8 +.B \-sharp +This option tells \fIxclock\fP to use sharper edges when drawn using +the Xrender extension. +.TP 8 +.B \-face \fIpattern\fP +This option specifies the font to use in digital mode when the +Xrender extension is used. +.SH X DEFAULTS +This program uses the +.I Clock +widget. It understands all of the core resource names and classes as well as: +.PP +.TP 8 +.B width (\fPclass\fB Width) +Specifies the width of the clock. The default for analog clocks is 164 +pixels; the default for digital clocks is whatever is needed to hold the +clock when displayed in the chosen font. +.TP 8 +.B height (\fPclass\fB Height) +Specifies the height of the clock. The default for analog clocks is 164 +pixels; the default for digital clocks is whatever is needed to hold the +clock when displayed in the chosen font. +.TP 8 +.B update (\fPclass\fB Interval) +Specifies the frequency in seconds at which the time should be redisplayed. +.TP 8 +.B foreground (\fPclass\fB Foreground) +Specifies the color for the tick marks. The default depends on whether +\fIreverseVideo\fP is specified. If \fIreverseVideo\fP is specified +the default is \fIlwhite\fP, otherwise the default is \fIblack\fP. + +.TP 8 +.B hands (\fPclass\fB Foreground) +Specifies the color of the insides of the clock's hands. The default +depends on whether +\fIreverseVideo\fP is specified. If \fIreverseVideo\fP is specified +the default is \fIlwhite\fP, otherwise the default is \fIblack\fP. +Note that this resource is not used when Xrender is in effect. +.TP 8 +.B highlight (\fPclass\fB Foreground) +Specifies the color used to highlight the clock's hands. The default is + depends on whether +\fIreverseVideo\fP is specified. If \fIreverseVideo\fP is specified +the default is \fIlwhite\fP, otherwise the default is \fIblack\fP. +Note that this resource is not used when Xrender is in effect. +.TP 8 +.B analog (\fPclass\fB Boolean) +Specifies whether or not an analog clock should be used instead of a digital +one. The default is True. +.TP 8 +.B twentyfour (\fPclass\fB Boolean) +Specifies whether or not a digital clock should display the time in +twenty-four hour format. The default is True. +.TP 8 +.B chime (\fPclass\fB Boolean) +Specifies whether or not a bell should be rung on the hour and half hour. +.TP 8 +.B padding (\fPclass\fB Margin) +Specifies the amount of internal padding in pixels to be used. The default is +8. +.TP 8 +.B font (\fPclass\fB Font) +Specifies the font to be used for the digital clock. Note that variable width +fonts currently will not always display correctly. +This font is only used when Xrender is not in effect. +.TP 8 +.B render (\fPclass\fB Boolean) +Specifies whether or not the Xrender extension should be used for the +display. The default is True if \fIxclock\fP has been compiled with +Xrender support. +.PP +When Xrender is in effect, the following additional resources are +understood: +.PP +.TP 8 +.B face (\fPclass\fB FaceName) +Specify the pattern for the font to be used for the digital clock when +Xrender is used. +.TP 8 +.B sharp (\fPclass\fB Boolean) +Specifies if sharp edges should be used when rendering the clock. +The default is False. +.TP 8 +.B buffer (\fPclass\fB Boolean) +Specifies that the updates of the image are drawn to a pixmap before copied +into the window instead drawing them into the window directly. +.PP +The defaults of the following color resources depend on whether +\fIreverseVideo\fP is specified. +If \fIreverseVideo\fP is specified the default is \fIlwhite\fP, +otherwise the default is \fIblack\fP. +.TP 8 +.B hourColor (\fPclass\fB Foreground) +The color of the hour hand. +.TP 8 +.B minuteColor (\fPclass\fB Foreground) +The color of the minute hand. +.TP 8 +.B secondColor (\fPclass\fB Foreground) +The color of the second hand. +.TP 8 +.B majorColor (\fPclass\fB Foreground) +The color of the major scale ticks (i. e. each five minutes). +.TP 8 +.B minorColor (\fPclass\fB Foreground) +The color of the minor scale ticks (between major ticks). +.SH WIDGETS +In order to specify resources, it is useful to know the hierarchy of +the widgets which compose \fIxclock\fR. In the notation below, +indentation indicates hierarchical structure. The widget class name +is given first, followed by the widget instance name. +.sp +.nf +.\".TA .5i +.ta .5i +XClock xclock + Clock clock +.fi +.sp +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH FILES +.TP +.I __apploaddir__/XClock +specifies required resources +.SH "SEE ALSO" +X(__miscmansuffix__), xrdb(1), time(3C) +.SH BUGS +.I Xclock +believes the system clock. +.PP +When in digital mode, the string should be centered automatically. +.SH AUTHORS +Tony Della Fera (MIT-Athena, DEC) +.br +Dave Mankins (MIT-Athena, BBN) +.br +Ed Moy (UC Berkeley) + diff --git a/xconsole/AUTHORS b/xconsole/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xconsole/COPYING b/xconsole/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xconsole/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xconsole/INSTALL b/xconsole/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xconsole/Makefile.am b/xconsole/Makefile.am new file mode 100644 index 0000000..de2cd2d --- /dev/null +++ b/xconsole/Makefile.am @@ -0,0 +1,82 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xconsole + +xconsole_CFLAGS = $(XCONSOLE_CFLAGS) +xconsole_LDADD = $(XCONSOLE_LIBS) + +xconsole_SOURCES = \ + xconsole.c + +appman_PRE = \ + xconsole.man + +# App default files (*.ad) + +appdefaultdir = @appdefaultdir@ + + +APPDEFAULTFILES = \ + XConsole + +SUFFIXES = .ad + +.ad: + cp $< $@ + +appdefault_DATA = $(APPDEFAULTFILES) + +EXTRA_DIST = $(APPDEFAULTFILES:%=%.ad) + +CLEANFILES = $(APPDEFAULTFILES) + + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST += $(appman_PRE) +CLEANFILES += $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES += .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xconsole/NEWS b/xconsole/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xconsole/README b/xconsole/README new file mode 100644 index 0000000..e69de29 diff --git a/xconsole/XConsole.ad b/xconsole/XConsole.ad new file mode 100644 index 0000000..c3407d4 --- /dev/null +++ b/xconsole/XConsole.ad @@ -0,0 +1,28 @@ +! $Xorg: XConsole.ad,v 1.3 2000/08/17 19:54:13 cpqbld Exp $ +! +! +! +! +! $XFree86: xc/programs/xconsole/XConsole.ad,v 1.2 2000/03/31 22:55:55 dawes Exp $ + +*allowShellResize: true +XConsole.translations: #override\ + : Deiconified() \n\ + : Iconified() \n\ + WM_PROTOCOLS: Quit() +XConsole.baseTranslations: #override\ + : Deiconified() \n\ + : Iconified() \n\ + WM_PROTOCOLS: Quit() +*text.translations: #override\ + CtrlC: Clear() \n\ + Clear: Clear() +*text.baseTranslations: #override\ + CtrlC: Clear() \n\ + Clear: Clear() +*text.scrollVertical: Always +*text.scrollHorizontal: Never +*text.width: 400 +*text.height: 70 +*text.allowResize: true +*editType: read diff --git a/xconsole/config.h.in b/xconsole/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/xconsole/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xconsole/mkinstalldirs b/xconsole/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xconsole/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xconsole/xconsole.man b/xconsole/xconsole.man new file mode 100644 index 0000000..8642cd8 --- /dev/null +++ b/xconsole/xconsole.man @@ -0,0 +1,117 @@ +.\" $Xorg: xconsole.man,v 1.4 2001/02/09 02:05:40 xorgcvs Exp $ +.\" Copyright 1994, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included in +.\" all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +.\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +.\" THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +.\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +.\" SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall not +.\" be used in advertising or otherwise to promote the sale, use or other +.\" dealing in this Software without prior written authorization from the +.\" The Open Group. +.\" +.\" $XFree86: xc/programs/xconsole/xconsole.man,v 1.9 2002/10/12 16:06:47 herrb Exp $ +.\" +.TH XCONSOLE 1 __xorgversion__ +.SH NAME +xconsole \- monitor system console messages with X +.SH SYNOPSIS +.ta 8n +\fBxconsole\fP [-\fItoolkitoption\fP ...] [-file \fIfile-name\fP] +[-notify] [-stripNonprint] [-daemon] [-verbose] [-exitOnFail] +.SH DESCRIPTION +The +.I xconsole +program displays messages which are usually sent to /dev/console. +.SH OPTIONS +.I Xconsole +accepts all of the standard X Toolkit command line options along with the +additional options listed below: +.TP 8 +.B \-file \fIfile-name\fP +To monitor some other device, use this option to specify the device name. +This does not work on regular files as they are always ready to be read from. +.TP 8 +.B \-notify \-nonotify +When new data are received from the console and the notify option is set, +the icon name of the application has " *" appended, so that it is evident +even when the application is iconified. \-notify is the default. +.TP 8 +.B \-daemon +This option causes +.I xconsole +to place itself in the background, using fork/exit. +.TP 8 +.B \-verbose +When set, this option directs +.I xconsole +to display an informative message in the first line of the text buffer. +.TP 8 +.B \-exitOnFail +When set, this option directs +.I xconsole +to exit when it is unable to redirect the console output. +.TP 8 +.B \-saveLines \fIcount\fP +When set, +.I xconsole +only preserves +.I count +lines of message history instead of growing the text buffer without bound +(a +.I count +of zero \- the default \- is treated as placing no limit on the history). +.SH X DEFAULTS +This program uses the +.I Athena Text +widget, look in the +.I Athena Widget Set +documentation for controlling it. +.PP +.I Xconsole +otherwise accepts resources of the same names as the command-line options +(without the leading dash). "file" is a string type, "saveLines" an +integer, and the remaining options are booleans. +.SH WIDGETS +In order to specify resources, it is useful to know the hierarchy of +the widgets which compose \fIxconsole\fR. In the notation below, +indentation indicates hierarchical structure. The widget class name +is given first, followed by the widget instance name. +.sp +.nf +.TA .5i +.ta .5i +XConsole xconsole + XConsole text +.fi +.sp +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH FILES +.TP +.I __apploaddir__/XConsole +specifies required resources +.SH "SEE ALSO" +X(__miscmansuffix__), xrdb(1), Athena Text widget +.SH AUTHOR +Keith Packard (MIT X Consortium) diff --git a/xcursorgen/AUTHORS b/xcursorgen/AUTHORS new file mode 100644 index 0000000..f9cc057 --- /dev/null +++ b/xcursorgen/AUTHORS @@ -0,0 +1,2 @@ +Original authors: + Manish Singh diff --git a/xcursorgen/COPYING b/xcursorgen/COPYING new file mode 100644 index 0000000..0243ddf --- /dev/null +++ b/xcursorgen/COPYING @@ -0,0 +1,19 @@ +Copyright (C) 2002 Manish Singh + +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, and that the name of Manish Singh not be used in +advertising or publicity pertaining to distribution of the software without +specific, written prior permission. Manish Singh makes no +representations about the suitability of this software for any purpose. It +is provided "as is" without express or implied warranty. + +MANISH SINGH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL MANISH SINGH 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. diff --git a/xcursorgen/INSTALL b/xcursorgen/INSTALL new file mode 100644 index 0000000..56b077d --- /dev/null +++ b/xcursorgen/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/xcursorgen/Makefile.am b/xcursorgen/Makefile.am new file mode 100644 index 0000000..f7119fd --- /dev/null +++ b/xcursorgen/Makefile.am @@ -0,0 +1,22 @@ +bin_PROGRAMS = xcursorgen + +xcursorgen_SOURCES = xcursorgen.c + +xcursorgen_CFLAGS = @XCURSORGEN_CFLAGS@ + +xcursorgen_LDADD = @XCURSORGEN_LIBS@ + +appmandir = $(APP_MAN_DIR) + +appman_PRE = xcursorgen.man +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +MAN_SUBSTS = -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xcursorgen/NEWS b/xcursorgen/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xcursorgen/README b/xcursorgen/README new file mode 100644 index 0000000..e69de29 diff --git a/xcursorgen/config.h.in b/xcursorgen/config.h.in new file mode 100644 index 0000000..bddcf36 --- /dev/null +++ b/xcursorgen/config.h.in @@ -0,0 +1,25 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Version number of package */ +#undef VERSION diff --git a/xcursorgen/mkinstalldirs b/xcursorgen/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xcursorgen/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xcursorgen/xcursorgen.man b/xcursorgen/xcursorgen.man new file mode 100644 index 0000000..52d5750 --- /dev/null +++ b/xcursorgen/xcursorgen.man @@ -0,0 +1,46 @@ +.\" +.\" Copyright 2002 Keith Packard.\" +.\" 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, and that the name of Keith Packard not be used in +.\" advertising or publicity pertaining to distribution of the software without +.\" specific, written prior permission. Keith Packard makes no +.\" representations about the suitability of this software for any purpose. It +.\" is provided "as is" without express or implied warranty. +.\" +.\" KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +.\" EVENT SHALL KEITH PACKARD 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. +.\" +.\" +.\" $XFree86: xc/programs/xcursorgen/xcursorgen.man,v 1.1 2002/09/03 06:48:28 keithp Exp $ +.\" +.TH XCURSORGEN 1 __vendorversion__ +.SH NAME +xcursorgen \- create an X cursor file from a collection of PNG images +.SH SYNOPSIS +.B "xcursorgen" +.RI [ config-file ] +.RI [ output-file ] +.SH DESCRIPTION +Xcursorgen reads the config-file to find the list of cursor images along +with their hotspot and nominal size information. Xcursorgen converts all of +the images to Xcursor format and writes them to the output-file. +.P +Each line in the config file is of the form: +.br + +.br +.P +Multiple images with the same are used to create animated cursors, +the value on each line indicates how long each image should be +displayed before switching to the next. can be elided for static +cursors. +.SH "SEE ALSO" +Xcursor(3x) diff --git a/xdriinfo/AUTHORS b/xdriinfo/AUTHORS new file mode 100644 index 0000000..ee4c3f3 --- /dev/null +++ b/xdriinfo/AUTHORS @@ -0,0 +1 @@ +Felix Külhing diff --git a/xdriinfo/COPYING b/xdriinfo/COPYING new file mode 100644 index 0000000..7f7e20e --- /dev/null +++ b/xdriinfo/COPYING @@ -0,0 +1,20 @@ +Client application for querying drivers' configuration information +Copyright (C) 2003 Felix Kuehling + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/xdriinfo/INSTALL b/xdriinfo/INSTALL new file mode 100644 index 0000000..56b077d --- /dev/null +++ b/xdriinfo/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/xdriinfo/Makefile.am b/xdriinfo/Makefile.am new file mode 100644 index 0000000..c5cce1d --- /dev/null +++ b/xdriinfo/Makefile.am @@ -0,0 +1,62 @@ +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xdriinfo + +xdriinfo_CFLAGS = $(XDRIINFO_CFLAGS) +# mesa should really use pkg-config ... +xdriinfo_LDADD = $(XDRIINFO_LIBS) + +xdriinfo_SOURCES = \ + xdriinfo.c + +appman_PRE = \ + xdriinfo.man + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xdriinfo/NEWS b/xdriinfo/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xdriinfo/README b/xdriinfo/README new file mode 100644 index 0000000..e69de29 diff --git a/xdriinfo/config.h.in b/xdriinfo/config.h.in new file mode 100644 index 0000000..bddcf36 --- /dev/null +++ b/xdriinfo/config.h.in @@ -0,0 +1,25 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Version number of package */ +#undef VERSION diff --git a/xdriinfo/mkinstalldirs b/xdriinfo/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xdriinfo/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xdriinfo/xdriinfo.man b/xdriinfo/xdriinfo.man new file mode 100644 index 0000000..efe5e51 --- /dev/null +++ b/xdriinfo/xdriinfo.man @@ -0,0 +1,33 @@ +.\" $XFree86$ +.TH xdriinfo 1 __vendorversion__ +.SH NAME +xdriinfo \- query configuration information of DRI drivers +.SH SYNOPSIS +.B xdriinfo +[\-display \fIdisplayname\fP] [command] +.SH DESCRIPTION +\fIxdriinfo\fP can be used to query configuration information of +direct rendering drivers. If no command argument is specified it lists +the names of the direct rendering drivers for all screens. +.PP +Valid commands are: +.TP +.B nscreens +Print the number of screens. +.TP +.B driver \fIscreen\fP +Print the name of the direct rendering driver for \fIscreen\fP. +.TP +.B options \fIscreen|driver\fP +Print the XML document describing the configuration options of a +driver. The driver can be specified directly by \fIdriver\fP name or +indirectly by \fIscreen\fP number. If the driver name is specified +directly then no X connection is needed. +.SH ENVIRONMENT +.TP +.B DISPLAY +The default display. +.SH "SEE ALSO" +.IR glxinfo (1x) +.SH AUTHOR +Felix Kuehling diff --git a/xhost/AUTHORS b/xhost/AUTHORS new file mode 100644 index 0000000..6388c16 --- /dev/null +++ b/xhost/AUTHORS @@ -0,0 +1,3 @@ +Original authors: + Bob Scheifler, MIT Laboratory for Computer Science + Jim Gettys, MIT Project Athena (DEC) \ No newline at end of file diff --git a/xhost/COPYING b/xhost/COPYING new file mode 100644 index 0000000..e871188 --- /dev/null +++ b/xhost/COPYING @@ -0,0 +1,32 @@ +Copyright 1985, 1986, 1987, 1998 The Open Group +Copyright 2004 Sun Microsystems, Inc. + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +X Window System is a trademark of The Open Group. + diff --git a/xhost/Makefile.am b/xhost/Makefile.am new file mode 100644 index 0000000..e4ed6c1 --- /dev/null +++ b/xhost/Makefile.am @@ -0,0 +1,40 @@ +bin_PROGRAMS = xhost + +xhost_SOURCES = xhost.c + +xhost_CFLAGS = @XHOST_CFLAGS@ + +xhost_LDADD = @XHOST_LIBS@ + +appman_PRE = xhost.man + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xhost/NEWS b/xhost/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xhost/README b/xhost/README new file mode 100644 index 0000000..e69de29 diff --git a/xhost/config.h.in b/xhost/config.h.in new file mode 100644 index 0000000..76b086a --- /dev/null +++ b/xhost/config.h.in @@ -0,0 +1,46 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if `struct sockaddr_in' has a `sin_len' member */ +#undef BSD44SOCKETS + +/* Define to 1 if you have the `authdes_create' function. */ +#undef HAVE_AUTHDES_CREATE + +/* Define to 1 if you have the `authdes_seccreate' function. */ +#undef HAVE_AUTHDES_SECCREATE + +/* Support IPv6 for TCP connections */ +#undef IPv6 + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Support Secure RPC ("SUN-DES-1") authentication for X11 clients */ +#undef SECURE_RPC + +/* Support TCP socket connections */ +#undef TCPCONN + +/* Support UNIX socket connections */ +#undef UNIXCONN + +/* Version number of package */ +#undef VERSION diff --git a/xhost/mkinstalldirs b/xhost/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xhost/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xinit/AUTHORS b/xinit/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xinit/COPYING b/xinit/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xinit/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xinit/INSTALL b/xinit/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xinit/Makefile.am b/xinit/Makefile.am new file mode 100644 index 0000000..ca72604 --- /dev/null +++ b/xinit/Makefile.am @@ -0,0 +1,102 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +XINITDIR = $(libdir)/X11/xinit + +bin_PROGRAMS = xinit +bin_SCRIPTS = startx + +xinit_CFLAGS = $(XINIT_CFLAGS) -DXINITDIR=\"$(XINITDIR)\" -DBINDIR=\"$(bindir)\" +xinit_LDADD = $(XINIT_LIBS) + +xinit_SOURCES = \ + xinit.c + +appmandir = $(APP_MAN_DIR) + +appman_PRE = \ + startx.man \ + xinit.man + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +# Translate XCOMM into pound sign with sed, rather than passing -DXCOMM=XCOMM +# to cpp, because that trick does not work on all ANSI C preprocessors. +# Delete line numbers from the cpp output (-P is not portable, I guess). +# Allow XCOMM to be preceded by whitespace and provide a means of generating +# output lines with trailing backslashes. +# Allow XHASH to always be substituted, even in cases where XCOMM isn't. + +CPP_SED_MAGIC = $(SED) -e '/^\# *[0-9][0-9]* *.*$$/d' \ + -e '/^\#line *[0-9][0-9]* *.*$$/d' \ + -e '/^[ ]*XCOMM$$/s/XCOMM/\#/' \ + -e '/^[ ]*XCOMM[^a-zA-Z0-9_]/s/XCOMM/\#/' \ + -e '/^[ ]*XHASH/s/XHASH/\#/' \ + -e '/\@\@$$/s/\@\@$$/\\/' + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MANDEFS = \ + -D__xorgversion__="\"$(XORGRELSTRING)\" \"$(XORGMANNAME)\"" \ + -D__appmansuffix__=$(APP_MAN_SUFFIX) \ + -D__filemansuffix__=$(FILE_MAN_SUFFIX) \ + -D__libmansuffix__=$(LIB_MAN_SUFFIX) \ + -D__miscmansuffix__=$(MISC_MAN_SUFFIX) \ + -D__XSERVERNAME__=Xorg -D__XCONFIGFILE__=xorg.conf \ + -D__xinitdir__=$(XINITDIR) \ + -DSHELL_CMD=$(SHELL_CMD) $(ARCHMANDEFS) + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + $(RAWCPP) $(RAWCPPFLAGS) $(MANDEFS) $(EXTRAMANDEFS) < $< | $(CPP_SED_MAGIC) > $@ + +xinitrcdir = $(XINITDIR) + +PROGCPPDEFS = \ + -DXRDB=@XRDB@ \ + -DXMODMAP=@XMODMAP@ \ + -DTWM=@TWM@ \ + -DXCLOCK=@XCLOCK@ \ + -DXTERM=@XTERM@ \ + -DXSERVER=@XSERVER@ \ + -DXAUTH=@XAUTH@ \ + -DXINIT=@XINIT@ + +SCRIPTDEFS = \ + -DXINITDIR=$(XINITDIR) $(PROGCPPDEFS) -DLIBDIR=$(libdir) \ + -DSHELL_CMD=$(SHELL_CMD) $(STARTX_COOKIE_FLAGS) + +xinitrc: xinitrc.cpp + $(RAWCPP) $(SCRIPTDEFS) < $(srcdir)/xinitrc.cpp | $(CPP_SED_MAGIC) > $@ + +startx: startx.cpp Makefile + $(RAWCPP) $(SCRIPTDEFS) < $(srcdir)/startx.cpp | $(CPP_SED_MAGIC) > $@ + +xinitrc_DATA = xinitrc + +CLEANFILES = xinitrc startx $(appman_DATA) + +EXTRA_DIST = xinitrc.cpp startx.cpp $(appman_PRE) \ + startx.cmd xinitrc.cmd xinit.def + diff --git a/xinit/NEWS b/xinit/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xinit/README b/xinit/README new file mode 100644 index 0000000..9bbe2c9 --- /dev/null +++ b/xinit/README @@ -0,0 +1,5 @@ +The xinit is not intended for naive users. Instead, site administrators should +design user-friendly scripts that present the desired interface when starting +up X. The startx script is one such example. + +Note that the sample xinitrc file is NOT installed by default. diff --git a/xinit/config.h.in b/xinit/config.h.in new file mode 100644 index 0000000..ed3ebc9 --- /dev/null +++ b/xinit/config.h.in @@ -0,0 +1,79 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define if you have Xorg X server */ +#undef XORG + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/xinit/mkinstalldirs b/xinit/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xinit/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xinit/startx.cmd b/xinit/startx.cmd new file mode 100644 index 0000000..cd37ecb --- /dev/null +++ b/xinit/startx.cmd @@ -0,0 +1,81 @@ +/* OS/2 REXX */ +/* $XFree86: xc/programs/xinit/startx.cmd,v 3.3 1996/10/17 15:23:47 dawes Exp $ + * + * This is just a sample implementation of a slightly less primitive + * interface than xinit. It looks for user xinitrc.cmd and xservrc.cmd + * files, then system xinitrc.cmd and xservrc.cmd files, else lets xinit choose + * its default. The system xinitrc should probably do things like check + * for Xresources files and merge them in, startup up a window manager, + * and pop a clock and serveral xterms. + * + * Site administrators are STRONGLY urged to write nicer versions. + */ +'@echo off' +ADDRESS CMD +env = 'OS2ENVIRONMENT' +x11root = VALUE('X11ROOT',,env) +IF x11root = '' THEN DO + SAY "The environment variable X11ROOT is not set. X/OS2 won't run without it." + EXIT +END + +home = VALUE('HOME',,env) +IF home = '' THEN home = x11root +os_shell = VALUE('X11SHELL',,env) +IF os_shell = '' THEN os_shell = VALUE('SHELL',,env) +IF os_shell = '' THEN os_shell = VALUE('OS2_SHELL',,env) +IF os_shell = '' THEN DO + SAY "There is no command interpreter in OS2_SHELL ???" + EXIT +END + +userclientrc = home'\xinitrc.cmd' +userserverrc = home'\xservrc.cmd' +sysclientrc = x11root'\usr\X11R6\lib\X11\xinit\xinitrc.cmd' +sysserverrc = x11root'\usr\X11R6\lib\X11\xinit\xservrc.cmd' +clientargs = '' +serverargs = '' + +IF exists(userclientrc) THEN + clientargs = userclientrc +ELSE +IF exists(sysclientrc) THEN + clientargs = sysclientrc + +IF exists(userserverrc) THEN + serverargs = userserverrc +ELSE +IF exists(sysserverrc) THEN + serverargs = sysserverrc + +whoseargs = "client" +PARSE ARG all + +DO i=1 TO WORDS(all) + cur = WORD(all,i) + IF \(FILESPEC('DRIVE',cur) = '') THEN DO + IF whoseargs = "client" THEN + clientargs = cur + ELSE + serverargs = cur + END + ELSE + IF cur = "--" THEN + whoseargs = "server" + ELSE + IF whoseargs = "client" THEN + clientargs = clientargs' 'cur + ELSE + serverargs = serverargs' 'cur +END + +xinit = x11root'\usr\X11R6\bin\xinit' +xinit os_shell' /c 'clientargs' -- 'serverargs + +RETURN + +exists: + IF STREAM(arg(1), 'C', 'QUERY EXISTS') = '' THEN + RETURN 0 + ELSE + RETURN 1 diff --git a/xinit/xinit.def b/xinit/xinit.def new file mode 100644 index 0000000..92c4176 --- /dev/null +++ b/xinit/xinit.def @@ -0,0 +1,4 @@ +NAME xinit NOTWINDOWCOMPAT +DESCRIPTION "@#XFREE86:4.4.0#@ $XFree86: xc/programs/xinit/xinit.def,v 3.2 2002/05/31 18:46:13 dawes Exp $" +PROTMODE +EXETYPE OS2 diff --git a/xinit/xinit.man b/xinit/xinit.man new file mode 100644 index 0000000..2ff692c --- /dev/null +++ b/xinit/xinit.man @@ -0,0 +1,200 @@ +.\" $Xorg: xinit.man,v 1.4 2001/02/09 02:05:49 xorgcvs Exp $ +.\" Copyright 1988, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/xinit/xinit.man,v 3.9 2001/02/07 23:25:56 dawes Exp $ +.\" +.TH XINIT 1 __xorgversion__ +.SH NAME +xinit \- X Window System initializer +.SH SYNOPSIS +.B xinit +[ [ +.I client +] +.I options +] [ +.B \-\^\- +[ +.I server +] [ +.I display +] +.I options +] +.SH DESCRIPTION +The \fIxinit\fP program is used to start the X Window System server and a first +client program on systems that +cannot start X directly from \fI/etc/init\fP or in environments +that use multiple window systems. When this first client exits, +\fIxinit\fP will kill the X server and then terminate. +.PP +If no specific client program is given on the command line, +\fIxinit\fP will look for a file in the user's home directory +called \fI.xinitrc\fP to run as a shell script to start up client programs. +If no such file exists, \fIxinit\fP will use the following as a default: +.sp + xterm \-geometry +1+1 \-n login \-display :0 +.sp +.PP +If no specific server program is given on the command line, +\fIxinit\fP will look for a file in the user's home directory +called \fI.xserverrc\fP to run as a shell script to start up the server. +If no such file exists, \fIxinit\fP will use the following as a default: +.sp + X :0 +.sp +Note that this assumes that there is a program named \fIX\fP in the current +search path. However, servers are usually named \fIXdisplaytype\fP where +\fIdisplaytype\fP is the type of graphics display which is driven by this +server. The site administrator should, therefore, make a link to the +appropriate type of server on the machine, or create a shell script that +runs \fIxinit\fP with the appropriate server. +.PP +Note, when using a \fI.xserverrc\fP script be sure to ``exec'' the real X server. +Failing to do this can make the X server slow to start and exit. For example: +.sp + exec Xdisplaytype +.PP +An important point is that programs which are run by \fI\.xinitrc\fP +should be run in the background if they do +not exit right away, so that they don't prevent other programs from +starting up. +However, the last long-lived program started (usually +a window manager or terminal emulator) should be +left in the foreground so that the script won't exit (which +indicates that the user is done and that \fIxinit\fP should exit). +.PP +An alternate client and/or server may be specified on the +command line. The desired client program and its arguments should be given +as the first command line arguments to \fIxinit\fP. To specify a particular +server command line, append a double dash (\-\^\-) to the \fIxinit\fP command +line (after any client and arguments) followed by the desired server command. +.PP +Both the client program name and the server program name must begin with a +slash (/) or a period (.). Otherwise, they are treated as an arguments to be +appended to their respective startup lines. This makes it possible to +add arguments (for example, foreground and background colors) without +having to retype the whole command line. +.PP +If an explicit server name is not given and the first argument following the +double dash (\-\^\-) is a colon followed by a digit, \fIxinit\fP will use that +number as the display +number instead of zero. All remaining arguments are appended to the server +command line. +.PP +.SH EXAMPLES +Below are several examples of how command line arguments in \fIxinit\fP are +used. +.TP 8 +.B "xinit" +This will start up a server named \fIX\fP and run the user's \fI\.xinitrc\fP, +if it exists, or else start an \fIxterm\fP. +.TP 8 +.B "xinit \-\^\- /usr/X11R6/bin/Xqdss :1" +This is how one could start a specific type of server on an alternate display. +.TP 8 +.B "xinit \-geometry =80x65+10+10 \-fn 8x13 \-j \-fg white \-bg navy" +This will start up a server named \fIX\fP, and will append the given +arguments to the default \fIxterm\fP command. It will ignore \fI\.xinitrc\fP. +.TP 8 +.B "xinit \-e widgets \-\^\- ./Xsun \-l \-c" +This will use the command \fI\.\/Xsun \-l \-c\fP to start the server and will +append the arguments \fI\-e widgets\fP to the default \fIxterm\fP command. +.TP 8 +.B "xinit /usr/ucb/rsh fasthost cpupig \-display ws:1 \-\^\- :1 \-a 2 \-t 5" +This will start a server named \fIX\fP on display 1 with the arguments +\fI\-a 2 \-t 5\fP. It will then start a remote shell on the machine +\fBfasthost\fP in which it will run the command \fIcpupig\fP, telling it +to display back on the local workstation. +.PP +Below is a sample \fI\.xinitrc\fP that starts a clock, several terminals, and +leaves the window manager running as the ``last'' application. Assuming that +the window manager has been configured properly, the user +then chooses the ``Exit'' menu item to shut down X. +.sp +.in +8 +.nf +xrdb \-load $HOME/.Xresources +xsetroot \-solid gray & +xclock \-g 50x50\-0+0 \-bw 0 & +xload \-g 50x50\-50+0 \-bw 0 & +xterm \-g 80x24+0+0 & +xterm \-g 80x24+0\-0 & +twm +.fi +.in -8 +.sp +Sites that want to create a common startup environment could simply create +a default \fI\.xinitrc\fP that references a site-wide startup file: +.sp +.in +8 +.nf +\&#!/bin/sh +\&. /usr/local/lib/site.xinitrc +.fi +.in -8 +.sp +Another approach is to write a script that starts \fIxinit\fP with a specific +shell script. Such scripts are usually named \fIx11\fP, \fIxstart\fP, or +\fIstartx\fP and are a convenient way to provide a simple interface for +novice users: +.sp +.in +8 +.nf +\&#!/bin/sh +xinit /usr/local/lib/site.xinitrc \-\^\- /usr/X11R6/bin/X bc +.fi +.in -8 +.sp +.SH "ENVIRONMENT VARIABLES" +.TP 15 +.B DISPLAY +This variable gets set to the name of the display to which clients should +connect. +.TP 15 +.B XINITRC +This variable specifies an init file containing shell commands to start up the +initial windows. By default, \fI\.xinitrc\fP in the home directory will be +used. +.SH FILES +.TP 15 +.I .xinitrc +default client script +.TP 15 +.I xterm +client to run if \fI.xinitrc\fP does not exist +.TP 15 +.I .xserverrc +default server script +.TP 15 +.I X +server to run if \fI.xserverrc\fP does not exist +.SH "SEE ALSO" +.IR X (__miscmansuffix__), +.IR startx (1), +.IR Xserver (1), +.IR xterm (1) +.SH AUTHOR +Bob Scheifler, MIT Laboratory for Computer Science diff --git a/xinit/xinitrc.cmd b/xinit/xinitrc.cmd new file mode 100644 index 0000000..f40a7b7 --- /dev/null +++ b/xinit/xinitrc.cmd @@ -0,0 +1,62 @@ +/* OS/2 REXX */ +/* $XFree86: xc/programs/xinit/xinitrc.cmd,v 3.5 1997/01/27 08:26:14 dawes Exp $ */ +'@echo off' +env = 'OS2ENVIRONMENT' +x11root = VALUE('X11ROOT',,env) +IF x11root = '' THEN DO + SAY "The environment variable X11ROOT is not set. X/OS2 won't run without it." + EXIT +END +home = VALUE('HOME',,env) +IF home = '' THEN home = x11root + +userresources = home'\.Xresources' +usermodmap = home'\.Xmodmap' +sysresources = x11root'\usr\X11R6\lib\X11\xinit\.Xresources' +sysmodmap = x11root'\usr\X11R6\lib\X11\xinit\.Xmodmap' +xbitmapdir = x11root'\usr\X11R6\include\X11\bitmaps' +manpath = VALUE('MANPATH',,env) + +/* merge in defaults */ +IF exists(sysresources) THEN + 'xrdb -merge 'sysresources + +IF exists(sysmodmap) THEN + 'xmodmap 'sysmodmap + +IF exists(userresources) THEN + 'xrdb -merge 'userresources + +IF exists(usermodmap) THEN + 'xmodmap 'usermodmap + +/* start some nice :-) test programs */ +'xsetroot -bitmap 'xbitmapdir'\xos2' +/* also try out the following ones: + * 'xsetroot -bitmap 'xbitmapdir'\xfree1' + * 'xsetroot -bitmap 'xbitmapdir'\xfree2' + */ + +/****** WARNING! ********* + * Below some programs are started minimized, some are started detached. + * In general, those that spawn other shells are minimized, others may be + * detached. You might be tempted to run the xterm's as well as detached. + * This works, but leaves you with an independent xterm/cmd pair, when the + * server shuts down, which you can only see in watchcat, not the process list. + * If you start and stop x11 multiple times, this will let you run out of + * PTYs, and will lead to a large number of background sessions. + */ +'detach xclock -update 1 -geometry 100x100-1+1' +'start/min/n "Login Xterm" xterm -sb -geometry 80x25+0+0 -name login' +IF manpath \= '' THEN + 'detach xman -geometry 100x100-105+1' +/* 'startx/min/n "Xterm 1" xterm -sb -geometry 80x50+494+51' */ +/* 'startx/min/n "Xterm 2" xterm -sb -geometry 80x20+494-0' */ +'twm' + +EXIT + +exists: +'DIR "'arg(1)'" >nul 2>&1' +if rc = 0 THEN RETURN 1 +RETURN 0 diff --git a/xinit/xinitrc.cpp b/xinit/xinitrc.cpp new file mode 100644 index 0000000..4f52f13 --- /dev/null +++ b/xinit/xinitrc.cpp @@ -0,0 +1,75 @@ +XCOMM!SHELL_CMD +XCOMM $Xorg: xinitrc.cpp,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ + +userresources=$HOME/.Xresources +usermodmap=$HOME/.Xmodmap +sysresources=XINITDIR/.Xresources +sysmodmap=XINITDIR/.Xmodmap + +XCOMM merge in defaults and keymaps + +if [ -f $sysresources ]; then + XRDB -merge $sysresources +fi + +if [ -f $sysmodmap ]; then + XMODMAP $sysmodmap +fi + +if [ -f $userresources ]; then + XRDB -merge $userresources +fi + +if [ -f $usermodmap ]; then + XMODMAP $usermodmap +fi + +XCOMM start some nice programs + +#if defined(__SCO__) || defined(__UNIXWARE__) +if [ -r /etc/default/xdesktops ]; then + . /etc/default/xdesktops +fi + +if [ -r $HOME/.x11rc ]; then + . $HOME/.x11rc +else + if [ -r /etc/default/X11 ]; then + . /etc/default/X11 + fi +fi + +#if defined(__SCO__) +if [ -n "$XSESSION" ]; then + case "$XSESSION" in + [Yy][Ee][Ss]) + [ -x /usr/bin/X11/scosession ] && exec /usr/bin/X11/scosession + ;; + esac +fi + +if [ -n "$XDESKTOP" ]; then + exec `eval echo $"$XDESKTOP"` +else + if [ -x /usr/bin/X11/pmwm -a -x /usr/bin/X11/scoterm ]; then + /usr/bin/X11/scoterm 2> /dev/null & + exec /usr/bin/X11/pmwm 2> /dev/null + fi +fi +#elif defined(__UNIXWARE__) +if [ -n "$XDESKTOP" ]; then + exec `eval echo $"$XDESKTOP"` +else + if [ -x /usr/X/bin/pmwm ]; then + exec /usr/X/bin/pmwm 2> /dev/null + fi +fi +#endif + +XCOMM This is the fallback case if nothing else is executed above +#endif /* !defined(__SCO__) && !defined(__UNIXWARE__) */ +TWM & +XCLOCK -geometry 50x50-1+1 & +XTERM -geometry 80x50+494+51 & +XTERM -geometry 80x20+494-0 & +exec XTERM -geometry 80x66+0+0 -name login diff --git a/xkbcomp/AUTHORS b/xkbcomp/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xkbcomp/COPYING b/xkbcomp/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xkbcomp/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xkbcomp/INSTALL b/xkbcomp/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xkbcomp/Makefile.am b/xkbcomp/Makefile.am new file mode 100644 index 0000000..3e63535 --- /dev/null +++ b/xkbcomp/Makefile.am @@ -0,0 +1,100 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xkbcomp + +AM_CFLAGS = $(XKBCOMP_CFLAGS) -DDFLT_XKB_CONFIG_ROOT='"$(datadir)/X11/xkb"' +xkbcomp_LDADD = $(XKBCOMP_LIBS) + +xkbcomp_SOURCES = \ + action.c \ + action.h \ + alias.c \ + alias.h \ + compat.c \ + compat.h \ + expr.c \ + expr.h \ + geometry.c \ + indicators.c \ + indicators.h \ + keycodes.c \ + keycodes.h \ + keymap.c \ + keytypes.c \ + listing.c \ + misc.c \ + misc.h \ + parseutils.c \ + parseutils.h \ + symbols.c \ + tokens.h \ + utils.c \ + utils.h \ + vmod.c \ + vmod.h \ + xkbcomp.c \ + xkbcomp.h \ + xkbparse.y \ + xkbpath.c \ + xkbpath.h \ + xkbscan.c + +appman_PRE = \ + xkbcomp.man + +BUILT_SOURCES = xkbparse.c +MAINTAINERCLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = \ + README.config \ + README.enhancing + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST += $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xkbcomp/NEWS b/xkbcomp/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xkbcomp/README b/xkbcomp/README new file mode 100644 index 0000000..8dd7a58 --- /dev/null +++ b/xkbcomp/README @@ -0,0 +1,25 @@ +X Keyboard Extension +-------------------- + +The X Keyboard Extension essentially replaces the core protocol definition of +keyboard. The extension makes possible to clearly and explicitly specify most +aspects of keyboard behaviour on per-key basis and to more closely track the +logical and physical state of the keyboard. It also includes a number of +keyboard controls designed to make keyboards more accessible to people with +physical impairments. + +There are five types of components in the server database corresponing to five +xkb symbolic names: symbols, geometry, keycodes, compat and types which +determine the keyboard behaviour. These five components can combined together +into a resulting keyboard mapping using the 'rules' component. + +The complete specification can be found on +http://www.x-docs.org/XKB/XKBproto.pdf + +For XKB configuration information see 'README.config' file. + +For information how to further enhance XKB configuration see 'README.enhancing' +file. + + +$XFree86$ diff --git a/xkbcomp/action.c b/xkbcomp/action.c new file mode 100644 index 0000000..023d1eb --- /dev/null +++ b/xkbcomp/action.c @@ -0,0 +1,1252 @@ +/* $Xorg: action.c,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/action.c,v 3.10tsi Exp $ */ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" + +#include "keycodes.h" +#include "vmod.h" +#include "misc.h" +#include "action.h" +#include "misc.h" + +static Bool actionsInitialized; +static ExprDef constTrue; +static ExprDef constFalse; + +/***====================================================================***/ + +static Bool +stringToAction(char *str,unsigned *type_rtrn) +{ + if (str==NULL) + return False; + + if (uStrCaseCmp(str,"noaction")==0) *type_rtrn= XkbSA_NoAction; + else if (uStrCaseCmp(str,"setmods")==0) *type_rtrn= XkbSA_SetMods; + else if (uStrCaseCmp(str,"latchmods")==0) *type_rtrn= XkbSA_LatchMods; + else if (uStrCaseCmp(str,"lockmods")==0) *type_rtrn= XkbSA_LockMods; + else if (uStrCaseCmp(str,"setgroup")==0) *type_rtrn= XkbSA_SetGroup; + else if (uStrCaseCmp(str,"latchgroup")==0) *type_rtrn= XkbSA_LatchGroup; + else if (uStrCaseCmp(str,"lockgroup")==0) *type_rtrn= XkbSA_LockGroup; + else if (uStrCaseCmp(str,"moveptr")==0) *type_rtrn= XkbSA_MovePtr; + else if (uStrCaseCmp(str,"movepointer")==0) *type_rtrn= XkbSA_MovePtr; + else if (uStrCaseCmp(str,"ptrbtn")==0) *type_rtrn= XkbSA_PtrBtn; + else if (uStrCaseCmp(str,"pointerbutton")==0) + *type_rtrn= XkbSA_PtrBtn; + else if (uStrCaseCmp(str,"lockptrbtn")==0) *type_rtrn= XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str,"lockpointerbutton")==0) + *type_rtrn= XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str,"lockptrbutton")==0) + *type_rtrn= XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str,"lockpointerbtn")==0) + *type_rtrn= XkbSA_LockPtrBtn; + else if (uStrCaseCmp(str,"setptrdflt")==0) *type_rtrn= XkbSA_SetPtrDflt; + else if (uStrCaseCmp(str,"setpointerdefault")==0) + *type_rtrn= XkbSA_SetPtrDflt; + else if (uStrCaseCmp(str,"isolock")==0) *type_rtrn= XkbSA_ISOLock; + else if (uStrCaseCmp(str,"terminate")==0) *type_rtrn= XkbSA_Terminate; + else if (uStrCaseCmp(str,"terminateserver")==0) + *type_rtrn= XkbSA_Terminate; + else if (uStrCaseCmp(str,"switchscreen")==0)*type_rtrn= XkbSA_SwitchScreen; + else if (uStrCaseCmp(str,"setcontrols")==0) *type_rtrn= XkbSA_SetControls; + else if (uStrCaseCmp(str,"lockcontrols")==0)*type_rtrn= XkbSA_LockControls; + else if (uStrCaseCmp(str,"actionmessage")==0)*type_rtrn= XkbSA_ActionMessage; + else if (uStrCaseCmp(str,"messageaction")==0)*type_rtrn= XkbSA_ActionMessage; + else if (uStrCaseCmp(str,"message")==0) *type_rtrn= XkbSA_ActionMessage; + else if (uStrCaseCmp(str,"redirect")==0) *type_rtrn= XkbSA_RedirectKey; + else if (uStrCaseCmp(str,"redirectkey")==0) *type_rtrn= XkbSA_RedirectKey; + else if (uStrCaseCmp(str,"devbtn")==0) *type_rtrn= XkbSA_DeviceBtn; + else if (uStrCaseCmp(str,"devicebtn")==0) *type_rtrn= XkbSA_DeviceBtn; + else if (uStrCaseCmp(str,"devbutton")==0) *type_rtrn= XkbSA_DeviceBtn; + else if (uStrCaseCmp(str,"devicebutton")==0)*type_rtrn= XkbSA_DeviceBtn; + else if (uStrCaseCmp(str,"lockdevbtn")==0) *type_rtrn= XkbSA_DeviceBtn; + else if (uStrCaseCmp(str,"lockdevicebtn")==0) + *type_rtrn= XkbSA_LockDeviceBtn; + else if (uStrCaseCmp(str,"lockdevbutton")==0) + *type_rtrn= XkbSA_LockDeviceBtn; + else if (uStrCaseCmp(str,"lockdevicebutton")==0) + *type_rtrn= XkbSA_LockDeviceBtn; + else if (uStrCaseCmp(str,"devval")==0) *type_rtrn=XkbSA_DeviceValuator; + else if (uStrCaseCmp(str,"deviceval")==0) *type_rtrn=XkbSA_DeviceValuator; + else if (uStrCaseCmp(str,"devvaluator")==0) *type_rtrn=XkbSA_DeviceValuator; + else if (uStrCaseCmp(str,"devicevaluator")==0) + *type_rtrn=XkbSA_DeviceValuator; + else if (uStrCaseCmp(str,"private")==0) *type_rtrn= PrivateAction; + else return False; + return True; +} + +static Bool +stringToField(char *str,unsigned *field_rtrn) +{ + + if (str==NULL) + return False; + + if (uStrCaseCmp(str,"clearlocks")==0) *field_rtrn= F_ClearLocks; + else if (uStrCaseCmp(str,"latchtolock")==0) *field_rtrn= F_LatchToLock; + else if (uStrCaseCmp(str,"genkeyevent")==0) *field_rtrn= F_GenKeyEvent; + else if (uStrCaseCmp(str,"generatekeyevent")==0) + *field_rtrn= F_GenKeyEvent; + else if (uStrCaseCmp(str,"report")==0) *field_rtrn= F_Report; + else if (uStrCaseCmp(str,"default")==0) *field_rtrn= F_Default; + else if (uStrCaseCmp(str,"affect")==0) *field_rtrn= F_Affect; + else if (uStrCaseCmp(str,"increment")==0) *field_rtrn= F_Increment; + else if (uStrCaseCmp(str,"mods")==0) *field_rtrn= F_Modifiers; + else if (uStrCaseCmp(str,"modifiers")==0) *field_rtrn= F_Modifiers; + else if (uStrCaseCmp(str,"group")==0) *field_rtrn= F_Group; + else if (uStrCaseCmp(str,"x")==0) *field_rtrn= F_X; + else if (uStrCaseCmp(str,"y")==0) *field_rtrn= F_Y; + else if (uStrCaseCmp(str,"accel")==0) *field_rtrn= F_Accel; + else if (uStrCaseCmp(str,"accelerate")==0) *field_rtrn= F_Accel; + else if (uStrCaseCmp(str,"repeat")==0) *field_rtrn= F_Accel; + else if (uStrCaseCmp(str,"button")==0) *field_rtrn= F_Button; + else if (uStrCaseCmp(str,"value")==0) *field_rtrn= F_Value; + else if (uStrCaseCmp(str,"controls")==0) *field_rtrn= F_Controls; + else if (uStrCaseCmp(str,"ctrls")==0) *field_rtrn= F_Controls; + else if (uStrCaseCmp(str,"type")==0) *field_rtrn= F_Type; + else if (uStrCaseCmp(str,"count")==0) *field_rtrn= F_Count; + else if (uStrCaseCmp(str,"screen")==0) *field_rtrn= F_Screen; + else if (uStrCaseCmp(str,"same")==0) *field_rtrn= F_Same; + else if (uStrCaseCmp(str,"sameserver")==0) *field_rtrn= F_Same; + else if (uStrCaseCmp(str,"data")==0) *field_rtrn= F_Data; + else if (uStrCaseCmp(str,"device")==0) *field_rtrn= F_Device; + else if (uStrCaseCmp(str,"dev")==0) *field_rtrn= F_Device; + else if (uStrCaseCmp(str,"key")==0) *field_rtrn= F_Keycode; + else if (uStrCaseCmp(str,"keycode")==0) *field_rtrn= F_Keycode; + else if (uStrCaseCmp(str,"kc")==0) *field_rtrn= F_Keycode; + else if (uStrCaseCmp(str,"clearmods")==0) *field_rtrn= F_ModsToClear; + else if (uStrCaseCmp(str,"clearmodifiers")==0) *field_rtrn= F_ModsToClear; + else return False; + return True; +} + +static char * +fieldText(unsigned field) +{ +static char buf[32]; + + switch (field) { + case F_ClearLocks: strcpy(buf,"clearLocks"); break; + case F_LatchToLock: strcpy(buf,"latchToLock"); break; + case F_GenKeyEvent: strcpy(buf,"genKeyEvent"); break; + case F_Report: strcpy(buf,"report"); break; + case F_Default: strcpy(buf,"default"); break; + case F_Affect: strcpy(buf,"affect"); break; + case F_Increment: strcpy(buf,"increment"); break; + case F_Modifiers: strcpy(buf,"modifiers"); break; + case F_Group: strcpy(buf,"group"); break; + case F_X: strcpy(buf,"x"); break; + case F_Y: strcpy(buf,"y"); break; + case F_Accel: strcpy(buf,"accel"); break; + case F_Button: strcpy(buf,"button"); break; + case F_Value: strcpy(buf,"value"); break; + case F_Controls: strcpy(buf,"controls"); break; + case F_Type: strcpy(buf,"type"); break; + case F_Count: strcpy(buf,"count"); break; + case F_Screen: strcpy(buf,"screen"); break; + case F_Same: strcpy(buf,"sameServer"); break; + case F_Data: strcpy(buf,"data"); break; + case F_Device: strcpy(buf,"device"); break; + case F_Keycode: strcpy(buf,"keycode"); break; + case F_ModsToClear: strcpy(buf,"clearmods"); break; + default: strcpy(buf,"unknown"); break; + } + return buf; +} + +/***====================================================================***/ + +static Bool +ReportMismatch(unsigned action,unsigned field,char *type) +{ + ERROR2("Value of %s field must be of type %s\n",fieldText(field),type); + ACTION1("Action %s definition ignored\n", + XkbActionTypeText(action,XkbMessage)); + return False; +} + +static Bool +ReportIllegal(unsigned action,unsigned field) +{ + ERROR2("Field %s is not defined for an action of type %s\n", + fieldText(field), + XkbActionTypeText(action,XkbMessage)); + ACTION("Action definition ignored\n"); + return False; +} + +static Bool +ReportActionNotArray(unsigned action,unsigned field) +{ + ERROR2("The %s field in the %s action is not an array\n", + fieldText(field), + XkbActionTypeText(action,XkbMessage)); + ACTION("Action definition ignored\n"); + return False; +} + +static Bool +ReportNotFound(unsigned action,unsigned field,char *what,char *bad) +{ + ERROR2("%s named %s not found\n",what,bad); + ACTION2("Ignoring the %s field of an %s action\n",fieldText(field), + XkbActionTypeText(action,XkbMessage)); + return False; +} + +static Bool +HandleNoAction( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ + return ReportIllegal(action->type,field); +} + +static Bool +CheckLatchLockFlags( unsigned action, + unsigned field, + ExprDef * value, + unsigned * flags_inout) +{ +unsigned tmp; +ExprResult result; + + if (field==F_ClearLocks) tmp= XkbSA_ClearLocks; + else if (field==F_LatchToLock) tmp= XkbSA_LatchToLock; + else return False; /* WSGO! */ + if (!ExprResolveBoolean(value,&result,NULL,NULL)) + return ReportMismatch(action,field,"boolean"); + if (result.uval) *flags_inout|= tmp; + else *flags_inout&= ~tmp; + return True; +} + +static Bool +CheckModifierField( XkbDescPtr xkb, + unsigned action, + ExprDef * value, + unsigned * flags_inout, + unsigned * mods_rtrn) +{ +ExprResult rtrn; + + if (value->op==ExprIdent) { + register char *valStr; + valStr= XkbAtomGetString(NULL,value->value.str); + if (valStr&&((uStrCaseCmp(valStr,"usemodmapmods")==0)|| + (uStrCaseCmp(valStr,"modmapmods")==0))) { + + *mods_rtrn= 0; + *flags_inout|= XkbSA_UseModMapMods; + return True; + } + } + if (!ExprResolveModMask(value,&rtrn,LookupVModMask,(XPointer)xkb)) + return ReportMismatch(action,F_Modifiers,"modifier mask"); + *mods_rtrn= rtrn.uval; + *flags_inout&= ~XkbSA_UseModMapMods; + return True; +} + +static Bool +HandleSetLatchMods( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +XkbModAction * act; +unsigned rtrn; +unsigned t1,t2; + + act= (XkbModAction *)action; + if (array_ndx!=NULL) { + switch (field) { + case F_ClearLocks: case F_LatchToLock: + case F_Modifiers: + return ReportActionNotArray(action->type,field); + } + } + switch (field) { + case F_ClearLocks: + case F_LatchToLock: + rtrn= act->flags; + if (CheckLatchLockFlags(action->type,field,value,&rtrn)) { + act->flags= rtrn; + return True; + } + return False; + case F_Modifiers: + t1= act->flags; + if (CheckModifierField(xkb,action->type,value,&t1,&t2)) { + act->flags= t1; + act->real_mods= act->mask= (t2&0xff); + t2= (t2>>8)&0xffff; + XkbSetModActionVMods(act,t2); + return True; + } + return False; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleLockMods( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +XkbModAction * act; +unsigned t1,t2; + + act= (XkbModAction *)action; + if ((array_ndx!=NULL)&&(field==F_Modifiers)) + return ReportActionNotArray(action->type,field); + switch (field) { + case F_Modifiers: + t1= act->flags; + if (CheckModifierField(xkb,action->type,value,&t1,&t2)) { + act->flags= t1; + act->real_mods= act->mask= (t2&0xff); + t2= (t2>>8)&0xffff; + XkbSetModActionVMods(act,t2); + return True; + } + return False; + } + return ReportIllegal(action->type,field); +} + +static LookupEntry groupNames[] = { + { "group1", 1 }, + { "group2", 2 }, + { "group3", 3 }, + { "group4", 4 }, + { "group5", 5 }, + { "group6", 6 }, + { "group7", 7 }, + { "group8", 8 }, + { NULL, 0 }, +}; + +static Bool +CheckGroupField( unsigned action, + ExprDef * value, + unsigned * flags_inout, + int * grp_rtrn) +{ +ExprDef * spec; +ExprResult rtrn; + + if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) { + *flags_inout&= ~XkbSA_GroupAbsolute; + spec= value->value.child; + } + else { + *flags_inout|= XkbSA_GroupAbsolute; + spec= value; + } + + if (!ExprResolveInteger(spec,&rtrn,SimpleLookup,(XPointer)groupNames)) + return ReportMismatch(action,F_Group,"integer (range 1..8)"); + if ((rtrn.ival<1)||(rtrn.ival>XkbNumKbdGroups)) { + ERROR2("Illegal group %d (must be in the range 1..%d)\n",rtrn.ival, + XkbNumKbdGroups); + ACTION1("Action %s definition ignored\n", + XkbActionTypeText(action,XkbMessage)); + return False; + } + if (value->op==OpNegate) *grp_rtrn= -rtrn.ival; + else if (value->op==OpUnaryPlus) *grp_rtrn= rtrn.ival; + else *grp_rtrn= rtrn.ival-1; + return True; +} + +static Bool +HandleSetLatchGroup( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +XkbGroupAction * act; +unsigned rtrn; +unsigned t1; +int t2; + + act= (XkbGroupAction *)action; + if (array_ndx!=NULL) { + switch (field) { + case F_ClearLocks: case F_LatchToLock: + case F_Group: + return ReportActionNotArray(action->type,field); + } + } + switch (field) { + case F_ClearLocks: + case F_LatchToLock: + rtrn= act->flags; + if (CheckLatchLockFlags(action->type,field,value,&rtrn)) { + act->flags= rtrn; + return True; + } + return False; + case F_Group: + t1= act->flags; + if (CheckGroupField(action->type,value,&t1,&t2)) { + act->flags= t1; + XkbSASetGroup(act,t2); + return True; + } + return False; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleLockGroup( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +XkbGroupAction * act; +unsigned t1; +int t2; + + act= (XkbGroupAction *)action; + if ((array_ndx!=NULL) && (field==F_Group)) + return ReportActionNotArray(action->type,field); + if (field==F_Group) { + t1= act->flags; + if (CheckGroupField(action->type,value,&t1,&t2)) { + act->flags= t1; + XkbSASetGroup(act,t2); + return True; + } + return False; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleMovePtr( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbPtrAction * act; +Bool absolute; + + act= (XkbPtrAction *)action; + if ((array_ndx!=NULL)&&((field==F_X)||(field==F_Y))) + return ReportActionNotArray(action->type,field); + + if ((field==F_X)||(field==F_Y)) { + if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) + absolute= False; + else absolute= True; + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"integer"); + if (field==F_X) { + if (absolute) + act->flags|= XkbSA_MoveAbsoluteX; + XkbSetPtrActionX(act,rtrn.ival); + } + else { + if (absolute) + act->flags|= XkbSA_MoveAbsoluteY; + XkbSetPtrActionY(act,rtrn.ival); + } + return True; + } + else if (field==F_Accel) { + if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"boolean"); + if (rtrn.uval) act->flags&= ~XkbSA_NoAcceleration; + else act->flags|= XkbSA_NoAcceleration; + } + return ReportIllegal(action->type,field); +} + +static LookupEntry btnNames[] = { + { "button1", 1 }, + { "button2", 2 }, + { "button3", 3 }, + { "button4", 4 }, + { "button5", 5 }, + { "default", 0 }, + { NULL, 0 } +}; + +static LookupEntry lockWhich[] = { + { "both", 0 }, + { "lock", XkbSA_LockNoUnlock }, + { "neither", (XkbSA_LockNoLock|XkbSA_LockNoUnlock) }, + { "unlock", XkbSA_LockNoLock }, + { NULL, 0 } +}; + +static Bool +HandlePtrBtn( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbPtrBtnAction * act; + + act= (XkbPtrBtnAction *)action; + if (field==F_Button) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames)) + return ReportMismatch(action->type,field,"integer (range 1..5)"); + if ((rtrn.ival<0)||(rtrn.ival>5)) { + ERROR("Button must specify default or be in the range 1..5\n"); + ACTION1("Illegal button value %d ignored\n",rtrn.ival); + return False; + } + act->button= rtrn.ival; + return True; + } + else if ((action->type==XkbSA_LockPtrBtn)&&(field==F_Affect)) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveEnum(value,&rtrn,lockWhich)) + return ReportMismatch(action->type,field,"lock or unlock"); + act->flags&= ~(XkbSA_LockNoLock|XkbSA_LockNoUnlock); + act->flags|= rtrn.ival; + return True; + } + else if (field==F_Count) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames)) + return ReportMismatch(action->type,field,"integer"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("The count field must have a value in the range 0..255\n"); + ACTION1("Illegal count %d ignored\n",rtrn.ival); + return False; + } + act->count= rtrn.ival; + return True; + } + return ReportIllegal(action->type,field); +} + +static LookupEntry ptrDflts[] = { + { "dfltbtn", XkbSA_AffectDfltBtn }, + { "defaultbutton", XkbSA_AffectDfltBtn }, + { "button", XkbSA_AffectDfltBtn }, + { NULL, 0 } +}; + +static Bool +HandleSetPtrDflt( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbPtrDfltAction * act; + + act= (XkbPtrDfltAction *)action; + if (field==F_Affect) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveEnum(value,&rtrn,ptrDflts)) + return ReportMismatch(action->type,field,"pointer component"); + act->affect= rtrn.uval; + return True; + } + else if ((field==F_Button)||(field==F_Value)) { + ExprDef *btn; + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) { + act->flags&= ~XkbSA_DfltBtnAbsolute; + btn= value->value.child; + } + else { + act->flags|= XkbSA_DfltBtnAbsolute; + btn= value; + } + + if (!ExprResolveInteger(btn,&rtrn,SimpleLookup,(XPointer)btnNames)) + return ReportMismatch(action->type,field,"integer (range 1..5)"); + if ((rtrn.ival<0)||(rtrn.ival>5)) { + ERROR("New default button value must be in the range 1..5\n"); + ACTION1("Illegal default button value %d ignored\n",rtrn.ival); + return False; + } + if (rtrn.ival==0) { + ERROR("Cannot set default pointer button to \"default\"\n"); + ACTION("Illegal default button setting ignored\n"); + return False; + } + if (value->op==OpNegate) + XkbSASetPtrDfltValue(act,-rtrn.ival); + else XkbSASetPtrDfltValue(act,rtrn.ival); + return True; + } + return ReportIllegal(action->type,field); +} + +static LookupEntry isoNames[] = { + { "mods", XkbSA_ISONoAffectMods }, + { "modifiers", XkbSA_ISONoAffectMods }, + { "group", XkbSA_ISONoAffectGroup }, + { "groups", XkbSA_ISONoAffectGroup }, + { "ptr", XkbSA_ISONoAffectPtr }, + { "pointer", XkbSA_ISONoAffectPtr }, + { "ctrls", XkbSA_ISONoAffectCtrls }, + { "controls", XkbSA_ISONoAffectCtrls }, + { "all", ~((unsigned)0) }, + { "none", 0 }, + { NULL, 0 }, +}; + +static Bool +HandleISOLock( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbISOAction * act; +unsigned flags,mods; +int group; + + act= (XkbISOAction *)action; + switch (field) { + case F_Modifiers: + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + flags= act->flags; + if (CheckModifierField(xkb,action->type,value,&flags,&mods)) { + act->flags= flags&(~XkbSA_ISODfltIsGroup); + act->real_mods= mods&0xff; + mods= (mods>>8)&0xff; + XkbSetModActionVMods(act,mods); + return True; + } + return False; + case F_Group: + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + flags= act->flags; + if (CheckGroupField(action->type,value,&flags,&group)) { + act->flags= flags|XkbSA_ISODfltIsGroup; + XkbSASetGroup(act,group); + return True; + } + return False; + case F_Affect: + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)isoNames)) + return ReportMismatch(action->type,field,"keyboard component"); + act->affect= (~rtrn.uval)&XkbSA_ISOAffectMask; + return True; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleSwitchScreen( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbSwitchScreenAction * act; + + act= (XkbSwitchScreenAction *)action; + if (field==F_Screen) { + ExprDef *scrn; + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if ((value->op==OpNegate)||(value->op==OpUnaryPlus)) { + act->flags&= ~XkbSA_SwitchAbsolute; + scrn= value->value.child; + } + else { + act->flags|= XkbSA_SwitchAbsolute; + scrn= value; + } + + if (!ExprResolveInteger(scrn,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"integer (0..255)"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("Screen index must be in the range 1..255\n"); + ACTION1("Illegal screen value %d ignored\n",rtrn.ival); + return False; + } + if (value->op==OpNegate) + XkbSASetScreen(act,-rtrn.ival); + else XkbSASetScreen(act,rtrn.ival); + return True; + } + else if (field==F_Same) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"boolean"); + if (rtrn.uval) act->flags&= ~XkbSA_SwitchApplication; + else act->flags|= XkbSA_SwitchApplication; + return True; + } + return ReportIllegal(action->type,field); +} + +LookupEntry ctrlNames[]= { + { "repeatkeys", XkbRepeatKeysMask }, + { "repeat", XkbRepeatKeysMask }, + { "autorepeat", XkbRepeatKeysMask }, + { "slowkeys", XkbSlowKeysMask }, + { "bouncekeys", XkbBounceKeysMask }, + { "stickykeys", XkbStickyKeysMask }, + { "mousekeys", XkbMouseKeysMask }, + { "mousekeysaccel", XkbMouseKeysAccelMask }, + { "accessxkeys", XkbAccessXKeysMask }, + { "accessxtimeout", XkbAccessXTimeoutMask }, + { "accessxfeedback", XkbAccessXFeedbackMask }, + { "audiblebell", XkbAudibleBellMask }, + { "overlay1", XkbOverlay1Mask }, + { "overlay2", XkbOverlay2Mask }, + { "ignoregrouplock", XkbIgnoreGroupLockMask }, + { "all", XkbAllBooleanCtrlsMask }, + { "none", 0 }, + { NULL, 0 } +}; + +static Bool +HandleSetLockControls( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbCtrlsAction * act; + + act= (XkbCtrlsAction *)action; + if (field==F_Controls) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)ctrlNames)) + return ReportMismatch(action->type,field,"controls mask"); + XkbActionSetCtrls(act,rtrn.uval); + return True; + } + return ReportIllegal(action->type,field); +} + +static LookupEntry evNames[]= { + { "press", XkbSA_MessageOnPress }, + { "keypress", XkbSA_MessageOnPress }, + { "release", XkbSA_MessageOnRelease }, + { "keyrelease", XkbSA_MessageOnRelease }, + { "all", XkbSA_MessageOnPress|XkbSA_MessageOnRelease }, + { "none", 0 }, + { NULL, 0 } +}; + +static Bool +HandleActionMessage( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbMessageAction * act; + + act= (XkbMessageAction *)action; + switch (field) { + case F_Report: + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)evNames)) + return ReportMismatch(action->type,field,"key event mask"); + act->flags&= ~(XkbSA_MessageOnPress|XkbSA_MessageOnRelease); + act->flags= rtrn.uval&(XkbSA_MessageOnPress|XkbSA_MessageOnRelease); + return True; + case F_GenKeyEvent: + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"boolean"); + if (rtrn.uval) act->flags|= XkbSA_MessageGenKeyEvent; + else act->flags&= ~XkbSA_MessageGenKeyEvent; + return True; + case F_Data: + if (array_ndx==NULL) { + if (!ExprResolveString(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"string"); + else { + int len= strlen(rtrn.str); + if ((len<1)||(len>6)) { + WARN("An action message can hold only 6 bytes\n"); + ACTION1("Extra %d bytes ignored\n",len-6); + } + strncpy((char *)act->message,rtrn.str,6); + } + return True; + } + else { + unsigned ndx; + if (!ExprResolveInteger(array_ndx,&rtrn,NULL,NULL)) { + ERROR("Array subscript must be integer\n"); + ACTION("Illegal subscript ignored\n"); + return False; + } + ndx= rtrn.uval; + if (ndx>5) { + ERROR("An action message is at most 6 bytes long\n"); + ACTION1("Attempt to use data[%d] ignored\n",ndx); + return False; + } + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"integer"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("Message data must be in the range 0..255\n"); + ACTION1("Illegal datum %d ignored\n",rtrn.ival); + return False; + } + act->message[ndx]= rtrn.uval; + } + return True; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleRedirectKey( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbRedirectKeyAction * act; +unsigned t1,t2,vmods,vmask; +unsigned long tmp; + + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + + act= (XkbRedirectKeyAction *)action; + switch (field) { + case F_Keycode: + if (!ExprResolveKeyName(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"key name"); + tmp= KeyNameToLong(rtrn.keyName.name); + if (!FindNamedKey(xkb,tmp,&t1,True,CreateKeyNames(xkb),0)) { + return ReportNotFound(action->type,field,"Key", + XkbKeyNameText(rtrn.keyName.name,XkbMessage)); + } + act->new_key= t1; + return True; + case F_ModsToClear: + case F_Modifiers: + t1= 0; + if (CheckModifierField(xkb,action->type,value,&t1,&t2)) { + act->mods_mask|= (t2&0xff); + if (field==F_Modifiers) + act->mods|= (t2&0xff); + else act->mods&= ~(t2&0xff); + + t2= (t2>>8)&0xffff; + vmods= XkbSARedirectVMods(act); + vmask= XkbSARedirectVModsMask(act); + vmask|= t2; + if (field==F_Modifiers) + vmods|= t2; + else vmods&= ~t2; + XkbSARedirectSetVMods(act,vmods); + XkbSARedirectSetVModsMask(act,vmask); + return True; + } + return True; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleDeviceBtn( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; +XkbDeviceBtnAction * act; + + act= (XkbDeviceBtnAction *)action; + if (field==F_Button) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"integer (range 1..255)"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("Button must specify default or be in the range 1..255\n"); + ACTION1("Illegal button value %d ignored\n",rtrn.ival); + return False; + } + act->button= rtrn.ival; + return True; + } + else if ((action->type==XkbSA_LockDeviceBtn)&&(field==F_Affect)) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveEnum(value,&rtrn,lockWhich)) + return ReportMismatch(action->type,field,"lock or unlock"); + act->flags&= ~(XkbSA_LockNoLock|XkbSA_LockNoUnlock); + act->flags|= rtrn.ival; + return True; + } + else if (field==F_Count) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)btnNames)) + return ReportMismatch(action->type,field,"integer"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("The count field must have a value in the range 0..255\n"); + ACTION1("Illegal count %d ignored\n",rtrn.ival); + return False; + } + act->count= rtrn.ival; + return True; + } + else if (field==F_Device) { + if (array_ndx!=NULL) + return ReportActionNotArray(action->type,field); + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"integer (range 1..255)"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("Device must specify default or be in the range 1..255\n"); + ACTION1("Illegal device value %d ignored\n",rtrn.ival); + return False; + } + act->device= rtrn.ival; + return True; + } + return ReportIllegal(action->type,field); +} + +static Bool +HandleDeviceValuator( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +#if 0 +ExprResult rtrn; +XkbDeviceValuatorAction * act; + + act= (XkbDeviceValuatorAction *)action; + /* XXX - Not yet implemented */ +#endif + return False; +} + +static Bool +HandlePrivate( XkbDescPtr xkb, + XkbAnyAction * action, + unsigned field, + ExprDef * array_ndx, + ExprDef * value) +{ +ExprResult rtrn; + + switch (field) { + case F_Type: + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportMismatch(PrivateAction,field,"integer"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("Private action type must be in the range 0..255\n"); + ACTION1("Illegal type %d ignored\n",rtrn.ival); + return False; + } + action->type= rtrn.uval; + return True; + case F_Data: + if (array_ndx==NULL) { + if (!ExprResolveString(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"string"); + else { + int len= strlen(rtrn.str); + if ((len<1)||(len>7)) { + WARN("A private action has 7 data bytes\n"); + ACTION1("Extra %d bytes ignored\n",len-6); + return False; + } + strncpy((char *)action->data,rtrn.str,7); + } + return True; + } + else { + unsigned ndx; + if (!ExprResolveInteger(array_ndx,&rtrn,NULL,NULL)) { + ERROR("Array subscript must be integer\n"); + ACTION("Illegal subscript ignored\n"); + return False; + } + ndx= rtrn.uval; + if (ndx>6) { + ERROR("The data for a private action is 7 bytes long\n"); + ACTION1("Attempt to use data[%d] ignored\n",ndx); + return False; + } + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportMismatch(action->type,field,"integer"); + if ((rtrn.ival<0)||(rtrn.ival>255)) { + ERROR("All data for a private action must be 0..255\n"); + ACTION1("Illegal datum %d ignored\n",rtrn.ival); + return False; + } + action->data[ndx]= rtrn.uval; + return True; + } + } + return ReportIllegal(PrivateAction,field); +} + +typedef Bool (*actionHandler)( + XkbDescPtr /* xkb */, + XkbAnyAction * /* action */, + unsigned /* field */, + ExprDef * /* array_ndx */, + ExprDef * /* value */ +); + +static actionHandler handleAction[XkbSA_NumActions+1] = { + HandleNoAction /* NoAction */, + HandleSetLatchMods /* SetMods */, + HandleSetLatchMods /* LatchMods */, + HandleLockMods /* LockMods */, + HandleSetLatchGroup /* SetGroup */, + HandleSetLatchGroup /* LatchGroup */, + HandleLockGroup /* LockGroup */, + HandleMovePtr /* MovePtr */, + HandlePtrBtn /* PtrBtn */, + HandlePtrBtn /* LockPtrBtn */, + HandleSetPtrDflt /* SetPtrDflt */, + HandleISOLock /* ISOLock */, + HandleNoAction /* Terminate */, + HandleSwitchScreen /* SwitchScreen */, + HandleSetLockControls /* SetControls */, + HandleSetLockControls /* LockControls */, + HandleActionMessage /* ActionMessage*/, + HandleRedirectKey /* RedirectKey */, + HandleDeviceBtn /* DeviceBtn */, + HandleDeviceBtn /* LockDeviceBtn*/, + HandleDeviceValuator /* DeviceValuatr*/, + HandlePrivate /* Private */ +}; + +/***====================================================================***/ + +static void +ApplyActionFactoryDefaults(XkbAction *action) +{ + if (action->type==XkbSA_SetPtrDflt) { /* increment default button */ + action->dflt.affect= XkbSA_AffectDfltBtn; + action->dflt.flags= 0; + XkbSASetPtrDfltValue(&action->dflt,1); + } + else if (action->type==XkbSA_ISOLock) { + action->iso.real_mods= LockMask; + } + return; +} + + +int +HandleActionDef( ExprDef * def, + XkbDescPtr xkb, + XkbAnyAction * action, + unsigned mergeMode, + ActionInfo * info) +{ +ExprDef * arg; +register char * str; +unsigned tmp,hndlrType; + + if (!actionsInitialized) + ActionsInit(); + + if (def->op!=ExprActionDecl) { + ERROR1("Expected an action definition, found %s\n",exprOpText(def->op)); + return False; + } + str= XkbAtomGetString(NULL,def->value.action.name); + if (!str) { + WSGO("Missing name in action definition!!\n"); + return False; + } + if (!stringToAction(str,&tmp)) { + ERROR1("Unknown action %s\n",str); + return False; + } + action->type= hndlrType= tmp; + if (action->type!=XkbSA_NoAction) { + ApplyActionFactoryDefaults((XkbAction *)action); + while (info) { + if ((info->action==XkbSA_NoAction)||(info->action==hndlrType)) { + if (!(*handleAction[hndlrType])(xkb,action, + info->field,info->array_ndx, + info->value)) { + return False; + } + } + info= info->next; + } + } + for (arg=def->value.action.args;arg!=NULL;arg=(ExprDef*)arg->common.next) { + ExprDef *field,*value,*arrayRtrn; + ExprResult elemRtrn,fieldRtrn; + unsigned fieldNdx; + + if (arg->op==OpAssign) { + field= arg->value.binary.left; + value= arg->value.binary.right; + } + else { + if ((arg->op==OpNot)||(arg->op==OpInvert)) { + field= arg->value.child; + value= &constFalse; + } + else { + field= arg; + value= &constTrue; + } + } + if (!ExprResolveLhs(field,&elemRtrn,&fieldRtrn,&arrayRtrn)) + return False; /* internal error -- already reported */ + + if (elemRtrn.str!=NULL) { + ERROR("Cannot change defaults in an action definition\n"); + ACTION2("Ignoring attempt to change %s.%s\n",elemRtrn.str, + fieldRtrn.str); + return False; + } + if (!stringToField(fieldRtrn.str,&fieldNdx)) { + ERROR1("Unknown field name %s\n",uStringText(fieldRtrn.str)); + return False; + } + if (!(*handleAction[hndlrType])(xkb,action,fieldNdx,arrayRtrn,value)) { + return False; + } + } + return True; +} + +/***====================================================================***/ + +int +SetActionField( XkbDescPtr xkb, + char * elem, + char * field, + ExprDef * array_ndx, + ExprDef * value, + ActionInfo ** info_rtrn) +{ +ActionInfo *new,*old; + + if (!actionsInitialized) + ActionsInit(); + + new= uTypedAlloc(ActionInfo); + if (new==NULL) { + WSGO("Couldn't allocate space for action default\n"); + return False; + } + if (uStrCaseCmp(elem,"action")==0) + new->action= XkbSA_NoAction; + else { + if (!stringToAction(elem,&new->action)) + return False; + if (new->action==XkbSA_NoAction) { + ERROR1("\"%s\" is not a valid field in a NoAction action\n",field); + return False; + } + } + if (!stringToField(field,&new->field)) { + ERROR1("\"%s\" is not a legal field name\n",field); + return False; + } + new->array_ndx= array_ndx; + new->value= value; + new->next= NULL; + old= *info_rtrn; + while ((old)&&(old->next)) + old= old->next; + if (old==NULL) *info_rtrn= new; + else old->next= new; + return True; +} + +/***====================================================================***/ + +void +ActionsInit(void) +{ + if (!actionsInitialized) { + bzero((char *)&constTrue,sizeof(constTrue)); + bzero((char *)&constFalse,sizeof(constFalse)); + constTrue.common.stmtType= StmtExpr; + constTrue.common.next= NULL; + constTrue.op= ExprIdent; + constTrue.type= TypeBoolean; + constTrue.value.str= XkbInternAtom(NULL,"true",False); + constFalse.common.stmtType= StmtExpr; + constFalse.common.next= NULL; + constFalse.op= ExprIdent; + constFalse.type= TypeBoolean; + constFalse.value.str= XkbInternAtom(NULL,"false",False); + actionsInitialized= 1; + } + return; +} + diff --git a/xkbcomp/action.h b/xkbcomp/action.h new file mode 100644 index 0000000..4a11664 --- /dev/null +++ b/xkbcomp/action.h @@ -0,0 +1,91 @@ +/* $Xorg: action.h,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef ACTION_H +#define ACTION_H 1 + +#define F_ClearLocks 0 +#define F_LatchToLock 1 +#define F_GenKeyEvent 2 +#define F_Report 3 +#define F_Default 4 +#define F_Affect 5 +#define F_Increment 6 +#define F_Modifiers 7 +#define F_Group 8 +#define F_X 9 +#define F_Y 10 +#define F_Accel 11 +#define F_Button 12 +#define F_Value 13 +#define F_Controls 14 +#define F_Type 15 +#define F_Count 16 +#define F_Screen 17 +#define F_Same 18 +#define F_Data 19 +#define F_Device 20 +#define F_Keycode 21 +#define F_ModsToClear 22 +#define F_LastField F_ModsToClear +#define F_NumFields (F_LastField+1) + +#define PrivateAction (XkbSA_LastAction+1) + +typedef struct _ActionInfo { + unsigned action; + unsigned field; + ExprDef * array_ndx; + ExprDef * value; + struct _ActionInfo * next; +} ActionInfo; + +extern int HandleActionDef( + ExprDef * /* def */, + XkbDescPtr /* xkb */, + XkbAnyAction * /* action */, + unsigned /* mergeMode */, + ActionInfo * /* info */ +); + +extern int SetActionField( + XkbDescPtr /* xkb */, + char * /* elem */, + char * /* field */, + ExprDef * /* index */, + ExprDef * /* value */, + ActionInfo ** /* info_rtrn */ +); + +extern void ActionsInit( + void +); + +extern LookupEntry ctrlNames[]; + +#endif /* ACTION_H */ diff --git a/xkbcomp/alias.c b/xkbcomp/alias.c new file mode 100644 index 0000000..f228b0d --- /dev/null +++ b/xkbcomp/alias.c @@ -0,0 +1,261 @@ +/* $Xorg: alias.c,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#include "xkbcomp.h" +#include "misc.h" +#include "alias.h" +#include "keycodes.h" + +#include + +static void +HandleCollision(AliasInfo *old,AliasInfo *new) +{ + if (strncmp(new->real,old->real,XkbKeyNameLength)==0) { + if (((new->def.fileID==old->def.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN2("Alias of %s for %s declared more than once\n", + XkbKeyNameText(new->alias,XkbMessage), + XkbKeyNameText(new->real,XkbMessage)); + ACTION("First definition ignored\n"); + } + } + else { + char *use,*ignore; + if (new->def.merge==MergeAugment) { + use= old->real; + ignore= new->real; + } + else { + use= new->real; + ignore= old->real; + } + if (((old->def.fileID==new->def.fileID)&&(warningLevel>0))|| + (warningLevel>9)){ + WARN1("Multiple definitions for alias %s\n", + XkbKeyNameText(old->alias,XkbMessage)); + ACTION2("Using %s, ignoring %s\n", XkbKeyNameText(use,XkbMessage), + XkbKeyNameText(ignore,XkbMessage)); + } + if (use!=old->real) + memcpy(old->real,use,XkbKeyNameLength); + } + old->def.fileID= new->def.fileID; + old->def.merge= new->def.merge; + return; +} + +static void +InitAliasInfo( AliasInfo * info, + unsigned merge, + unsigned file_id, + char * alias, + char * real) +{ + bzero(info,sizeof(AliasInfo)); + info->def.merge= merge; + info->def.fileID= file_id; + strncpy(info->alias,alias,XkbKeyNameLength); + strncpy(info->real,real,XkbKeyNameLength); + return; +} + +int +HandleAliasDef( KeyAliasDef * def, + unsigned merge, + unsigned file_id, + AliasInfo ** info_in) +{ +AliasInfo * info; + + for (info= *info_in;info!=NULL;info= (AliasInfo *)info->def.next) { + if (strncmp(info->alias,def->alias,XkbKeyNameLength)==0) { + AliasInfo new; + InitAliasInfo(&new,merge,file_id,def->alias,def->real); + HandleCollision(info,&new); + return True; + } + } + info= uTypedCalloc(1,AliasInfo); + if (info==NULL) { + WSGO("Allocation failure in HandleAliasDef\n"); + return False; + } + info->def.fileID= file_id; + info->def.merge= merge; + info->def.next= (CommonInfo *)*info_in; + memcpy(info->alias,def->alias,XkbKeyNameLength); + memcpy(info->real,def->real,XkbKeyNameLength); + *info_in= (AliasInfo *)AddCommonInfo(&(*info_in)->def,&info->def); + return True; +} + +void +ClearAliases(AliasInfo **info_in) +{ + if ((info_in)&&(*info_in)) + ClearCommonInfo(&(*info_in)->def); + return; +} + +Bool +MergeAliases(AliasInfo **into,AliasInfo **merge,unsigned how_merge) +{ +AliasInfo * tmp; +KeyAliasDef def; + + if ((*merge)==NULL) + return True; + if ((*into)==NULL) { + *into= *merge; + *merge= NULL; + return True; + } + bzero((char *)&def,sizeof(KeyAliasDef)); + for (tmp= *merge;tmp!=NULL;tmp= (AliasInfo *)tmp->def.next) { + if (how_merge==MergeDefault) + def.merge= tmp->def.merge; + else def.merge= how_merge; + memcpy(def.alias,tmp->alias,XkbKeyNameLength); + memcpy(def.real,tmp->real,XkbKeyNameLength); + if (!HandleAliasDef(&def,def.merge,tmp->def.fileID,into)) + return False; + } + return True; +} + +int +ApplyAliases(XkbDescPtr xkb,Bool toGeom,AliasInfo **info_in) +{ +register int i; +XkbKeyAliasPtr old,a; +AliasInfo * info; +int nNew,nOld; +Status status; + + if (*info_in==NULL) + return True; + if (toGeom) { + nOld= (xkb->geom?xkb->geom->num_key_aliases:0); + old= (xkb->geom?xkb->geom->key_aliases:NULL); + } + else { + nOld= (xkb->names?xkb->names->num_key_aliases:0); + old= (xkb->names?xkb->names->key_aliases:NULL); + } + for (nNew=0,info= *info_in;info!=NULL;info= (AliasInfo *)info->def.next) { + unsigned long lname; + unsigned int kc; + + lname= KeyNameToLong(info->real); + if (!FindNamedKey(xkb,lname,&kc,False,CreateKeyNames(xkb),0)) { + if (warningLevel>4) { + WARN2("Attempt to alias %s to non-existent key %s\n", + XkbKeyNameText(info->alias,XkbMessage), + XkbKeyNameText(info->real,XkbMessage)); + ACTION("Ignored\n"); + } + info->alias[0]= '\0'; + continue; + } + lname= KeyNameToLong(info->alias); + if (FindNamedKey(xkb,lname,&kc,False,False,0)) { + if (warningLevel>4) { + WARN("Attempt to create alias with the name of a real key\n"); + ACTION2("Alias \"%s = %s\" ignored\n", + XkbKeyNameText(info->alias,XkbMessage), + XkbKeyNameText(info->real,XkbMessage)); + } + info->alias[0]= '\0'; + continue; + } + nNew++; + if ( old ) { + for (i=0,a=old;ialias,info->alias,XkbKeyNameLength)==0) { + AliasInfo old; + InitAliasInfo(&old,MergeAugment,0,a->alias,a->real); + HandleCollision(&old,info); + memcpy(old.real,a->real,XkbKeyNameLength); + info->alias[0]= '\0'; + nNew--; + break; + } + } + } + } + if (nNew==0) { + ClearCommonInfo(&(*info_in)->def); + *info_in= NULL; + return True; + } + status= Success; + if (toGeom) { + if (!xkb->geom) { + XkbGeometrySizesRec sizes; + bzero((char *)&sizes,sizeof(XkbGeometrySizesRec)); + sizes.which= XkbGeomKeyAliasesMask; + sizes.num_key_aliases= nOld+nNew; + status= XkbAllocGeometry(xkb,&sizes); + } + else { + status= XkbAllocGeomKeyAliases(xkb->geom,nOld+nNew); + } + if (xkb->geom) + old= xkb->geom->key_aliases; + } + else { + status= XkbAllocNames(xkb,XkbKeyAliasesMask,0,nOld+nNew); + if (xkb->names) + old= xkb->names->key_aliases; + } + if (status!=Success) { + WSGO("Allocation failure in ApplyAliases\n"); + return False; + } + if (toGeom) + a= &xkb->geom->key_aliases[nOld]; + else a= &xkb->names->key_aliases[nOld]; + for (info= *info_in;info!=NULL;info= (AliasInfo *)info->def.next) { + if (info->alias[0]!='\0') { + strncpy(a->alias,info->alias,XkbKeyNameLength); + strncpy(a->real,info->real,XkbKeyNameLength); + a++; + } + } +#ifdef DEBUG + if ((a-old)!=(nOld+nNew)) { + WSGO2("Expected %d aliases total but created %d\n",nOld+nNew,a-old); + } +#endif + if (toGeom) + xkb->geom->num_key_aliases+= nNew; + ClearCommonInfo(&(*info_in)->def); + *info_in= NULL; + return True; +} diff --git a/xkbcomp/alias.h b/xkbcomp/alias.h new file mode 100644 index 0000000..fd03388 --- /dev/null +++ b/xkbcomp/alias.h @@ -0,0 +1,61 @@ +/* $Xorg: alias.h,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef ALIAS_H +#define ALIAS_H 1 + +typedef struct _AliasInfo { + CommonInfo def; + char alias[XkbKeyNameLength+1]; + char real[XkbKeyNameLength+1]; +} AliasInfo; + +extern int HandleAliasDef( + KeyAliasDef * /* def */, + unsigned /* merge */, + unsigned /* file_id */, + AliasInfo ** /* info */ +); + +extern void ClearAliases( + AliasInfo ** /* info */ +); + +extern Bool MergeAliases( + AliasInfo ** /* into */, + AliasInfo ** /* merge */, + unsigned /* how_merge */ +); + +extern int ApplyAliases( + XkbDescPtr /* xkb */, + Bool /* toGeom */, + AliasInfo ** /* info */ +); + +#endif /* ALIAS_H */ diff --git a/xkbcomp/compat.h b/xkbcomp/compat.h new file mode 100644 index 0000000..4edf788 --- /dev/null +++ b/xkbcomp/compat.h @@ -0,0 +1,8 @@ +/* $XFree86$ */ + +#ifndef COMPAT_H +#define COMPAT_H 1 + +extern LookupEntry groupNames[]; + +#endif /* COMPAT_H */ diff --git a/xkbcomp/config.h.in b/xkbcomp/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/xkbcomp/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xkbcomp/expr.h b/xkbcomp/expr.h new file mode 100644 index 0000000..3946cf0 --- /dev/null +++ b/xkbcomp/expr.h @@ -0,0 +1,189 @@ +/* $Xorg: expr.h,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef EXPR_H +#define EXPR_H 1 + +typedef union _ExprResult { + char * str; + int ival; + unsigned uval; + XkbKeyNameRec keyName; +} ExprResult; + +typedef Bool (*IdentLookupFunc)( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern char *exprTypeText( + unsigned /* type */ +); + +extern int ExprResolveLhs( + ExprDef * /* expr */, + ExprResult * /* elem_rtrn */, + ExprResult * /* field_rtrn */, + ExprDef ** /* index_rtrn */ +); + +typedef struct _LookupPriv { + XPointer priv; + IdentLookupFunc chain; + XPointer chainPriv; +} LookupPriv; + +typedef struct _LookupEntry { + char * name; + unsigned result; +} LookupEntry; + +typedef struct _LookupTable { + char * element; + LookupEntry * entries; + struct _LookupTable * nextElement; +} LookupTable; + + +extern char *exprOpText( + unsigned /* type */ +); + +extern int RadioLookup( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int SimpleLookup( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int TableLookup( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int LookupModIndex( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int LookupModMask( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int ExprResolveModIndex( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveModMask( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* priv */ +); + +extern int ExprResolveBoolean( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveInteger( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveFloat( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveString( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveKeyName( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveEnum( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + LookupEntry * /* values */ +); + +extern int ExprResolveMask( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +extern int ExprResolveKeySym( + ExprDef * /* expr */, + ExprResult * /* val_rtrn */, + IdentLookupFunc /* lookup */, + XPointer /* lookupPriv */ +); + +#endif /* EXPR_H */ diff --git a/xkbcomp/geometry.c b/xkbcomp/geometry.c new file mode 100644 index 0000000..b6463cc --- /dev/null +++ b/xkbcomp/geometry.c @@ -0,0 +1,3277 @@ +/* $Xorg: geometry.c,v 1.3 2000/08/17 19:54:30 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/geometry.c,v 1.5tsi Exp $ */ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "vmod.h" +#include "misc.h" +#include "indicators.h" +#include "action.h" +#include "keycodes.h" +#include "alias.h" + +#include "X11/extensions/XKBgeom.h" + +#define DFLT_FONT "helvetica" +#define DFLT_SLANT "r" +#define DFLT_WEIGHT "medium" +#define DFLT_SET_WIDTH "normal" +#define DFLT_VARIANT "" +#define DFLT_ENCODING "iso8859-1" +#define DFLT_SIZE 120 + +typedef struct _PropertyInfo { + CommonInfo defs; + char * name; + char * value; +} PropertyInfo; + +#define _GSh_Outlines (1<<1) +#define _GSh_Approx (1<<2) +#define _GSh_Primary (1<<3) +typedef struct _ShapeInfo { + CommonInfo defs; + Atom name; + short index; + unsigned short nOutlines; + unsigned short szOutlines; + XkbOutlinePtr outlines; + XkbOutlinePtr approx; + XkbOutlinePtr primary; + int dfltCornerRadius; +} ShapeInfo; + +#define shText(d,s) \ + ((s)?XkbAtomText((d),(s)->name,XkbMessage):"default shape") + +#define _GD_Priority (1<<0) +#define _GD_Top (1<<1) +#define _GD_Left (1<<2) +#define _GD_Angle (1<<3) +#define _GD_Shape (1<<4) +#define _GD_FontVariant (1<<4) /* CHEATING */ +#define _GD_Corner (1<<5) +#define _GD_Width (1<<5) /* CHEATING */ +#define _GD_Color (1<<6) +#define _GD_OffColor (1<<7) +#define _GD_Height (1<<7) /* CHEATING */ +#define _GD_Text (1<<8) +#define _GD_Font (1<<9) +#define _GD_FontSlant (1<<10) +#define _GD_FontWeight (1<<11) +#define _GD_FontSetWidth (1<<12) +#define _GD_FontSize (1<<13) +#define _GD_FontEncoding (1<<14) +#define _GD_FontSpec (1<<15) + + +#define _GD_FontParts (_GD_Font|_GD_FontSlant|_GD_FontWeight|_GD_FontSetWidth|_GD_FontSize|_GD_FontEncoding|_GD_FontVariant) + +typedef struct _DoodadInfo { + CommonInfo defs; + Atom name; + unsigned char type; + unsigned char priority; + short top; + short left; + short angle; + unsigned short corner; + unsigned short width; + unsigned short height; + Atom shape; + Atom color; + Atom offColor; + Atom text; + Atom font; + Atom fontSlant; + Atom fontWeight; + Atom fontSetWidth; + Atom fontVariant; + unsigned short fontSize; + Atom fontEncoding; + Atom fontSpec; + char * logoName; + struct _SectionInfo *section; +} DoodadInfo; + +#define Yes 1 +#define No 0 +#define Undefined -1 + +#define _GK_Default (1<<0) +#define _GK_Name (1<<1) +#define _GK_Gap (1<<2) +#define _GK_Shape (1<<3) +#define _GK_Color (1<<4) +typedef struct _KeyInfo { + CommonInfo defs; + char name[8]; + short gap; + short index; + Atom shape; + Atom color; + struct _RowInfo * row; +} KeyInfo; +#define keyText(k) ((k)&&(k)->name[0]?(k)->name:"default") + +#define _GR_Default (1<<0) +#define _GR_Vertical (1<<1) +#define _GR_Top (1<<2) +#define _GR_Left (1<<3) +typedef struct _RowInfo { + CommonInfo defs; + unsigned short top; + unsigned short left; + short index; + Bool vertical; + unsigned short nKeys; + KeyInfo * keys; + KeyInfo dfltKey; + struct _SectionInfo *section; +} RowInfo; +#define rowText(d,r) \ + ((r)?XkbAtomText((d),(r)->section->name,XkbMessage):"default") + +#define _GOK_UnknownRow -1 +typedef struct _OverlayKeyInfo { + CommonInfo defs; + short sectionRow; + short overlayRow; + char over[XkbKeyNameLength+1]; + char under[XkbKeyNameLength+1]; +} OverlayKeyInfo; + +typedef struct _OverlayInfo { + CommonInfo defs; + Atom name; + unsigned short nRows; + unsigned short nKeys; + OverlayKeyInfo *keys; +} OverlayInfo; +#define oiText(d,o) ((o)?XkbAtomText((d),(o)->name,XkbMessage):"default") + + +#define _GS_Default (1<<0) +#define _GS_Name (1<<1) +#define _GS_Top (1<<2) +#define _GS_Left (1<<3) +#define _GS_Width (1<<4) +#define _GS_Height (1<<5) +#define _GS_Angle (1<<6) +#define _GS_Priority (1<<7) +typedef struct _SectionInfo { + CommonInfo defs; + Atom name; + unsigned short top; + unsigned short left; + unsigned short width; + unsigned short height; + unsigned short angle; + unsigned short nRows; + unsigned short nDoodads; + unsigned short nOverlays; + unsigned char priority; + unsigned char nextDoodadPriority; + RowInfo * rows; + DoodadInfo * doodads; + RowInfo dfltRow; + DoodadInfo * dfltDoodads; + OverlayInfo * overlays; + struct _GeometryInfo *geometry; +} SectionInfo; +#define scText(d,s) ((s)?XkbAtomText((d),(s)->name,XkbMessage):"default") + +typedef struct _GeometryInfo { + char * name; + Display * dpy; + unsigned fileID; + unsigned merge; + int errorCount; + unsigned nextPriority; + int nProps; + int nShapes; + int nSections; + int nDoodads; + PropertyInfo * props; + ShapeInfo * shapes; + SectionInfo * sections; + DoodadInfo * doodads; + int widthMM; + int heightMM; + Atom font; + Atom fontSlant; + Atom fontWeight; + Atom fontSetWidth; + Atom fontVariant; + unsigned fontSize; + Atom fontEncoding; + Atom fontSpec; + Atom baseColor; + Atom labelColor; + int dfltCornerRadius; + SectionInfo dfltSection; + DoodadInfo * dfltDoodads; + AliasInfo * aliases; +} GeometryInfo; + +static char * +ddText(Display *dpy,DoodadInfo *di) +{ +static char buf[64]; + + if (di==NULL) { + strcpy(buf,"default"); + return buf; + } + if (di->section) { + sprintf(buf,"%s in section %s",XkbAtomText(dpy,di->name,XkbMessage), + scText(dpy,di->section)); + return buf; + } + return XkbAtomText(dpy,di->name,XkbMessage); +} + +/***====================================================================***/ + +static void +InitPropertyInfo(PropertyInfo *pi,GeometryInfo *info) +{ + pi->defs.defined= 0; + pi->defs.fileID= info->fileID; + pi->defs.merge= info->merge; + pi->name= pi->value= NULL; + return; +} + +static void +FreeProperties(PropertyInfo *pi,GeometryInfo *info) +{ +PropertyInfo * tmp; +PropertyInfo * next; + + if (info->props==pi) { + info->props= NULL; + info->nProps= 0; + } + for (tmp=pi;tmp!=NULL;tmp=next) { + if (tmp->name) + uFree(tmp->name); + if (tmp->value) + uFree(tmp->value); + tmp->name= tmp->value=NULL; + next= (PropertyInfo *)tmp->defs.next; + uFree(tmp); + } + return; +} + +static void +InitKeyInfo(KeyInfo *key,RowInfo *row,GeometryInfo *info) +{ + + if (key!=&row->dfltKey) { + *key= row->dfltKey; + strcpy(key->name,"unknown"); + key->defs.defined&= ~_GK_Default; + } + else { + bzero(key,sizeof(KeyInfo)); + strcpy(key->name,"default"); + key->defs.defined= _GK_Default; + key->defs.fileID= info->fileID; + key->defs.merge= info->merge; + key->defs.next= NULL; + key->row= row; + } + return; +} + +static void +ClearKeyInfo(KeyInfo *key) +{ + key->defs.defined&= ~_GK_Default; + strcpy(key->name,"default"); + key->gap= 0; + key->shape= None; + key->color= None; + return; +} + +static void +FreeKeys(KeyInfo *key,RowInfo *row,GeometryInfo *info) +{ +KeyInfo * tmp; +KeyInfo * next; + + if (row->keys==key) { + row->nKeys= 0; + row->keys= NULL; + } + for (tmp=key;tmp!=NULL;tmp=next) { + ClearKeyInfo(tmp); + next= (KeyInfo *)tmp->defs.next; + uFree(tmp); + } + return; +} + +static void +InitRowInfo(RowInfo *row,SectionInfo *section,GeometryInfo *info) +{ + if (row!= §ion->dfltRow) { + *row= section->dfltRow; + row->defs.defined&= ~_GR_Default; + } + else { + bzero(row,sizeof(RowInfo *)); + row->defs.defined= _GR_Default; + row->defs.fileID= info->fileID; + row->defs.merge= info->merge; + row->defs.next= NULL; + row->section= section; + row->nKeys= 0; + row->keys= NULL; + InitKeyInfo(&row->dfltKey,row,info); + } + return; +} + +static void +ClearRowInfo(RowInfo *row,GeometryInfo *info) +{ + row->defs.defined&= ~_GR_Default; + row->top= row->left= 0; + row->vertical= False; + row->nKeys= 0; + if (row->keys) + FreeKeys(row->keys,row,info); + ClearKeyInfo(&row->dfltKey); + row->dfltKey.defs.defined|= _GK_Default; + return; +} + +static void +FreeRows(RowInfo *row,SectionInfo *section,GeometryInfo *info) +{ +RowInfo * next; +RowInfo * tmp; + + if (row==section->rows) { + section->nRows= 0; + section->rows= NULL; + } + for (tmp=row;tmp!=NULL;tmp=next) { + ClearRowInfo(tmp,info); + next= (RowInfo *)tmp->defs.next; + uFree(tmp); + } + return; +} + +static DoodadInfo * +FindDoodadByType(DoodadInfo *di,unsigned type) +{ + while (di) { + if (di->type==type) + return di; + di= (DoodadInfo *)di->defs.next; + } + return NULL; +} + +static DoodadInfo * +FindDoodadByName(DoodadInfo *di,Atom name) +{ + while (di) { + if (di->name==name) + return di; + di= (DoodadInfo *)di->defs.next; + } + return NULL; +} + +static void +InitDoodadInfo(DoodadInfo *di,unsigned type,SectionInfo *si,GeometryInfo *info) +{ +DoodadInfo * dflt; + + dflt= NULL; + if (si && si->dfltDoodads) + dflt= FindDoodadByType(si->dfltDoodads,type); + if ((dflt==NULL)&&(info->dfltDoodads)) + dflt= FindDoodadByType(info->dfltDoodads,type); + if (dflt!=NULL) { + *di= *dflt; + di->defs.next= NULL; + } + else { + bzero(di,sizeof(DoodadInfo)); + di->defs.fileID= info->fileID; + di->type= type; + } + di->section= si; + if (si!=NULL) { + di->priority= si->nextDoodadPriority++; +#if XkbGeomMaxPriority < 255 + if (si->nextDoodadPriority>XkbGeomMaxPriority) + si->nextDoodadPriority= XkbGeomMaxPriority; +#endif + } + else { + di->priority= info->nextPriority++; + if (info->nextPriority>XkbGeomMaxPriority) + info->nextPriority= XkbGeomMaxPriority; + } + return; +} + +static void +ClearDoodadInfo(DoodadInfo *di) +{ +CommonInfo defs; + + defs= di->defs; + bzero(di,sizeof(DoodadInfo)); + di->defs= defs; + di->defs.defined= 0; + return; +} + +static void +ClearOverlayInfo(OverlayInfo *ol) +{ + if (ol && ol->keys) { + ol->keys= (OverlayKeyInfo *)ClearCommonInfo(&ol->keys->defs); + ol->nKeys= 0; + } + return; +} + +static void +FreeDoodads(DoodadInfo *di,SectionInfo *si,GeometryInfo *info) +{ +DoodadInfo * tmp; +DoodadInfo * next; + + if (si) { + if (si->doodads==di) { + si->doodads= NULL; + si->nDoodads= 0; + } + if (si->dfltDoodads==di) + si->dfltDoodads= NULL; + } + if (info->doodads==di) { + info->doodads= NULL; + info->nDoodads= 0; + } + if (info->dfltDoodads==di) + info->dfltDoodads= NULL; + for (tmp=di;tmp!=NULL;tmp=next) { + next= (DoodadInfo *)tmp->defs.next; + ClearDoodadInfo(tmp); + uFree(tmp); + } + return; +} + +static void +InitSectionInfo(SectionInfo *si,GeometryInfo *info) +{ + if (si!=&info->dfltSection) { + *si= info->dfltSection; + si->defs.defined&= ~_GS_Default; + si->name= XkbInternAtom(info->dpy,"unknown",False); + si->priority= info->nextPriority++; + if (info->nextPriority>XkbGeomMaxPriority) + info->nextPriority= XkbGeomMaxPriority; + } + else { + bzero(si,sizeof(SectionInfo)); + si->defs.fileID= info->fileID; + si->defs.merge= info->merge; + si->defs.next= NULL; + si->geometry= info; + si->name= XkbInternAtom(info->dpy,"default",False); + InitRowInfo(&si->dfltRow,si,info); + } + return; +} + +static void +DupSectionInfo(SectionInfo *into,SectionInfo *from,GeometryInfo *info) +{ +CommonInfo defs; + + defs= into->defs; + *into= *from; + into->defs.fileID= defs.fileID; + into->defs.merge= defs.merge; + into->defs.next= NULL; + into->dfltRow.defs.fileID= defs.fileID; + into->dfltRow.defs.merge= defs.merge; + into->dfltRow.defs.next= NULL; + into->dfltRow.section= into; + into->dfltRow.dfltKey.defs.fileID= defs.fileID; + into->dfltRow.dfltKey.defs.merge= defs.merge; + into->dfltRow.dfltKey.defs.next= NULL; + into->dfltRow.dfltKey.row= &into->dfltRow; + return; +} + +static void +ClearSectionInfo(SectionInfo *si,GeometryInfo *info) +{ + + si->defs.defined&= ~_GS_Default; + si->name= XkbInternAtom(info->dpy,"default",False); + si->top= si->left= 0; + si->width= si->height= 0; + si->angle= 0; + if (si->rows) { + FreeRows(si->rows,si,info); + si->rows= NULL; + } + ClearRowInfo(&si->dfltRow,info); + if (si->doodads) { + FreeDoodads(si->doodads,si,info); + si->doodads= NULL; + } + si->dfltRow.defs.defined= _GR_Default; + return; +} + +static void +FreeSections(SectionInfo *si,GeometryInfo *info) +{ +SectionInfo * tmp; +SectionInfo * next; + + if (si==info->sections) { + info->nSections= 0; + info->sections= NULL; + } + for (tmp=si;tmp!=NULL;tmp=next) { + ClearSectionInfo(tmp,info); + next= (SectionInfo *)tmp->defs.next; + uFree(tmp); + } + return; +} + +static void +FreeShapes(ShapeInfo *si,GeometryInfo *info) +{ +ShapeInfo * tmp; +ShapeInfo * next; + + if (si==info->shapes) { + info->nShapes= 0; + info->shapes= NULL; + } + for (tmp=si;tmp!=NULL;tmp=next) { + if (tmp->outlines) { + register int i; + for (i=0;inOutlines;i++) { + if (tmp->outlines[i].points!=NULL) { + uFree(tmp->outlines[i].points); + tmp->outlines[i].num_points= 0; + tmp->outlines[i].points= NULL; + } + } + uFree(tmp->outlines); + tmp->szOutlines= 0; + tmp->nOutlines= 0; + tmp->outlines= NULL; + tmp->primary= tmp->approx=NULL; + } + next= (ShapeInfo *)tmp->defs.next; + uFree(tmp); + } + return; +} + +/***====================================================================***/ + +static void +InitGeometryInfo(GeometryInfo *info,unsigned fileID,unsigned merge) +{ + bzero(info,sizeof(GeometryInfo)); + info->fileID= fileID; + info->merge= merge; + InitSectionInfo(&info->dfltSection,info); + info->dfltSection.defs.defined= _GS_Default; + return; +} + +static void +ClearGeometryInfo(GeometryInfo *info) +{ + if (info->name) + uFree(info->name); + info->name= NULL; + if (info->props) + FreeProperties(info->props,info); + if (info->shapes) + FreeShapes(info->shapes,info); + if (info->sections) + FreeSections(info->sections,info); + info->widthMM= 0; + info->heightMM= 0; + info->dfltCornerRadius= 0; + ClearSectionInfo(&info->dfltSection,info); + info->dfltSection.defs.defined= _GS_Default; + if (info->aliases) + ClearAliases(&info->aliases); + return; +} + +/***====================================================================***/ + +static PropertyInfo * +NextProperty(GeometryInfo *info) +{ +PropertyInfo * pi; + + pi= uTypedAlloc(PropertyInfo); + if (pi) { + bzero((char *)pi,sizeof(PropertyInfo)); + info->props= (PropertyInfo *)AddCommonInfo(&info->props->defs, + (CommonInfo *)pi); + info->nProps++; + } + return pi; +} + +static PropertyInfo * +FindProperty(GeometryInfo *info,char *name) +{ +PropertyInfo * old; + + if (!name) + return NULL; + for (old= info->props;old!=NULL;old=(PropertyInfo *)old->defs.next) { + if ((old->name)&&(uStringEqual(name,old->name))) + return old; + } + return NULL; +} + +static Bool +AddProperty(GeometryInfo *info,PropertyInfo *new) +{ +PropertyInfo * old; + + if ((!new)||(!new->value)||(!new->name)) + return False; + old= FindProperty(info,new->name); + if (old!=NULL) { + if ((new->defs.merge==MergeReplace)||(new->defs.merge==MergeOverride)) { + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple definitions for the \"%s\" property\n", + new->name); + ACTION2("Ignoring \"%s\", using \"%s\"\n",old->value, + new->value); + } + if (old->value) + uFree(old->value); + old->value= uStringDup(new->value); + return True; + } + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple definitions for \"%s\" property\n",new->name); + ACTION2("Using \"%s\", ignoring \"%s\" \n",old->value,new->value); + } + return True; + } + old= new; + if ((new= NextProperty(info))==NULL) + return False; + new->defs.next= NULL; + new->name= uStringDup(old->name); + new->value= uStringDup(old->value); + return True; +} + +/***====================================================================***/ + +static ShapeInfo * +NextShape(GeometryInfo *info) +{ +ShapeInfo * si; + + si= uTypedAlloc(ShapeInfo); + if (si) { + bzero((char *)si,sizeof(ShapeInfo)); + info->shapes= (ShapeInfo *)AddCommonInfo(&info->shapes->defs, + (CommonInfo *)si); + info->nShapes++; + si->dfltCornerRadius= info->dfltCornerRadius; + } + return si; +} + +static ShapeInfo * +FindShape(GeometryInfo *info,Atom name,char *type,char *which) +{ +ShapeInfo * old; + + for (old= info->shapes;old!=NULL;old=(ShapeInfo *)old->defs.next) { + if (name==old->name) + return old; + } + if (type!=NULL) { + old= info->shapes; + WARN3("Unknown shape \"%s\" for %s %s\n", + XkbAtomText(info->dpy,name,XkbMessage),type,which); + if (old) { + ACTION1("Using default shape %s instead\n",shText(info->dpy,old)); + return old; + } + ACTION("No default shape; definition ignored\n"); + return NULL; + } + return NULL; +} + +static Bool +AddShape(GeometryInfo *info,ShapeInfo *new) +{ +ShapeInfo * old; + + old= FindShape(info,new->name,NULL,NULL); + if (old!=NULL) { + if ((new->defs.merge==MergeReplace)||(new->defs.merge==MergeOverride)) { + ShapeInfo *next= (ShapeInfo *)old->defs.next; + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Duplicate shape name \"%s\"\n",shText(info->dpy,old)); + ACTION("Using last definition\n"); + } + *old= *new; + old->defs.next= &next->defs; + return True; + } + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple shapes named \"%s\"\n",shText(info->dpy,old)); + ACTION("Using first definition\n"); + } + return True; + } + old= new; + if ((new= NextShape(info))==NULL) + return False; + *new= *old; + new->defs.next= NULL; + old->szOutlines= old->nOutlines= 0; + old->outlines= NULL; + old->approx= NULL; + old->primary= NULL; + return True; +} + +/***====================================================================***/ + +static void +ReplaceDoodad(DoodadInfo *into,DoodadInfo *from) +{ +CommonInfo * next; + + next= into->defs.next; + ClearDoodadInfo(into); + *into= *from; + into->defs.next= next; + next= from->defs.next; + ClearDoodadInfo(from); + from->defs.next= next; + return; +} + +static DoodadInfo * +NextDfltDoodad(SectionInfo *si,GeometryInfo *info) +{ +DoodadInfo * di; + + di= uTypedCalloc(1,DoodadInfo); + if (!di) + return NULL; + if (si) { + si->dfltDoodads= (DoodadInfo *)AddCommonInfo(&si->dfltDoodads->defs, + (CommonInfo *)di); + } + else { + info->dfltDoodads= (DoodadInfo *)AddCommonInfo(&info->dfltDoodads->defs, + (CommonInfo *)di); + } + return di; +} + +static DoodadInfo * +NextDoodad(SectionInfo *si,GeometryInfo *info) +{ +DoodadInfo * di; + + di= uTypedCalloc(1,DoodadInfo); + if (di) { + if (si) { + si->doodads= (DoodadInfo *)AddCommonInfo(&si->doodads->defs, + (CommonInfo *)di); + si->nDoodads++; + } + else { + info->doodads= (DoodadInfo *)AddCommonInfo(&info->doodads->defs, + (CommonInfo *)di); + info->nDoodads++; + } + } + return di; +} + +static Bool +AddDoodad(SectionInfo *si,GeometryInfo *info,DoodadInfo *new) +{ +DoodadInfo * old; + + old= FindDoodadByName((si?si->doodads:info->doodads),new->name); + if (old!=NULL) { + if ((new->defs.merge==MergeReplace)||(new->defs.merge==MergeOverride)) { + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple doodads named \"%s\"\n", + XkbAtomText(info->dpy,old->name,XkbMessage)); + ACTION("Using last definition\n"); + } + ReplaceDoodad(old,new); + old->section= si; + return True; + } + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple doodads named \"%s\"\n", + XkbAtomText(info->dpy,old->name,XkbMessage)); + ACTION("Using first definition\n"); + } + return True; + } + old= new; + if ((new= NextDoodad(si,info))==NULL) + return False; + ReplaceDoodad(new,old); + new->section= si; + new->defs.next= NULL; + return True; +} + +static DoodadInfo * +FindDfltDoodadByTypeName(char *name,SectionInfo *si,GeometryInfo *info) +{ +DoodadInfo * dflt; +unsigned type; + + if (uStrCaseCmp(name,"outline")==0) type= XkbOutlineDoodad; + else if (uStrCaseCmp(name,"solid")==0) type= XkbSolidDoodad; + else if (uStrCaseCmp(name,"text")==0) type= XkbTextDoodad; + else if (uStrCaseCmp(name,"indicator")==0) type= XkbIndicatorDoodad; + else if (uStrCaseCmp(name,"logo")==0) type= XkbLogoDoodad; + else return NULL; + if ((si)&&(si->dfltDoodads)) + dflt= FindDoodadByType(si->dfltDoodads,type); + else dflt= NULL; + if ((!dflt)&&(info->dfltDoodads)) + dflt= FindDoodadByType(info->dfltDoodads,type); + if (dflt==NULL) { + dflt= NextDfltDoodad(si,info); + if (dflt!=NULL) { + dflt->name= None; + dflt->type= type; + } + } + return dflt; +} + +/***====================================================================***/ + +static Bool +AddOverlay(SectionInfo *si,GeometryInfo *info,OverlayInfo *new) +{ +OverlayInfo * old; + + for (old=si->overlays;old!=NULL;old=(OverlayInfo *)old->defs.next) { + if (old->name==new->name) + break; + } + if (old!=NULL) { + if ((new->defs.merge==MergeReplace)||(new->defs.merge==MergeOverride)) { + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN2("Multiple overlays named \"%s\" for section \"%s\"\n", + XkbAtomText(info->dpy,old->name,XkbMessage), + XkbAtomText(info->dpy,si->name,XkbMessage)); + ACTION("Using last definition\n"); + } + ClearOverlayInfo(old); + old->nKeys= new->nKeys; + old->keys= new->keys; + new->nKeys= 0; + new->keys= NULL; + return True; + } + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN2("Multiple doodads named \"%s\" in section \"%s\"\n", + XkbAtomText(info->dpy,old->name,XkbMessage), + XkbAtomText(info->dpy,si->name,XkbMessage)); + ACTION("Using first definition\n"); + } + return True; + } + old= new; + new= uTypedCalloc(1,OverlayInfo); + if (!new) { + if (warningLevel>0) { + WSGO("Couldn't allocate a new OverlayInfo\n"); + ACTION2("Overlay \"%s\" in section \"%s\" will be incomplete\n", + XkbAtomText(info->dpy,old->name,XkbMessage), + XkbAtomText(info->dpy,si->name,XkbMessage)); + } + return False; + } + *new= *old; + old->nKeys= 0; + old->keys= NULL; + si->overlays= (OverlayInfo *)AddCommonInfo(&si->overlays->defs, + (CommonInfo *)new); + si->nOverlays++; + return True; +} + +/***====================================================================***/ + +static SectionInfo * +NextSection(GeometryInfo *info) +{ +SectionInfo * si; + + si= uTypedAlloc(SectionInfo); + if (si) { + *si= info->dfltSection; + si->defs.defined&= ~_GS_Default; + si->defs.next= NULL; + si->nRows= 0; + si->rows= NULL; + info->sections= (SectionInfo *)AddCommonInfo(&info->sections->defs, + (CommonInfo *)si); + info->nSections++; + } + return si; +} + +static SectionInfo * +FindMatchingSection(GeometryInfo *info,SectionInfo *new) +{ +SectionInfo * old; + + for (old=info->sections;old!=NULL;old=(SectionInfo *)old->defs.next) { + if (new->name==old->name) + return old; + } + return NULL; +} + +static Bool +AddSection(GeometryInfo *info,SectionInfo *new) +{ +SectionInfo * old; + + old= FindMatchingSection(info,new); + if (old!=NULL) { +#ifdef NOTDEF + if ((new->defs.merge==MergeReplace)||(new->defs.merge==MergeOverride)) { + SectionInfo *next= (SectionInfo *)old->defs.next; + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Duplicate shape name \"%s\"\n",shText(info->dpy,old)); + ACTION("Using last definition\n"); + } + *old= *new; + old->defs.next= &next->defs; + return True; + } + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple shapes named \"%s\"\n",shText(info->dpy,old)); + ACTION("Using first definition\n"); + } + return True; +#else + WARN("Don't know how to merge sections yet\n"); +#endif + } + old= new; + if ((new= NextSection(info))==NULL) + return False; + *new= *old; + new->defs.next= NULL; + old->nRows= old->nDoodads= old->nOverlays= 0; + old->rows= NULL; + old->doodads= NULL; + old->overlays= NULL; + if (new->doodads) { + DoodadInfo *di; + for (di=new->doodads;di;di=(DoodadInfo *)di->defs.next) { + di->section= new; + } + } + return True; +} + +/***====================================================================***/ + +static RowInfo * +NextRow(SectionInfo *si) +{ +RowInfo * row; + + row= uTypedAlloc(RowInfo); + if (row) { + *row= si->dfltRow; + row->defs.defined&= ~_GR_Default; + row->defs.next= NULL; + row->nKeys= 0; + row->keys= NULL; + si->rows= (RowInfo *)AddCommonInfo(&si->rows->defs,(CommonInfo *)row); + row->index= si->nRows++; + } + return row; +} + +static Bool +AddRow(SectionInfo *si,RowInfo *new) +{ +RowInfo * old; + + old= new; + if ((new= NextRow(si))==NULL) + return False; + *new= *old; + new->defs.next= NULL; + old->nKeys= 0; + old->keys= NULL; + return True; +} + +/***====================================================================***/ + +static KeyInfo * +NextKey(RowInfo *row) +{ +KeyInfo * key; + + key= uTypedAlloc(KeyInfo); + if (key) { + *key= row->dfltKey; + key->defs.defined&= ~_GK_Default; + key->defs.next= NULL; + key->index= row->nKeys++; + } + return key; +} + +static Bool +AddKey(RowInfo *row,KeyInfo *new) +{ +KeyInfo * old; + + old= new; + if ((new= NextKey(row))==NULL) + return False; + *new= *old; + new->defs.next= NULL; + row->keys= (KeyInfo *)AddCommonInfo(&row->keys->defs,(CommonInfo *)new); + return True; +} + +/***====================================================================***/ + +static void +MergeIncludedGeometry(GeometryInfo *into,GeometryInfo *from,unsigned merge) +{ +Bool clobber; + + if (from->errorCount>0) { + into->errorCount+= from->errorCount; + return; + } + clobber= (merge==MergeOverride)||(merge==MergeReplace); + if (into->name==NULL) { + into->name= from->name; + from->name= NULL; + } + if ((into->widthMM==0)||((from->widthMM!=0)&&clobber)) + into->widthMM= from->widthMM; + if ((into->heightMM==0)||((from->heightMM!=0)&&clobber)) + into->heightMM= from->heightMM; + if ((into->font==None)||((from->font!=None)&&clobber)) + into->font= from->font; + if ((into->fontSlant==None)||((from->fontSlant!=None)&&clobber)) + into->fontSlant= from->fontSlant; + if ((into->fontWeight==None)||((from->fontWeight!=None)&&clobber)) + into->fontWeight= from->fontWeight; + if ((into->fontSetWidth==None)||((from->fontSetWidth!=None)&&clobber)) + into->fontSetWidth= from->fontSetWidth; + if ((into->fontVariant==None)||((from->fontVariant!=None)&&clobber)) + into->fontVariant= from->fontVariant; + if ((into->fontSize==0)||((from->fontSize!=0)&&clobber)) + into->fontSize= from->fontSize; + if ((into->fontEncoding==None)||((from->fontEncoding!=None)&&clobber)) + into->fontEncoding= from->fontEncoding; + if ((into->fontSpec==None)||((from->fontSpec!=None)&&clobber)) + into->fontSpec= from->fontSpec; + if ((into->baseColor==None)||((from->baseColor!=None)&&clobber)) + into->baseColor= from->baseColor; + if ((into->labelColor==None)||((from->labelColor!=None)&&clobber)) + into->labelColor= from->labelColor; + into->nextPriority= from->nextPriority; + if (from->props!=NULL) { + PropertyInfo *pi; + for (pi=from->props;pi;pi=(PropertyInfo *)pi->defs.next) { + if (!AddProperty(into,pi)) + into->errorCount++; + } + } + if (from->shapes!=NULL) { + ShapeInfo * si; + + for (si=from->shapes;si;si=(ShapeInfo *)si->defs.next) { + if (!AddShape(into,si)) + into->errorCount++; + } + } + if (from->sections!=NULL) { + SectionInfo * si; + + for (si=from->sections;si;si=(SectionInfo *)si->defs.next) { + if (!AddSection(into,si)) + into->errorCount++; + } + } + if (from->doodads!=NULL) { + DoodadInfo * di; + + for (di=from->doodads;di;di=(DoodadInfo *)di->defs.next) { + if (!AddDoodad(NULL,into,di)) + into->errorCount++; + } + } + if (!MergeAliases(&into->aliases,&from->aliases,merge)) + into->errorCount++; + return; +} + +typedef void (*FileHandler)( + XkbFile * /* file */, + XkbDescPtr /* xkb */, + unsigned /* merge */, + GeometryInfo * /* info */ +); + +static Bool +HandleIncludeGeometry(IncludeStmt *stmt,XkbDescPtr xkb,GeometryInfo *info, + FileHandler hndlr) +{ +unsigned newMerge; +XkbFile * rtrn; +GeometryInfo included; +Bool haveSelf; + + haveSelf= False; + if ((stmt->file==NULL)&&(stmt->map==NULL)) { + haveSelf= True; + included= *info; + bzero(info,sizeof(GeometryInfo)); + } + else if (ProcessIncludeFile(stmt,XkmGeometryIndex,&rtrn,&newMerge)) { + InitGeometryInfo(&included,rtrn->id,newMerge); + included.nextPriority= info->nextPriority; + included.dfltCornerRadius= info->dfltCornerRadius; + DupSectionInfo(&included.dfltSection,&info->dfltSection,info); + (*hndlr)(rtrn,xkb,MergeOverride,&included); + if (stmt->stmt!=NULL) { + if (included.name!=NULL) + uFree(included.name); + included.name= stmt->stmt; + stmt->stmt= NULL; + } + } + else { + info->errorCount+= 10; + return False; + } + if ((stmt->next!=NULL)&&(included.errorCount<1)) { + IncludeStmt * next; + unsigned op; + GeometryInfo next_incl; + + for (next=stmt->next;next!=NULL;next=next->next) { + if ((next->file==NULL)&&(next->map==NULL)) { + haveSelf= True; + MergeIncludedGeometry(&included,info,next->merge); + ClearGeometryInfo(info); + } + else if (ProcessIncludeFile(next,XkmGeometryIndex,&rtrn,&op)) { + InitGeometryInfo(&next_incl,rtrn->id,op); + next_incl.nextPriority= included.nextPriority; + next_incl.dfltCornerRadius= included.dfltCornerRadius; + DupSectionInfo(&next_incl.dfltSection,&included.dfltSection, + &included); + (*hndlr)(rtrn,xkb,MergeOverride,&next_incl); + MergeIncludedGeometry(&included,&next_incl,op); + ClearGeometryInfo(&next_incl); + } + else { + info->errorCount+= 10; + return False; + } + } + } + if (haveSelf) + *info= included; + else { + MergeIncludedGeometry(info,&included,newMerge); + ClearGeometryInfo(&included); + } + return (info->errorCount==0); +} + +static int +SetShapeField( ShapeInfo * si, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + GeometryInfo * info) +{ +ExprResult tmp; + + if ((uStrCaseCmp(field,"radius")==0)||(uStrCaseCmp(field,"corner")==0)|| + (uStrCaseCmp(field,"cornerradius")==0)) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("key shape",field,shText(info->dpy,si)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("key shape",field, + shText(info->dpy,si),"number"); + } + if (si) + si->dfltCornerRadius= tmp.ival; + else info->dfltCornerRadius= tmp.ival; + return True; + } + info->errorCount++; + return ReportBadField("key shape",field,shText(info->dpy,si)); +} + +static int +SetShapeDoodadField( DoodadInfo * di, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SectionInfo * si, + GeometryInfo * info) +{ +ExprResult tmp; +char * typeName; + + typeName= (di->type==XkbSolidDoodad?"solid doodad":"outline doodad"); + if ((!uStrCaseCmp(field,"corner"))||(!uStrCaseCmp(field,"cornerradius"))) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Corner; + di->corner= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"angle")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Angle; + di->angle= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"shape")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"string"); + } + di->shape= XkbInternAtom(info->dpy,tmp.str,False); + di->defs.defined|= _GD_Shape; + return True; + } + return ReportBadField(typeName,field,ddText(info->dpy,di)); +} + +#define FIELD_STRING 0 +#define FIELD_SHORT 1 +#define FIELD_USHORT 2 + +static int +SetTextDoodadField( DoodadInfo * di, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SectionInfo * si, + GeometryInfo * info) +{ +ExprResult tmp; +unsigned def; +unsigned type; +char * typeName= "text doodad"; +union { + Atom * str; + short * ival; + unsigned short * uval; +} pField; + + if (uStrCaseCmp(field,"angle")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Angle; + di->angle= tmp.ival; + return True; + } + if (uStrCaseCmp(field,"width")==0) { + type= FIELD_USHORT; + pField.uval= &di->width; + def= _GD_Width; + } + else if (uStrCaseCmp(field,"height")==0) { + type= FIELD_USHORT; + pField.uval= &di->height; + def= _GD_Height; + } + else if (uStrCaseCmp(field,"text")==0) { + type= FIELD_STRING; + pField.str= &di->text; + def= _GD_Text; + } + else if (uStrCaseCmp(field,"font")==0) { + type= FIELD_STRING; + pField.str= &di->font; + def= _GD_Font; + } + else if ((uStrCaseCmp(field,"fontslant")==0)|| + (uStrCaseCmp(field,"slant")==0)) { + type= FIELD_STRING; + pField.str= &di->fontSlant; + def= _GD_FontSlant; + } + else if ((uStrCaseCmp(field,"fontweight")==0)|| + (uStrCaseCmp(field,"weight")==0)) { + type= FIELD_STRING; + pField.str= &di->fontWeight; + def= _GD_FontWeight; + } + else if ((uStrCaseCmp(field,"fontwidth")==0)|| + (uStrCaseCmp(field,"setwidth")==0)) { + type= FIELD_STRING; + pField.str= &di->fontSetWidth; + def= _GD_FontSetWidth; + } + else if ((uStrCaseCmp(field,"fontvariant")==0)|| + (uStrCaseCmp(field,"variant")==0)) { + type= FIELD_STRING; + pField.str= &di->fontVariant; + def= _GD_FontVariant; + } + else if ((uStrCaseCmp(field,"fontencoding")==0)|| + (uStrCaseCmp(field,"encoding")==0)) { + type= FIELD_STRING; + pField.str= &di->fontEncoding; + def= _GD_FontEncoding; + } + else if ((uStrCaseCmp(field,"xfont")==0)|| + (uStrCaseCmp(field,"xfontname")==0)) { + type= FIELD_STRING; + pField.str= &di->fontSpec; + def= _GD_FontSpec; + } + else if (uStrCaseCmp(field,"fontsize")==0) { + type= FIELD_USHORT; + pField.uval= &di->fontSize; + def= _GD_FontSize; + } + else { + return ReportBadField(typeName,field,ddText(info->dpy,di)); + } + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (type==FIELD_STRING) { + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di), + "string"); + } + di->defs.defined|= def; + *pField.str= XkbInternAtom(NULL,tmp.str,False); + } + else { + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"number"); + } + if ((type==FIELD_USHORT)&&(tmp.ival<0)) { + info->errorCount++; + return + ReportBadType(typeName,field,ddText(info->dpy,di),"unsigned"); + } + di->defs.defined|= def; + if (type==FIELD_USHORT) + *pField.uval= tmp.uval; + else *pField.ival= tmp.ival; + } + return True; +} + +static int +SetIndicatorDoodadField( DoodadInfo * di, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SectionInfo * si, + GeometryInfo * info) +{ +ExprResult tmp; + + if ((uStrCaseCmp(field,"oncolor")==0)||(uStrCaseCmp(field,"offcolor")==0) + ||(uStrCaseCmp(field,"shape")==0)) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("indicator doodad",field, + ddText(info->dpy,di)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("indicator doodad",field,ddText(info->dpy,di), + "string"); + } + if (uStrCaseCmp(field,"oncolor")==0) { + di->defs.defined|= _GD_Color; + di->color= XkbInternAtom(NULL,tmp.str,False); + } + else if (uStrCaseCmp(field,"offcolor")==0) { + di->defs.defined|= _GD_OffColor; + di->offColor= XkbInternAtom(NULL,tmp.str,False); + } + else if (uStrCaseCmp(field,"shape")==0) { + di->defs.defined|= _GD_Shape; + di->shape= XkbInternAtom(info->dpy,tmp.str,False); + } + return True; + } + return ReportBadField("indicator doodad",field,ddText(info->dpy,di)); +} + +static int +SetLogoDoodadField( DoodadInfo * di, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SectionInfo * si, + GeometryInfo * info) +{ +ExprResult tmp; +char * typeName= "logo doodad"; + + if ((!uStrCaseCmp(field,"corner"))||(!uStrCaseCmp(field,"cornerradius"))) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Corner; + di->corner= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"angle")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Angle; + di->angle= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"shape")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"string"); + } + di->shape= XkbInternAtom(info->dpy,tmp.str,False); + di->defs.defined|= _GD_Shape; + return True; + } + else if ((!uStrCaseCmp(field,"logoname"))||(!uStrCaseCmp(field,"name"))) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray(typeName,field,ddText(info->dpy,di)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType(typeName,field,ddText(info->dpy,di),"string"); + } + di->logoName= uStringDup(tmp.str); + return True; + } + return ReportBadField(typeName,field,ddText(info->dpy,di)); +} + +static int +SetDoodadField( DoodadInfo * di, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SectionInfo * si, + GeometryInfo * info) +{ +ExprResult tmp; + + if (uStrCaseCmp(field,"priority")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("doodad",field,ddText(info->dpy,di)); + } + if (!ExprResolveInteger(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("doodad",field,ddText(info->dpy,di),"integer"); + } + if ((tmp.ival<0)||(tmp.ival>XkbGeomMaxPriority)) { + info->errorCount++; + ERROR2("Doodad priority %d out of range (must be 0..%d)\n", + tmp.ival,XkbGeomMaxPriority); + ACTION1("Priority for doodad %s not changed",ddText(info->dpy,di)); + return False; + } + di->defs.defined|= _GD_Priority; + di->priority= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"left")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("doodad",field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("doodad",field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Left; + di->left= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"top")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("doodad",field,ddText(info->dpy,di)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("doodad",field,ddText(info->dpy,di),"number"); + } + di->defs.defined|= _GD_Top; + di->top= tmp.ival; + return True; + } + else if (uStrCaseCmp(field,"color")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("doodad",field,ddText(info->dpy,di)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("doodad",field,ddText(info->dpy,di),"string"); + } + di->defs.defined|= _GD_Color; + di->color= XkbInternAtom(NULL,tmp.str,False); + return True; + } + switch (di->type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + return SetShapeDoodadField(di,field,arrayNdx,value,si,info); + case XkbTextDoodad: + return SetTextDoodadField(di,field,arrayNdx,value,si,info); + case XkbIndicatorDoodad: + return SetIndicatorDoodadField(di,field,arrayNdx,value,si,info); + case XkbLogoDoodad: + return SetLogoDoodadField(di,field,arrayNdx,value,si,info); + } + WSGO1("Unknown doodad type %d in SetDoodadField\n",(unsigned int)di->type); + ACTION2("Definition of %s in %s ignored\n",field,ddText(info->dpy,di)); + return False; +} + +static int +SetSectionField( SectionInfo * si, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + GeometryInfo * info) +{ +unsigned short * pField; +unsigned def; +ExprResult tmp; + + pField= NULL; + def= 0; + if (uStrCaseCmp(field,"priority")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard section",field,scText(info->dpy,si)); + } + if (!ExprResolveInteger(value,&tmp,NULL,NULL)) { + info->errorCount++; + ReportBadType("keyboard section",field,scText(info->dpy,si), + "integer"); + return False; + } + if ((tmp.ival<0)||(tmp.ival>XkbGeomMaxPriority)) { + info->errorCount++; + ERROR2("Section priority %d out of range (must be 0..%d)\n", + tmp.ival,XkbGeomMaxPriority); + ACTION1("Priority for section %s not changed",scText(info->dpy,si)); + return False; + } + si->priority= tmp.ival; + si->defs.defined|= _GS_Priority; + return True; + } + else if (uStrCaseCmp(field,"top")==0) { + pField= &si->top; + def= _GS_Top; + } + else if (uStrCaseCmp(field,"left")==0) { + pField= &si->left; + def= _GS_Left; + } + else if (uStrCaseCmp(field,"width")==0) { + pField= &si->width; + def= _GS_Width; + } + else if (uStrCaseCmp(field,"height")==0) { + pField= &si->height; + def= _GS_Height; + } + else if (uStrCaseCmp(field,"angle")==0) { + pField= &si->angle; + def= _GS_Angle; + } + else { + info->errorCount++; + return ReportBadField("keyboard section",field,scText(info->dpy,si)); + } + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard section",field,scText(info->dpy,si)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + ReportBadType("keyboard section",field,scText(info->dpy,si),"number"); + return False; + } + si->defs.defined|= def; + *pField= tmp.uval; + return True; +} + +static int +SetRowField( RowInfo * row, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + GeometryInfo * info) +{ +ExprResult tmp; + + if (uStrCaseCmp(field,"top")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard row",field,rowText(info->dpy,row)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard row",field,rowText(info->dpy,row), + "number"); + } + row->defs.defined|= _GR_Top; + row->top= tmp.uval; + } + else if (uStrCaseCmp(field,"left")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard row",field,rowText(info->dpy,row)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard row",field,rowText(info->dpy,row), + "number"); + } + row->defs.defined|= _GR_Left; + row->left= tmp.uval; + } + else if (uStrCaseCmp(field,"vertical")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard row",field,rowText(info->dpy,row)); + } + if (!ExprResolveBoolean(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard row",field,rowText(info->dpy,row), + "boolean"); + } + row->defs.defined|= _GR_Vertical; + row->vertical= tmp.uval; + } + else { + info->errorCount++; + return ReportBadField("keyboard row",field,rowText(info->dpy,row)); + } + return True; +} + +static int +SetKeyField( KeyInfo *key, + char *field, + ExprDef *arrayNdx, + ExprDef *value, + GeometryInfo *info) +{ +ExprResult tmp; + + if (uStrCaseCmp(field,"gap")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("key",field,keyText(key)); + } + if (!ExprResolveFloat(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("key",field,keyText(key),"number"); + } + key->defs.defined|= _GK_Gap; + key->gap= tmp.ival; + } + else if (uStrCaseCmp(field,"shape")==0) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("key",field,keyText(key)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("key",field,keyText(key),"string"); + } + key->defs.defined|= _GK_Shape; + key->shape= XkbInternAtom(info->dpy,tmp.str,False); + } + else if ((uStrCaseCmp(field,"color")==0)|| + (uStrCaseCmp(field,"keycolor")==0)) { + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("key",field,keyText(key)); + } + if (!ExprResolveString(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("key",field,keyText(key),"string"); + } + key->defs.defined|= _GK_Color; + key->color= XkbInternAtom(NULL,tmp.str,False); + } + else if ((uStrCaseCmp(field,"name")==0)||(uStrCaseCmp(field,"keyname")==0)){ + if (arrayNdx!=NULL) { + info->errorCount++; + return ReportNotArray("key",field,keyText(key)); + } + if (!ExprResolveKeyName(value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("key",field,keyText(key),"key name"); + } + key->defs.defined|= _GK_Name; + bzero(key->name,XkbKeyNameLength+1); + strncpy(key->name,tmp.keyName.name,XkbKeyNameLength); + } + else { + info->errorCount++; + return ReportBadField("key",field,keyText(key)); + } + return True; +} + +static int +SetGeometryProperty(GeometryInfo *info,char *property,ExprDef *value) +{ +PropertyInfo pi; +ExprResult result; + + InitPropertyInfo(&pi,info); + pi.name= property; + if (!ExprResolveString(value,&result,NULL,NULL)) { + info->errorCount++; + ERROR("Property values must be type string\n"); + ACTION1("Ignoring illegal definition of \"%s\" property\n",property); + return False; + } + pi.value= result.str; + return AddProperty(info,&pi); +} + +static int +HandleGeometryVar(VarDef *stmt,XkbDescPtr xkb,GeometryInfo *info) +{ +ExprResult elem,field,tmp; +ExprDef * ndx; +DoodadInfo * di; +Atom * pField; + + if (ExprResolveLhs(stmt->name,&elem,&field,&ndx)==0) + return 0; /* internal error, already reported */ + if (elem.str&&(uStrCaseCmp(elem.str,"shape")==0)) + return SetShapeField(NULL,field.str,ndx,stmt->value,info); + if (elem.str&&(uStrCaseCmp(elem.str,"key")==0)) + return SetKeyField(&info->dfltSection.dfltRow.dfltKey, + field.str,ndx,stmt->value,info); + if (elem.str&&(uStrCaseCmp(elem.str,"row")==0)) + return SetRowField(&info->dfltSection.dfltRow,field.str,ndx, + stmt->value,info); + if (elem.str&&(uStrCaseCmp(elem.str,"section")==0)) { + return SetSectionField(&info->dfltSection,field.str,ndx,stmt->value, + info); + } + if (elem.str&&(uStrCaseCmp(elem.str,"property")==0)) { + if (ndx!=NULL) { + info->errorCount++; + ERROR1("The %s geometry property is not an array\n",field.str); + ACTION("Ignoring illegal property definition\n"); + return False; + } + return SetGeometryProperty(info,field.str,stmt->value); + } + if (elem.str&&((di=FindDfltDoodadByTypeName(elem.str,NULL,info))!=NULL)) { + return SetDoodadField(di,field.str,ndx,stmt->value,NULL,info); + } + if (elem.str&&(uStrCaseCmp(elem.str,"solid")==0)) { + DoodadInfo *dflt; + dflt= FindDoodadByType(info->dfltDoodads,XkbSolidDoodad); + if (dflt==NULL) + dflt= NextDfltDoodad(NULL,info); + return SetDoodadField(dflt,field.str,ndx,stmt->value,NULL,info); + } + if (elem.str&&(uStrCaseCmp(elem.str,"outline")==0)) { + DoodadInfo *dflt; + dflt= FindDoodadByType(info->dfltDoodads,XkbOutlineDoodad); + if (dflt==NULL) + dflt= NextDfltDoodad(NULL,info); + return SetDoodadField(dflt,field.str,ndx,stmt->value,NULL,info); + } + if (elem.str&&(uStrCaseCmp(elem.str,"text")==0)) { + DoodadInfo *dflt; + dflt= FindDoodadByType(info->dfltDoodads,XkbTextDoodad); + if (dflt==NULL) + dflt= NextDfltDoodad(NULL,info); + return SetDoodadField(dflt,field.str,ndx,stmt->value,NULL,info); + } + if (elem.str&&(uStrCaseCmp(elem.str,"indicator")==0)) { + DoodadInfo *dflt; + dflt= FindDoodadByType(info->dfltDoodads,XkbIndicatorDoodad); + if (dflt==NULL) + dflt= NextDfltDoodad(NULL,info); + return SetDoodadField(dflt,field.str,ndx,stmt->value,NULL,info); + } + if (elem.str&&(uStrCaseCmp(elem.str,"logo")==0)) { + DoodadInfo *dflt; + dflt= FindDoodadByType(info->dfltDoodads,XkbLogoDoodad); + if (dflt==NULL) + dflt= NextDfltDoodad(NULL,info); + return SetDoodadField(dflt,field.str,ndx,stmt->value,NULL,info); + } + if (elem.str) { + WARN("Assignment to field of unknown element\n"); + ACTION2("No value assigned to %s.%s\n",elem.str,field.str); + return False; + } + + if ((uStrCaseCmp(field.str,"width")==0)|| + (uStrCaseCmp(field.str,"widthmm")==0)) { + if (ndx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard",field.str,"geometry"); + } + if (!ExprResolveFloat(stmt->value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard",field.str,"geometry","number"); + } + if (tmp.ival<1) { + WARN("Keyboard width must be positive\n"); + ACTION1("Ignoring illegal keyboard width %s\n", + XkbGeomFPText(tmp.ival,XkbMessage)); + return True; + } + if (info->widthMM!=0) { + WARN("Keyboard width multiply defined\n"); + ACTION1("Using last definition (%s),", + XkbGeomFPText(tmp.ival,XkbMessage)); + INFO1(" ignoring first (%s)\n", + XkbGeomFPText(info->widthMM,XkbMessage)); + } + info->widthMM= tmp.ival; + return True; + } + else if ((uStrCaseCmp(field.str,"height")==0)|| + (uStrCaseCmp(field.str,"heightmm")==0)) { + if (ndx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard",field.str,"geometry"); + } + if (!ExprResolveFloat(stmt->value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard",field.str,"geometry","number"); + } + if (tmp.ival<1) { + WARN("Keyboard height must be positive\n"); + ACTION1("Ignoring illegal keyboard height %s\n", + XkbGeomFPText(tmp.ival,XkbMessage)); + return True; + } + if (info->heightMM!=0) { + WARN("Keyboard height multiply defined\n"); + ACTION1("Using last definition (%s),", + XkbGeomFPText(tmp.ival,XkbMessage)); + INFO1(" ignoring first (%s)\n", + XkbGeomFPText(info->heightMM,XkbMessage)); + } + info->heightMM= tmp.ival; + return True; + } + else if (uStrCaseCmp(field.str,"font")==0) { + pField= &info->font; + } + else if ((uStrCaseCmp(field.str,"fontslant")==0)|| + (uStrCaseCmp(field.str,"slant")==0)) { + pField= &info->fontSlant; + } + else if ((uStrCaseCmp(field.str,"fontweight")==0)|| + (uStrCaseCmp(field.str,"weight")==0)) { + pField= &info->fontWeight; + } + else if ((uStrCaseCmp(field.str,"fontwidth")==0)|| + (uStrCaseCmp(field.str,"setwidth")==0)) { + pField= &info->fontWeight; + } + else if ((uStrCaseCmp(field.str,"fontencoding")==0)|| + (uStrCaseCmp(field.str,"encoding")==0)) { + pField= &info->fontEncoding; + } + else if ((uStrCaseCmp(field.str,"xfont")==0)|| + (uStrCaseCmp(field.str,"xfontname")==0)) { + pField= &info->fontSpec; + } + else if (uStrCaseCmp(field.str,"fontsize")==0) { + if (ndx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard",field.str,"geometry"); + } + if (!ExprResolveFloat(stmt->value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard",field.str,"geometry","number"); + } + if ((tmp.ival<40)||(tmp.ival>2550)) { + info->errorCount++; + ERROR1("Illegal font size %d (must be 4..255)\n",tmp.ival); + ACTION("Ignoring font size in keyboard geometry\n"); + return False; + } + info->fontSize= tmp.ival; + return True; + } + else if ((uStrCaseCmp(field.str,"color")==0)|| + (uStrCaseCmp(field.str,"basecolor")==0)){ + if (ndx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard",field.str,"geometry"); + } + if (!ExprResolveString(stmt->value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard",field.str,"geometry","string"); + } + info->baseColor= XkbInternAtom(NULL,tmp.str,False); + return True; + } + else if (uStrCaseCmp(field.str,"labelcolor")==0){ + if (ndx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard",field.str,"geometry"); + } + if (!ExprResolveString(stmt->value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard",field.str,"geometry","string"); + } + info->labelColor= XkbInternAtom(NULL,tmp.str,False); + return True; + } + else { + return SetGeometryProperty(info,field.str,stmt->value); + } + + if (ndx!=NULL) { + info->errorCount++; + return ReportNotArray("keyboard",field.str,"geometry"); + } + if (!ExprResolveString(stmt->value,&tmp,NULL,NULL)) { + info->errorCount++; + return ReportBadType("keyboard",field.str,"geometry","string"); + } + *pField= XkbInternAtom(NULL,tmp.str,False); + return True; +} + +/***====================================================================***/ + +static Bool +HandleShapeBody(ShapeDef *def,ShapeInfo *si,unsigned merge,GeometryInfo *info) +{ +OutlineDef * ol; +int nOut,nPt; +XkbOutlinePtr outline; +ExprDef * pt; + + if (def->nOutlines<1) { + WARN1("Shape \"%s\" has no outlines\n",shText(info->dpy,si)); + ACTION("Definition ignored\n"); + return True; + } + si->nOutlines= def->nOutlines; + si->outlines= uTypedCalloc(def->nOutlines,XkbOutlineRec); + if (!si->outlines) { + ERROR1("Couldn't allocate outlines for \"%s\"\n",shText(info->dpy,si)); + ACTION("Definition ignored\n"); + info->errorCount++; + return False; + } + for (nOut=0,ol=def->outlines;ol!=NULL;ol=(OutlineDef *)ol->common.next) { + if (ol->nPoints<1) { + SetShapeField(si,XkbAtomGetString(NULL,ol->field),NULL, + ol->points,info); + continue; + } + outline= NULL; + outline= &si->outlines[nOut++]; + outline->num_points= ol->nPoints; + outline->corner_radius= si->dfltCornerRadius; + outline->points= uTypedCalloc(ol->nPoints,XkbPointRec); + if (!outline->points) { + ERROR1("Can't allocate points for \"%s\"\n",shText(info->dpy,si)); + ACTION("Definition ignored\n"); + info->errorCount++; + return False; + } + for (nPt=0,pt=ol->points;pt!=NULL;pt=(ExprDef *)pt->common.next) { + outline->points[nPt].x= pt->value.coord.x; + outline->points[nPt].y= pt->value.coord.y; + nPt++; + } + if (ol->field!=None) { + char *str= XkbAtomText(NULL,ol->field,XkbMessage); + if ((uStrCaseCmp(str,"approximation")==0)|| + (uStrCaseCmp(str,"approx")==0)) { + if (si->approx==NULL) + si->approx= outline; + else { + WARN1("Multiple approximations for \"%s\"\n", + shText(info->dpy,si)); + ACTION("Treating all but the first as normal outlines\n"); + } + } + else if (uStrCaseCmp(str,"primary")==0) { + if (si->primary==NULL) + si->primary= outline; + else { + WARN1("Multiple primary outlines for \"%s\"\n", + shText(info->dpy,si)); + ACTION("Treating all but the first as normal outlines\n"); + } + } + else { + WARN2("Unknown outline type %s for \"%s\"\n",str, + shText(info->dpy,si)); + ACTION("Treated as a normal outline\n"); + } + } + } + if (nOut!=si->nOutlines) { + WSGO2("Expected %d outlines, got %d\n",(unsigned int)si->nOutlines, + nOut); + si->nOutlines= nOut; + } + return True; +} + +static int +HandleShapeDef(ShapeDef *def,XkbDescPtr xkb,unsigned merge,GeometryInfo *info) +{ +ShapeInfo si; + + if (def->merge!=MergeDefault) + merge= def->merge; + + bzero(&si,sizeof(ShapeInfo)); + si.defs.merge= merge; + si.name= XkbInternAtom(info->dpy,XkbAtomGetString(NULL,def->name),False); + si.dfltCornerRadius= info->dfltCornerRadius; + if (!HandleShapeBody(def,&si,merge,info)) + return False; + if (!AddShape(info,&si)) + return False; + return True; +} + +/***====================================================================***/ + +static int +HandleDoodadDef( DoodadDef *def, + unsigned merge, + SectionInfo *si, + GeometryInfo *info) +{ +ExprResult elem,field; +ExprDef * ndx; +DoodadInfo new; +VarDef * var; + + if (def->common.stmtType==StmtIndicatorMapDef) { + def->common.stmtType= StmtDoodadDef; + def->type= XkbIndicatorDoodad; + } + InitDoodadInfo(&new,def->type,si,info); + new.name= XkbInternAtom(info->dpy,XkbAtomGetString(NULL,def->name),False); + for (var=def->body;var!=NULL;var= (VarDef *)var->common.next) { + if (ExprResolveLhs(var->name,&elem,&field,&ndx)==0) + return 0; /* internal error, already reported */ + if (elem.str!=NULL) { + WARN1("Assignment to field of unknown element in doodad %s\n", + ddText(info->dpy,&new)); + ACTION2("No value assigned to %s.%s\n",elem.str,field.str); + } + else if (!SetDoodadField(&new,field.str,ndx,var->value,si,info)) + return False; + } + if (!AddDoodad(si,info,&new)) + return False; + ClearDoodadInfo(&new); + return True; +} + +/***====================================================================***/ + +static int +HandleOverlayDef( OverlayDef * def, + unsigned merge, + SectionInfo * si, + GeometryInfo * info) +{ +OverlayKeyDef * keyDef; +OverlayKeyInfo *key; +OverlayInfo ol; + + if ((def->nKeys<1)&&(warningLevel>3)) { + WARN2("Overlay \"%s\" in section \"%s\" has no keys\n", + XkbAtomText(NULL,def->name,XkbMessage), + scText(info->dpy,si)); + ACTION("Overlay ignored\n"); + return True; + } + bzero(&ol,sizeof(OverlayInfo)); + ol.name= XkbInternAtom(info->dpy,XkbAtomGetString(NULL,def->name),False); + for (keyDef= def->keys;keyDef;keyDef=(OverlayKeyDef *)keyDef->common.next) { + key= uTypedCalloc(1,OverlayKeyInfo); + if ((!key)&&warningLevel>0) { + WSGO("Couldn't allocate OverlayKeyInfo\n"); + ACTION2("Overlay %s for section %s will be incomplete\n", + oiText(info->dpy,&ol), + scText(info->dpy,si)); + return False; + } + strncpy(key->over,keyDef->over,XkbKeyNameLength); + strncpy(key->under,keyDef->under,XkbKeyNameLength); + key->sectionRow= _GOK_UnknownRow; + key->overlayRow= _GOK_UnknownRow; + ol.keys= (OverlayKeyInfo *)AddCommonInfo(&ol.keys->defs, + (CommonInfo *)key); + ol.nKeys++; + } + if (!AddOverlay(si,info,&ol)) + return False; + ClearOverlayInfo(&ol); + return True; +} + +/***====================================================================***/ + +static Bool +HandleComplexKey(KeyDef *def,KeyInfo *key,GeometryInfo *info) +{ +RowInfo * row; +ExprDef * expr; + + row= key->row; + for (expr=def->expr;expr!=NULL;expr=(ExprDef *)expr->common.next) { + if (expr->op==OpAssign) { + ExprResult elem,f; + ExprDef *ndx; + if (ExprResolveLhs(expr->value.binary.left,&elem,&f,&ndx)==0) + return False; /* internal error, already reported */ + if ((elem.str==NULL)||(uStrCaseCmp(elem.str,"key")==0)) { + if (!SetKeyField(key,f.str,ndx,expr->value.binary.right,info)) + return False; + } + else { + ERROR("Illegal element used in a key definition\n"); + ACTION2("Assignment to %s.%s ignored\n",elem.str,f.str); + return False; + } + } + else { + switch (expr->type) { + case TypeInt: case TypeFloat: + if (!SetKeyField(key,"gap",NULL,expr,info)) + return False; + break; + case TypeString: + if (!SetKeyField(key,"shape",NULL,expr,info)) + return False; + break; + case TypeKeyName: + if (!SetKeyField(key,"name",NULL,expr,info)) + return False; + break; + default: + ERROR("Cannot determine field for unnamed expression\n"); + ACTION3("Ignoring key %d in row %d of section %s\n", + row->nKeys+1,row->section->nRows+1, + rowText(info->dpy,row)); + return False; + } + } + } + return True; +} + +static Bool +HandleRowBody(RowDef *def,RowInfo *row,unsigned merge,GeometryInfo *info) +{ +KeyDef * keyDef; + + if ((def->nKeys<1)&&(warningLevel>3)) { + ERROR1("Row in section %s has no keys\n",rowText(info->dpy,row)); + ACTION("Section ignored\n"); + return True; + } + for (keyDef= def->keys; keyDef!=NULL;keyDef=(KeyDef *)keyDef->common.next) { + if (keyDef->common.stmtType==StmtVarDef) { + VarDef *var= (VarDef *)keyDef; + ExprResult elem,field; + ExprDef *ndx; + if (ExprResolveLhs(var->name,&elem,&field,&ndx)==0) + return 0; /* internal error, already reported */ + if ((elem.str==NULL)||(uStrCaseCmp(elem.str,"row")==0)) { + if (!SetRowField(row,field.str,ndx,var->value,info)) + return False; + } + else if (uStrCaseCmp(elem.str,"key")==0) { + if (!SetKeyField(&row->dfltKey,field.str,ndx,var->value,info)) + return False; + } + else { + WARN("Assignment to field of unknown element in row\n"); + ACTION2("No value assigned to %s.%s\n",elem.str,field.str); + } + } + else if (keyDef->common.stmtType==StmtKeyDef) { + KeyInfo key; + InitKeyInfo(&key,row,info); + if (keyDef->name!=NULL) { + int len= strlen(keyDef->name); + if ((len<1)||(len>XkbKeyNameLength)) { + ERROR2("Illegal name %s for key in section %s\n", + keyDef->name, + rowText(info->dpy,row)); + ACTION("Section not compiled\n"); + return False; + } + bzero(key.name,XkbKeyNameLength+1); + strncpy(key.name,keyDef->name,XkbKeyNameLength); + key.defs.defined|= _GK_Name; + } + else if (!HandleComplexKey(keyDef,&key,info)) + return False; + if (!AddKey(row,&key)) + return False; + } + else { + WSGO1("Unexpected statement (type %d) in row body\n", + keyDef->common.stmtType); + return False; + } + } + return True; +} + +static Bool +HandleSectionBody( SectionDef * def, + SectionInfo * si, + unsigned merge, + GeometryInfo * info) +{ +RowDef * rowDef; +DoodadInfo * di; + + for (rowDef= def->rows;rowDef!=NULL;rowDef=(RowDef *)rowDef->common.next) { + if (rowDef->common.stmtType==StmtVarDef) { + VarDef *var= (VarDef *)rowDef; + ExprResult elem,field; + ExprDef *ndx; + if (ExprResolveLhs(var->name,&elem,&field,&ndx)==0) + return 0; /* internal error, already reported */ + if ((elem.str==NULL)||(uStrCaseCmp(elem.str,"section")==0)) { + if (!SetSectionField(si,field.str,ndx,var->value,info)) + return False; + } + else if (uStrCaseCmp(elem.str,"row")==0) { + if (!SetRowField(&si->dfltRow,field.str,ndx,var->value,info)) + return False; + } + else if (uStrCaseCmp(elem.str,"key")==0) { + if(!SetKeyField(&si->dfltRow.dfltKey,field.str,ndx, + var->value,info)) + return False; + } + else if ((di=FindDfltDoodadByTypeName(elem.str,si,info))!=NULL) { + if (!SetDoodadField(di,field.str,ndx,var->value,si,info)) + return False; + } + else { + WARN("Assignment to field of unknown element in section\n"); + ACTION2("No value assigned to %s.%s\n",elem.str,field.str); + } + } + else if (rowDef->common.stmtType==StmtRowDef) { + RowInfo row; + InitRowInfo(&row,si,info); + if (!HandleRowBody(rowDef,&row,merge,info)) + return False; + if (!AddRow(si,&row)) + return False; +/* ClearRowInfo(&row,info);*/ + } + else if ((rowDef->common.stmtType==StmtDoodadDef)|| + (rowDef->common.stmtType==StmtIndicatorMapDef)) { + if (!HandleDoodadDef((DoodadDef *)rowDef,merge,si,info)) + return False; + } + else if (rowDef->common.stmtType==StmtOverlayDef) { + if (!HandleOverlayDef((OverlayDef *)rowDef,merge,si,info)) + return False; + } + else { + WSGO1("Unexpected statement (type %d) in section body\n", + rowDef->common.stmtType); + return False; + } + } + if (si->nRows!=def->nRows) { + WSGO2("Expected %d rows, found %d\n",(unsigned int)def->nRows, + (unsigned int)si->nRows); + ACTION1("Definition of section %s might be incorrect\n", + scText(info->dpy,si)); + } + return True; +} + +static int +HandleSectionDef( SectionDef * def, + XkbDescPtr xkb, + unsigned merge, + GeometryInfo * info) +{ +SectionInfo si; +char * str; + + if (def->merge!=MergeDefault) + merge= def->merge; + InitSectionInfo(&si,info); + si.defs.merge= merge; + str= XkbAtomGetString(NULL,def->name); + if ((str==NULL)||(strlen(str)<1)) { + ERROR("Section defined without a name\n"); + ACTION("Definition ignored\n"); + return False; + } + si.name= XkbInternAtom(info->dpy,XkbAtomGetString(NULL,def->name),False); + if (!HandleSectionBody(def,&si,merge,info)) + return False; + if (!AddSection(info,&si)) + return False; + return True; +} + +/***====================================================================***/ + +static void +HandleGeometryFile( XkbFile * file, + XkbDescPtr xkb, + unsigned merge, + GeometryInfo * info) +{ +ParseCommon * stmt; +char * failWhat; + + if (merge==MergeDefault) + merge= MergeAugment; + info->name= uStringDup(file->name); + stmt= file->defs; + while (stmt) { + failWhat= NULL; + switch (stmt->stmtType) { + case StmtInclude: + if (!HandleIncludeGeometry((IncludeStmt *)stmt,xkb,info, + HandleGeometryFile)) + info->errorCount++; + break; + case StmtKeyAliasDef: + if (!HandleAliasDef((KeyAliasDef *)stmt, + merge,info->fileID,&info->aliases)) { + info->errorCount++; + } + break; + case StmtVarDef: + if (!HandleGeometryVar((VarDef *)stmt,xkb,info)) + info->errorCount++; + break; + case StmtShapeDef: + if (!HandleShapeDef((ShapeDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + case StmtSectionDef: + if (!HandleSectionDef((SectionDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + case StmtIndicatorMapDef: + case StmtDoodadDef: + if (!HandleDoodadDef((DoodadDef *)stmt,merge,NULL,info)) + info->errorCount++; + break; + case StmtVModDef: + if (!failWhat) failWhat= "virtual modfier"; + case StmtInterpDef: + if (!failWhat) failWhat= "symbol interpretation"; + case StmtGroupCompatDef: + if (!failWhat) failWhat= "group compatibility map"; + case StmtKeycodeDef: + if (!failWhat) failWhat= "key name"; + ERROR("Interpretation files may not include other types\n"); + ACTION1("Ignoring %s definition.\n",failWhat); + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleGeometryFile\n", + stmt->stmtType); + break; + } + stmt= stmt->next; + if (info->errorCount>10) { +#ifdef NOISY + ERROR("Too many errors\n"); +#endif + ACTION1("Abandoning geometry file \"%s\"\n",file->topName); + break; + } + } + return; +} + +/***====================================================================***/ + +static Bool +CopyShapeDef(Display *dpy,XkbGeometryPtr geom,ShapeInfo *si) +{ +register int i,n; +XkbShapePtr shape; +XkbOutlinePtr old_outline,outline; +Atom name; + + si->index= geom->num_shapes; + name= XkbInternAtom(dpy,XkbAtomGetString(NULL,si->name),False); + shape= XkbAddGeomShape(geom,name,si->nOutlines); + if (!shape) { + WSGO("Couldn't allocate shape in geometry\n"); + ACTION1("Shape %s not compiled\n",shText(dpy,si)); + return False; + } + old_outline= si->outlines; + for (i=0;inOutlines;i++,old_outline++) { + outline= XkbAddGeomOutline(shape,old_outline->num_points); + if (!outline) { + WSGO("Couldn't allocate outline in shape\n"); + ACTION1("Shape %s is incomplete\n",shText(dpy,si)); + return False; + } + n= old_outline->num_points; + memcpy(outline->points,old_outline->points,n*sizeof(XkbPointRec)); + outline->num_points= old_outline->num_points; + outline->corner_radius= old_outline->corner_radius; + } + if (si->approx) { + n= (si->approx-si->outlines); + shape->approx= &shape->outlines[n]; + } + if (si->primary) { + n= (si->primary-si->outlines); + shape->primary= &shape->outlines[n]; + } + XkbComputeShapeBounds(shape); + return True; +} + +static Bool +VerifyDoodadInfo(DoodadInfo *di,GeometryInfo *info) +{ + if ((di->defs.defined&(_GD_Top|_GD_Left))!=(_GD_Top|_GD_Left)) { + if (warningLevel<9) { + ERROR1("No position defined for doodad %s\n",ddText(info->dpy,di)); + ACTION("Illegal doodad ignored\n"); + return False; + } + } + if ((di->defs.defined & _GD_Priority) == 0) { + /* calculate priority -- should be just above previous doodad/row */ + } + switch (di->type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + if ((di->defs.defined&_GD_Shape)==0) { + ERROR2("No shape defined for %s doodad %s\n", + (di->type==XkbOutlineDoodad?"outline":"filled"), + ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + else { + ShapeInfo *si; + si= FindShape(info,di->shape, (di->type==XkbOutlineDoodad? + "outline doodad": + "solid doodad"), + ddText(info->dpy,di)); + if (si) + di->shape= si->name; + else { + ERROR1("No legal shape for %s\n",ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + } + if ((di->defs.defined&_GD_Color)==0) { + if (warningLevel>5) { + WARN1("No color for doodad %s\n",ddText(info->dpy,di)); + ACTION("Using black\n"); + } + di->color= XkbInternAtom(NULL,"black",False); + } + break; + case XkbTextDoodad: + if ((di->defs.defined&_GD_Text)==0) { + ERROR1("No text specified for text doodad %s\n", + ddText(info->dpy,di)); + ACTION("Illegal doodad definition ignored\n"); + return False; + } + if ((di->defs.defined&_GD_Angle)==0) + di->angle= 0; + if ((di->defs.defined&_GD_Color)==0) { + if (warningLevel>5) { + WARN1("No color specified for doodad %s\n", + ddText(info->dpy,di)); + ACTION("Using black\n"); + } + di->color= XkbInternAtom(NULL,"black",False); + } + if ((di->defs.defined&_GD_FontSpec)!=0) { + if ((di->defs.defined&_GD_FontParts)==0) + return True; + if (warningLevel<9) { + WARN1("Text doodad %s has full and partial font definition\n", + ddText(info->dpy,di)); + ACTION("Full specification ignored\n"); + } + di->defs.defined&= ~_GD_FontSpec; + di->fontSpec= None; + } + if ((di->defs.defined&_GD_Font)==0) { + if (warningLevel>5) { + WARN1("No font specified for doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using \"%s\"\n",DFLT_FONT); + } + di->font= XkbInternAtom(NULL,DFLT_FONT,False); + } + if ((di->defs.defined&_GD_FontSlant)==0) { + if (warningLevel>7) { + WARN1("No font slant for text doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using \"%s\"\n",DFLT_SLANT); + } + di->fontSlant= XkbInternAtom(NULL,DFLT_SLANT,False); + } + if ((di->defs.defined&_GD_FontWeight)==0) { + if (warningLevel>7) { + WARN1("No font weight for text doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using \"%s\"\n",DFLT_WEIGHT); + } + di->fontWeight= XkbInternAtom(NULL,DFLT_WEIGHT,False); + } + if ((di->defs.defined&_GD_FontSetWidth)==0) { + if (warningLevel>9) { + WARN1("No font set width for text doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using \"%s\"\n",DFLT_SET_WIDTH); + } + di->fontSetWidth= XkbInternAtom(NULL,DFLT_SET_WIDTH,False); + } + if ((di->defs.defined&_GD_FontVariant)==0) { + if (warningLevel>9) { + WARN1("No font variant for text doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using \"%s\"\n",DFLT_VARIANT); + } + di->fontVariant= XkbInternAtom(NULL,DFLT_VARIANT,False); + } + if ((di->defs.defined&_GD_FontEncoding)==0) { + if (warningLevel>7) { + WARN1("No font encoding for doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using \"%s\"\n",DFLT_ENCODING); + } + di->fontEncoding= XkbInternAtom(NULL,DFLT_ENCODING,False); + } + if ((di->defs.defined&_GD_FontSize)==0) { + if (warningLevel>7) { + WARN1("No font size for text doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using %s point text\n", + XkbGeomFPText(DFLT_SIZE,XkbMessage)); + } + di->fontSize= DFLT_SIZE; + } + if ((di->defs.defined&_GD_Height)==0) { + unsigned size,nLines; + char *tmp; + size= (di->fontSize*120)/100; + size= (size*254)/720; /* convert to mm/10 */ + for (nLines=1,tmp=XkbAtomGetString(NULL,di->text);*tmp;tmp++) { + if (*tmp=='\n') nLines++; + } + size*= nLines; + if (warningLevel>5) { + WARN1("No height for text doodad %s\n", + ddText(info->dpy,di)); + ACTION1("Using calculated height %s millimeters\n", + XkbGeomFPText(size,XkbMessage)); + } + di->height= size; + } + if ((di->defs.defined&_GD_Width)==0) { + unsigned width,tmp; + char *str; + width= tmp= 0; + for (str=XkbAtomGetString(NULL,di->text);*str;str++) { + if (*str!='\n') + tmp++; + else { + if (tmp>width) + width= tmp; + tmp= 1; + } + } + if (width==0) + width= tmp; + width*= (di->height*2)/3; + if (warningLevel>5) { + WARN1("No width for text doodad %s\n",ddText(info->dpy,di)); + ACTION1("Using calculated width %s millimeters\n", + XkbGeomFPText(width,XkbMessage)); + } + di->width= width; + } + break; + case XkbIndicatorDoodad: + if ((di->defs.defined&_GD_Shape)==0) { + ERROR1("No shape defined for indicator doodad %s\n", + ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + else { + ShapeInfo *si; + si= FindShape(info,di->shape,"indicator doodad", + ddText(info->dpy,di)); + if (si) + di->shape= si->name; + else { + ERROR1("No legal shape for doodad %s\n", + ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + } + if ((di->defs.defined&_GD_Color)==0) { + if (warningLevel>5) { + WARN1("No \"on\" color for indicator doodad %s\n", + ddText(info->dpy,di)); + ACTION("Using green\n"); + } + di->color= XkbInternAtom(NULL,"green",False); + } + if ((di->defs.defined&_GD_OffColor)==0) { + if (warningLevel>5) { + WARN1("No \"off\" color for indicator doodad %s\n", + ddText(info->dpy,di)); + ACTION("Using black\n"); + } + di->offColor= XkbInternAtom(NULL,"black",False); + } + break; + case XkbLogoDoodad: + if (di->logoName==NULL) { + ERROR1("No logo name defined for logo doodad %s\n", + ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + if ((di->defs.defined&_GD_Shape)==0) { + ERROR1("No shape defined for logo doodad %s\n", + ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + else { + ShapeInfo *si; + si= FindShape(info,di->shape,"logo doodad", + ddText(info->dpy,di)); + if (si) + di->shape= si->name; + else { + ERROR1("No legal shape for %s\n",ddText(info->dpy,di)); + ACTION("Incomplete definition ignored\n"); + return False; + } + } + if ((di->defs.defined&_GD_Color)==0) { + if (warningLevel>5) { + WARN1("No color for doodad %s\n",ddText(info->dpy,di)); + ACTION("Using black\n"); + } + di->color= XkbInternAtom(NULL,"black",False); + } + break; + default: + WSGO1("Uknown doodad type %d in VerifyDoodad\n",(unsigned int)di->type); + return False; + } + return True; +} + +#define FONT_TEMPLATE "-*-%s-%s-%s-%s-%s-*-%d-*-*-*-*-%s" + +static char * +FontFromParts( Atom fontTok, + Atom weightTok, + Atom slantTok, + Atom setWidthTok, + Atom varTok, + int size, + Atom encodingTok) +{ +int totalSize; +char *font,*weight,*slant,*setWidth,*variant,*encoding; +char * rtrn; + + font= (fontTok!=None?XkbAtomGetString(NULL,fontTok):DFLT_FONT); + weight= (weightTok!=None?XkbAtomGetString(NULL,weightTok):DFLT_WEIGHT); + slant= (slantTok!=None?XkbAtomGetString(NULL,slantTok):DFLT_SLANT); + setWidth= (setWidthTok!=None?XkbAtomGetString(NULL,setWidthTok): + DFLT_SET_WIDTH); + variant= (varTok!=None?XkbAtomGetString(NULL,varTok):DFLT_VARIANT); + encoding= (encodingTok!=None?XkbAtomGetString(NULL,encodingTok): + DFLT_ENCODING); + if (size==0) + size= DFLT_SIZE; + totalSize= strlen(FONT_TEMPLATE)+strlen(font)+strlen(weight)+strlen(slant); + totalSize+= strlen(setWidth)+strlen(variant)+strlen(encoding); + rtrn= uCalloc(totalSize,1); + if (rtrn) { + sprintf(rtrn,FONT_TEMPLATE,font,weight,slant,setWidth,variant, + size,encoding); + } + return rtrn; +} + +static Bool +CopyDoodadDef( XkbGeometryPtr geom, + XkbSectionPtr section, + DoodadInfo * di, + GeometryInfo * info) +{ +Atom name; +XkbDoodadPtr doodad; +XkbColorPtr color; +XkbShapePtr shape; +ShapeInfo * si; + + if (!VerifyDoodadInfo(di,info)) + return False; + name= XkbInternAtom(NULL,XkbAtomGetString(NULL,di->name),False); + doodad= XkbAddGeomDoodad(geom,section,name); + if (!doodad) { + WSGO1("Couldn't allocate doodad in %s\n", + (section?"section":"geometry")); + ACTION1("Cannot copy doodad %s\n",ddText(info->dpy,di)); + return False; + } + doodad->any.type= di->type; + doodad->any.priority= di->priority; + doodad->any.top= di->top; + doodad->any.left= di->left; + switch (di->type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + si= FindShape(info,di->shape,NULL,NULL); + if (!si) + return False; + doodad->shape.angle= di->angle; + color= XkbAddGeomColor(geom,XkbAtomGetString(NULL,di->color),geom->num_colors); + shape= &geom->shapes[si->index]; + XkbSetShapeDoodadColor(geom,&doodad->shape,color); + XkbSetShapeDoodadShape(geom,&doodad->shape,shape); + break; + case XkbTextDoodad: + doodad->text.angle= di->angle; + doodad->text.width= di->width; + doodad->text.height= di->height; + if (di->fontSpec==None) + doodad->text.font= FontFromParts(di->font,di->fontWeight, + di->fontSlant,di->fontSetWidth, + di->fontVariant, + di->fontSize,di->fontEncoding); + else doodad->text.font= XkbAtomGetString(NULL,di->fontSpec); + doodad->text.text= XkbAtomGetString(NULL,di->text); + color= XkbAddGeomColor(geom,XkbAtomGetString(NULL,di->color),geom->num_colors); + XkbSetTextDoodadColor(geom,&doodad->text,color); + break; + case XkbIndicatorDoodad: + si= FindShape(info,di->shape,NULL,NULL); + if (!si) + return False; + shape= &geom->shapes[si->index]; + color= XkbAddGeomColor(geom,XkbAtomGetString(NULL,di->color),geom->num_colors); + XkbSetIndicatorDoodadShape(geom,&doodad->indicator,shape); + XkbSetIndicatorDoodadOnColor(geom,&doodad->indicator,color); + color= XkbAddGeomColor(geom,XkbAtomGetString(NULL,di->offColor),geom->num_colors); + XkbSetIndicatorDoodadOffColor(geom,&doodad->indicator,color); + break; + case XkbLogoDoodad: + si= FindShape(info,di->shape,NULL,NULL); + if (!si) + return False; + doodad->logo.angle= di->angle; + color= XkbAddGeomColor(geom,XkbAtomGetString(NULL,di->color),geom->num_colors); + shape= &geom->shapes[si->index]; + XkbSetLogoDoodadColor(geom,&doodad->logo,color); + XkbSetLogoDoodadShape(geom,&doodad->logo,shape); + doodad->logo.logo_name= di->logoName; + di->logoName= NULL; + break; + } + return True; +} + +/***====================================================================***/ + +static Bool +VerifyOverlayInfo( XkbGeometryPtr geom, + XkbSectionPtr section, + OverlayInfo * oi, + GeometryInfo * info, + short rowMap[256], + short rowSize[256]) +{ +register OverlayKeyInfo * ki,*next; +unsigned long oKey,uKey,sKey; +XkbRowPtr row; +XkbKeyPtr key; +int r,k; + + /* find out which row each key is in */ + for (ki=oi->keys;ki!=NULL;ki=(OverlayKeyInfo *)ki->defs.next) { + oKey= KeyNameToLong(ki->over); + uKey= KeyNameToLong(ki->under); + for (r=0,row=section->rows;(rnum_rows)&&oKey;r++,row++) { + for (k=0,key=row->keys;(knum_keys)&&oKey;k++,key++) { + sKey= KeyNameToLong(key->name.name); + if (sKey==oKey) { + if (warningLevel>0) { + WARN3("Key %s in section \"%s\" and overlay \"%s\"\n", + XkbKeyNameText(key->name.name,XkbMessage), + XkbAtomText(info->dpy,section->name,XkbMessage), + XkbAtomText(info->dpy,oi->name,XkbMessage)); + ACTION("Overlay definition ignored\n"); + } + oKey= 0; + } + else if (sKey==uKey) { + ki->sectionRow= r; + oKey= 0; + } + } + } + if ((ki->sectionRow==_GOK_UnknownRow)&&(warningLevel>0)) { + WARN3("Key %s not in \"%s\", but has an overlay key in \"%s\"\n", + XkbKeyNameText(ki->under,XkbMessage), + XkbAtomText(info->dpy,section->name,XkbMessage), + XkbAtomText(info->dpy,oi->name,XkbMessage)); + ACTION("Definition ignored\n"); + } + } + /* now prune out keys that aren't in the section */ + while ((oi->keys!=NULL)&&(oi->keys->sectionRow==_GOK_UnknownRow)) { + next= (OverlayKeyInfo *)oi->keys->defs.next; + uFree(oi->keys); + oi->keys= next; + oi->nKeys--; + } + for (ki=oi->keys;(ki!=NULL)&&(ki->defs.next!=NULL);ki=next) { + next= (OverlayKeyInfo *)ki->defs.next; + if (next->sectionRow==_GOK_UnknownRow) { + ki->defs.next= next->defs.next; + oi->nKeys--; + uFree(next); + next= (OverlayKeyInfo *)ki->defs.next; + } + } + if (oi->nKeys<1) { + ERROR2("Overlay \"%s\" for section \"%s\" has no legal keys\n", + XkbAtomText(info->dpy,oi->name,XkbMessage), + XkbAtomText(info->dpy,section->name,XkbMessage)); + ACTION("Overlay definition ignored\n"); + return False; + } + /* now figure out how many rows are defined for the overlay */ + bzero(rowSize,sizeof(short)*256); + for (k=0;k<256;k++) { + rowMap[k]= -1; + } + oi->nRows= 0; + for (ki=oi->keys;ki!=NULL;ki=(OverlayKeyInfo *)ki->defs.next) { + if (rowMap[ki->sectionRow]==-1) + rowMap[ki->sectionRow]= oi->nRows++; + ki->overlayRow= rowMap[ki->sectionRow]; + rowSize[ki->overlayRow]++; + } + return True; +} + +static Bool +CopyOverlayDef( XkbGeometryPtr geom, + XkbSectionPtr section, + OverlayInfo * oi, + GeometryInfo * info) +{ +Atom name; +XkbOverlayPtr ol; +XkbOverlayRowPtr row; +XkbOverlayKeyPtr key; +OverlayKeyInfo * ki; +short rowMap[256],rowSize[256]; +int i; + + if (!VerifyOverlayInfo(geom,section,oi,info,rowMap,rowSize)) + return False; + name= XkbInternAtom(NULL,XkbAtomGetString(NULL,oi->name),False); + ol= XkbAddGeomOverlay(section,name,oi->nRows); + if (!ol) { + WSGO2("Couldn't add overlay \"%s\" to section \"%s\"\n", + XkbAtomText(info->dpy,name,XkbMessage), + XkbAtomText(info->dpy,section->name,XkbMessage)); + return False; + } + for (i=0;inRows;i++) { + int tmp,row_under; + for (tmp=0,row_under=-1;(tmpnum_rows)&&(row_under<0);tmp++) { + if (rowMap[tmp]==i) + row_under= tmp; + } + if (!XkbAddGeomOverlayRow(ol,row_under,rowSize[i])) { + WSGO3("Can't add row %d to overlay \"%s\" of section \"%s\"\n", + i,XkbAtomText(info->dpy,name,XkbMessage), + XkbAtomText(info->dpy,section->name,XkbMessage)); + return False; + } + } + for (ki=oi->keys;ki!=NULL;ki=(OverlayKeyInfo *)ki->defs.next) { + row= &ol->rows[ki->overlayRow]; + key= &row->keys[row->num_keys++]; + bzero(key,sizeof(XkbOverlayKeyRec)); + strncpy(key->over.name,ki->over,XkbKeyNameLength); + strncpy(key->under.name,ki->under,XkbKeyNameLength); + } + return True; +} + +/***====================================================================***/ + +static Bool +CopySectionDef(XkbGeometryPtr geom,SectionInfo *si,GeometryInfo *info) +{ +XkbSectionPtr section; +XkbRowPtr row; +XkbKeyPtr key; +KeyInfo * ki; +RowInfo * ri; +Atom name; + + name= XkbInternAtom(NULL,XkbAtomGetString(NULL,si->name),False); + section= XkbAddGeomSection(geom,name,si->nRows,si->nDoodads,si->nOverlays); + if (section==NULL) { + WSGO("Couldn't allocate section in geometry\n"); + ACTION1("Section %s not compiled\n",scText(info->dpy,si)); + return False; + } + section->top= si->top; + section->left= si->left; + section->width= si->width; + section->height= si->height; + section->angle= si->angle; + section->priority= si->priority; + for (ri=si->rows;ri!=NULL;ri=(RowInfo *)ri->defs.next) { + row= XkbAddGeomRow(section,ri->nKeys); + if (row==NULL) { + WSGO("Couldn't allocate row in section\n"); + ACTION1("Section %s is incomplete\n",scText(info->dpy,si)); + return False; + } + row->top= ri->top; + row->left= ri->left; + row->vertical= ri->vertical; + for (ki=ri->keys;ki!=NULL;ki=(KeyInfo *)ki->defs.next) { + XkbColorPtr color; + if ((ki->defs.defined&_GK_Name)==0) { + ERROR3("Key %d of row %d in section %s has no name\n", + (int)ki->index,(int)ri->index, + scText(info->dpy,si)); + ACTION1("Section %s ignored\n",scText(info->dpy,si)); + return False; + } + key= XkbAddGeomKey(row); + if (key==NULL) { + WSGO("Couldn't allocate key in row\n"); + ACTION1("Section %s is incomplete\n",scText(info->dpy,si)); + return False; + } + memcpy(key->name.name,ki->name,XkbKeyNameLength); + key->gap= ki->gap; + if (ki->shape==None) + key->shape_ndx= 0; + else { + ShapeInfo *si; + si= FindShape(info,ki->shape,"key",keyText(ki)); + if (!si) + return False; + key->shape_ndx= si->index; + } + if (ki->color!=None) + color= XkbAddGeomColor(geom,XkbAtomGetString(NULL,ki->color),geom->num_colors); + else color= XkbAddGeomColor(geom,"white",geom->num_colors); + XkbSetKeyColor(geom,key,color); + } + } + if (si->doodads!=NULL) { + DoodadInfo *di; + for (di=si->doodads;di!=NULL;di=(DoodadInfo *)di->defs.next) { + CopyDoodadDef(geom,section,di,info); + } + } + if (si->overlays!=NULL) { + OverlayInfo *oi; + for (oi=si->overlays;oi!=NULL;oi=(OverlayInfo *)oi->defs.next) { + CopyOverlayDef(geom,section,oi,info); + } + } + if (XkbComputeSectionBounds(geom,section)) { + /* 7/6/94 (ef) -- check for negative origin and translate */ + if ((si->defs.defined&_GS_Width)==0) + section->width= section->bounds.x2; + if ((si->defs.defined&_GS_Height)==0) + section->height= section->bounds.y2; + } + return True; +} + +/***====================================================================***/ + +Bool +CompileGeometry(XkbFile *file,XkbFileInfo *result,unsigned merge) +{ +GeometryInfo info; +XkbDescPtr xkb; + + xkb= result->xkb; + InitGeometryInfo(&info,file->id,merge); + info.dpy= xkb->dpy; + HandleGeometryFile(file,xkb,merge,&info); + + if (info.errorCount==0) { + XkbGeometryPtr geom; + XkbGeometrySizesRec sizes; + bzero(&sizes,sizeof(sizes)); + sizes.which= XkbGeomAllMask; + sizes.num_properties= info.nProps; + sizes.num_colors= 8; + sizes.num_shapes= info.nShapes; + sizes.num_sections= info.nSections; + sizes.num_doodads= info.nDoodads; + if (XkbAllocGeometry(xkb,&sizes)!=Success) { + WSGO("Couldn't allocate GeometryRec\n"); + ACTION("Geometry not compiled\n"); + return False; + } + geom= xkb->geom; + + geom->width_mm= info.widthMM; + geom->height_mm= info.heightMM; + if (info.name!=NULL) { + geom->name= XkbInternAtom(xkb->dpy,info.name,False); + if (XkbAllocNames(xkb,XkbGeometryNameMask,0,0)==Success) + xkb->names->geometry= geom->name; + } + if (info.fontSpec!=None) + geom->label_font= uStringDup(XkbAtomGetString(NULL,info.fontSpec)); + else geom->label_font= FontFromParts(info.font,info.fontWeight, + info.fontSlant,info.fontSetWidth, + info.fontVariant, + info.fontSize,info.fontEncoding); + XkbAddGeomColor(geom,"black",geom->num_colors); + XkbAddGeomColor(geom,"white",geom->num_colors); + + if (info.baseColor==None) + info.baseColor= XkbInternAtom(NULL,"white",False); + if (info.labelColor==None) + info.labelColor= XkbInternAtom(NULL,"black",False); + geom->base_color= + XkbAddGeomColor(geom,XkbAtomGetString(NULL,info.baseColor),geom->num_colors); + geom->label_color= + XkbAddGeomColor(geom,XkbAtomGetString(NULL,info.labelColor),geom->num_colors); + + if (info.props) { + PropertyInfo *pi; + for (pi= info.props;pi!=NULL;pi=(PropertyInfo *)pi->defs.next) { + if (!XkbAddGeomProperty(geom,pi->name,pi->value)) + return False; + } + } + if (info.shapes) { + ShapeInfo *si; + for (si= info.shapes;si!=NULL;si=(ShapeInfo *)si->defs.next) { + if (!CopyShapeDef(xkb->dpy,geom,si)) + return False; + } + } + if (info.sections) { + SectionInfo *si; + for (si= info.sections;si!=NULL;si=(SectionInfo *)si->defs.next) { + if (!CopySectionDef(geom,si,&info)) + return False; + } + } + if (info.doodads) { + DoodadInfo *di; + for (di= info.doodads;di!=NULL;di=(DoodadInfo *)di->defs.next) { + if (!CopyDoodadDef(geom,NULL,di,&info)) + return False; + } + } + if (info.aliases) + ApplyAliases(xkb,True,&info.aliases); + ClearGeometryInfo(&info); + return True; + } + return False; +} diff --git a/xkbcomp/indicators.c b/xkbcomp/indicators.c new file mode 100644 index 0000000..3061f3e --- /dev/null +++ b/xkbcomp/indicators.c @@ -0,0 +1,485 @@ +/* $Xorg: indicators.c,v 1.3 2000/08/17 19:54:31 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/indicators.c,v 1.4 2001/01/17 23:45:43 dawes Exp $ */ + +#include "xkbcomp.h" +#include "misc.h" +#include "tokens.h" +#include "expr.h" +#include "vmod.h" +#include "indicators.h" +#include "action.h" +#include "compat.h" + +/***====================================================================***/ + +#define ReportIndicatorBadType(d,l,f,w) \ + ReportBadType("indicator map",(f),\ + XkbAtomText((d),(l)->name,XkbMessage),(w)) +#define ReportIndicatorNotArray(d,l,f) \ + ReportNotArray("indicator map",(f),\ + XkbAtomText((d),(l)->name,XkbMessage)) + +/***====================================================================***/ + +void +ClearIndicatorMapInfo(Display *dpy,LEDInfo *info) +{ + info->name= XkbInternAtom(dpy,"default",False); + info->indicator= _LED_NotBound; + info->flags= info->which_mods= info->real_mods= 0; + info->vmods= 0; + info->which_groups= info->groups= 0; + info->ctrls= 0; + return; +} + +LEDInfo * +AddIndicatorMap(LEDInfo *oldLEDs,LEDInfo *new) +{ +LEDInfo *old,*last; +unsigned collide; + + last= NULL; + for (old=oldLEDs;old!=NULL;old=(LEDInfo *)old->defs.next) { + if (old->name==new->name) { + if ((old->real_mods==new->real_mods)&& + (old->vmods==new->vmods)&& + (old->groups==new->groups)&& + (old->ctrls==new->ctrls)&& + (old->which_mods==new->which_mods)&& + (old->which_groups==new->which_groups)) { + old->defs.defined|= new->defs.defined; + return oldLEDs; + } + if (new->defs.merge==MergeReplace) { + CommonInfo *next= old->defs.next; + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Map for indicator %s redefined\n", + XkbAtomText(NULL,old->name,XkbMessage)); + ACTION("Earlier definition ignored\n"); + } + *old= *new; + old->defs.next= next; + return oldLEDs; + } + collide= 0; + if (UseNewField(_LED_Index,&old->defs,&new->defs,&collide)) { + old->indicator= new->indicator; + old->defs.defined|= _LED_Index; + } + if (UseNewField(_LED_Mods,&old->defs,&new->defs,&collide)) { + old->which_mods= new->which_mods; + old->real_mods= new->real_mods; + old->vmods= new->vmods; + old->defs.defined|= _LED_Mods; + } + if (UseNewField(_LED_Groups,&old->defs,&new->defs,&collide)) { + old->which_groups= new->which_groups; + old->groups= new->groups; + old->defs.defined|= _LED_Groups; + } + if (UseNewField(_LED_Ctrls,&old->defs,&new->defs,&collide)) { + old->ctrls= new->ctrls; + old->defs.defined|= _LED_Ctrls; + } + if (UseNewField(_LED_Explicit,&old->defs,&new->defs,&collide)) { + old->flags&= ~XkbIM_NoExplicit; + old->flags|= (new->flags&XkbIM_NoExplicit); + old->defs.defined|= _LED_Explicit; + } + if (UseNewField(_LED_Automatic,&old->defs,&new->defs,&collide)) { + old->flags&= ~XkbIM_NoAutomatic; + old->flags|= (new->flags&XkbIM_NoAutomatic); + old->defs.defined|= _LED_Automatic; + } + if (UseNewField(_LED_DrivesKbd,&old->defs,&new->defs,&collide)) { + old->flags&= ~XkbIM_LEDDrivesKB; + old->flags|= (new->flags&XkbIM_LEDDrivesKB); + old->defs.defined|= _LED_DrivesKbd; + } + if (collide) { + WARN1("Map for indicator %s redefined\n", + XkbAtomText(NULL,old->name,XkbMessage)); + ACTION1("Using %s definition for duplicate fields\n", + (new->defs.merge==MergeAugment?"first":"last")); + } + return oldLEDs; + } + if (old->defs.next==NULL) + last= old; + } + /* new definition */ + old= uTypedAlloc(LEDInfo); + if (!old) { + WSGO("Couldn't allocate indicator map\n"); + ACTION1("Map for indicator %s not compiled\n", + XkbAtomText(NULL,new->name,XkbMessage)); + return False; + } + *old= *new; + old->defs.next= NULL; + if (last) { + last->defs.next= &old->defs; + return oldLEDs; + } + return old; +} + +LookupEntry modComponentNames[] = { + { "base", XkbIM_UseBase }, + { "latched", XkbIM_UseLatched }, + { "locked", XkbIM_UseLocked }, + { "effective", XkbIM_UseEffective }, + { "compat", XkbIM_UseCompat }, + { "any", XkbIM_UseAnyMods }, + { "none", 0 }, + { NULL, 0 } +}; +LookupEntry groupComponentNames[] = { + { "base", XkbIM_UseBase }, + { "latched", XkbIM_UseLatched }, + { "locked", XkbIM_UseLocked }, + { "effective", XkbIM_UseEffective }, + { "any", XkbIM_UseAnyGroup }, + { "none", 0 }, + { NULL, 0 } +}; + +int +SetIndicatorMapField( LEDInfo * led, + XkbDescPtr xkb, + char * field, + ExprDef * arrayNdx, + ExprDef * value) +{ +ExprResult rtrn; +Bool ok; + + ok= True; + if ((uStrCaseCmp(field,"modifiers")==0)||(uStrCaseCmp(field,"mods")==0)) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveModMask(value,&rtrn,LookupVModMask,(XPointer)xkb)) + return ReportIndicatorBadType(xkb->dpy,led,field,"modifier mask"); + led->real_mods= rtrn.uval&0xff; + led->vmods= (rtrn.uval>>8)&0xff; + led->defs.defined|= _LED_Mods; + } + else if (uStrCaseCmp(field,"groups")==0) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)groupNames)) + return ReportIndicatorBadType(xkb->dpy,led,field,"group mask"); + led->groups= rtrn.uval; + led->defs.defined|= _LED_Groups; + } + else if ((uStrCaseCmp(field,"controls")==0)|| + (uStrCaseCmp(field,"ctrls")==0)) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup,(XPointer)ctrlNames)) + return ReportIndicatorBadType(xkb->dpy,led,field,"controls mask"); + led->ctrls= rtrn.uval; + led->defs.defined|= _LED_Ctrls; + } + else if (uStrCaseCmp(field,"allowexplicit")==0) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) + return ReportIndicatorBadType(xkb->dpy,led,field,"boolean"); + if (rtrn.uval) led->flags&= ~XkbIM_NoExplicit; + else led->flags|= XkbIM_NoExplicit; + led->defs.defined|= _LED_Explicit; + } + else if ((uStrCaseCmp(field,"whichmodstate")==0)|| + (uStrCaseCmp(field,"whichmodifierstate")==0)) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup, + (XPointer)modComponentNames)) { + return ReportIndicatorBadType(xkb->dpy,led,field, + "mask of modifier state components"); + } + led->which_mods= rtrn.uval; + } + else if (uStrCaseCmp(field,"whichgroupstate")==0) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveMask(value,&rtrn,SimpleLookup, + (XPointer)groupComponentNames)){ + return ReportIndicatorBadType(xkb->dpy,led,field, + "mask of group state components"); + } + led->which_groups= rtrn.uval; + } + else if ((uStrCaseCmp(field,"driveskbd")==0)|| + (uStrCaseCmp(field,"driveskeyboard")==0)|| + (uStrCaseCmp(field,"leddriveskbd")==0)|| + (uStrCaseCmp(field,"leddriveskeyboard")==0)|| + (uStrCaseCmp(field,"indicatordriveskbd")==0)|| + (uStrCaseCmp(field,"indicatordriveskeyboard")==0)) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveBoolean(value,&rtrn,NULL,NULL)) + return ReportIndicatorBadType(xkb->dpy,led,field,"boolean"); + if (rtrn.uval) led->flags|= XkbIM_LEDDrivesKB; + else led->flags&= ~XkbIM_LEDDrivesKB; + led->defs.defined|= _LED_DrivesKbd; + } + else if (uStrCaseCmp(field,"index")==0) { + if (arrayNdx!=NULL) + return ReportIndicatorNotArray(xkb->dpy,led,field); + if (!ExprResolveInteger(value,&rtrn,NULL,NULL)) + return ReportIndicatorBadType(xkb->dpy,led,field,"indicator index"); + if ((rtrn.uval<1)||(rtrn.uval>32)) { + ERROR2("Illegal indicator index %d (range 1..%d)\n",rtrn.uval, + XkbNumIndicators); + ACTION1("Index definition for %s indicator ignored\n", + XkbAtomText(NULL,led->name,XkbMessage)); + return False; + } + led->indicator= rtrn.uval; + led->defs.defined|= _LED_Index; + } + else { + ERROR2("Unknown field %s in map for %s indicator\n",field, + XkbAtomText(NULL,led->name,XkbMessage)); + ACTION("Definition ignored\n"); + ok= False; + } + return ok; +} + +LEDInfo * +HandleIndicatorMapDef( IndicatorMapDef * def, + XkbDescPtr xkb, + LEDInfo * dflt, + LEDInfo * oldLEDs, + unsigned merge) +{ +LEDInfo led,*rtrn; +VarDef * var; +Bool ok; + + if (def->merge!=MergeDefault) + merge= def->merge; + + led= *dflt; + led.defs.merge= merge; + led.name= def->name; + + ok= True; + for (var= def->body;var!=NULL;var= (VarDef *)var->common.next) { + ExprResult elem,field; + ExprDef * arrayNdx; + if (!ExprResolveLhs(var->name,&elem,&field,&arrayNdx)) { + ok= False; + continue; + } + if (elem.str!=NULL) { + ERROR1("Cannot set defaults for \"%s\" element in indicator map\n", + elem.str); + ACTION2("Assignment to %s.%s ignored\n",elem.str,field.str); + ok= False; + } + else { + ok=SetIndicatorMapField(&led,xkb,field.str,arrayNdx,var->value)&&ok; + } + } + if (ok) { + rtrn= AddIndicatorMap(oldLEDs,&led); + return rtrn; + } + return NULL; +} + +Bool +CopyIndicatorMapDefs(XkbFileInfo *result,LEDInfo *leds,LEDInfo **unboundRtrn) +{ +LEDInfo * led,*next; +LEDInfo * unbound,*last; +XkbDescPtr xkb; + + xkb= result->xkb; + if (XkbAllocNames(xkb,XkbIndicatorNamesMask,0,0)!=Success) { + WSGO("Couldn't allocate names\n"); + ACTION("Indicator names may be incorrect\n"); + } + if (XkbAllocIndicatorMaps(xkb)!=Success) { + WSGO("Can't allocate indicator maps\n"); + ACTION("Indicator map definitions may be lost\n"); + return False; + } + last= unbound= (unboundRtrn?*unboundRtrn:NULL); + while ((last!=NULL) && (last->defs.next!=NULL)) { + last= (LEDInfo *)last->defs.next; + } + for (led=leds;led!=NULL;led=next) { + next= (LEDInfo *)led->defs.next; + if ((led->groups!=0)&&(led->which_groups==0)) + led->which_groups= XkbIM_UseEffective; + if ((led->which_mods==0)&&((led->real_mods)||(led->vmods))) + led->which_mods= XkbIM_UseEffective; + if ((led->indicator==_LED_NotBound)||(!xkb->indicators)) { + if (unboundRtrn!=NULL) { + led->defs.next= NULL; + if (last!=NULL) last->defs.next= (CommonInfo *)led; + else unbound= led; + last= led; + } + else uFree(led); + } + else { + register XkbIndicatorMapPtr im; + im= &xkb->indicators->maps[led->indicator-1]; + im->flags= led->flags; + im->which_groups= led->which_groups; + im->groups= led->groups; + im->which_mods= led->which_mods; + im->mods.mask= led->real_mods; + im->mods.real_mods= led->real_mods; + im->mods.vmods= led->vmods; + im->ctrls= led->ctrls; + if (xkb->names!=NULL) + xkb->names->indicators[led->indicator-1]= led->name; + uFree(led); + } + } + if (unboundRtrn!=NULL) { + *unboundRtrn= unbound; + } + return True; +} + +Bool +BindIndicators( XkbFileInfo * result, + Bool force, + LEDInfo * unbound, + LEDInfo ** unboundRtrn) +{ +XkbDescPtr xkb; +register int i; +register LEDInfo *led,*next,*last; + + xkb= result->xkb; + if (xkb->names!=NULL) { + for (led=unbound;led!=NULL;led= (LEDInfo *)led->defs.next) { + if (led->indicator==_LED_NotBound) { + for (i=0;inames->indicators[i]==led->name) { + led->indicator= i+1; + break; + } + } + } + } + if (force) { + for (led=unbound;led!=NULL;led= (LEDInfo *)led->defs.next) { + if (led->indicator==_LED_NotBound) { + for (i=0;inames->indicators[i]==None) { + xkb->names->indicators[i]= led->name; + led->indicator= i+1; + xkb->indicators->phys_indicators&= ~(1<indicator==_LED_NotBound) { + ERROR("No unnamed indicators found\n"); + ACTION1("Virtual indicator map \"%s\" not bound\n", + XkbAtomGetString(xkb->dpy,led->name)); + continue; + } + } + } + } + } + for (last=NULL,led=unbound;led!=NULL;led= next) { + next= (LEDInfo *)led->defs.next; + if (led->indicator==_LED_NotBound) { + if (force) { + unbound= next; + uFree(led); + } + else { + if (last) + last->defs.next= &led->defs; + else unbound= led; + last= led; + } + } + else { + if ((xkb->names!=NULL)&& + (xkb->names->indicators[led->indicator-1]!=led->name)) { + Atom old= xkb->names->indicators[led->indicator-1]; + ERROR1("Multiple names bound to indicator %d\n",(unsigned int)led->indicator); + ACTION2("Using %s, ignoring %s\n", + XkbAtomGetString(xkb->dpy,old), + XkbAtomGetString(xkb->dpy,led->name)); + led->indicator= _LED_NotBound; + if (force) { + uFree(led); + unbound= next; + } + else { + if (last) + last->defs.next= &led->defs; + else unbound= led; + last= led; + } + } + else { + XkbIndicatorMapPtr map; + map= &xkb->indicators->maps[led->indicator-1]; + map->flags= led->flags; + map->which_groups= led->which_groups; + map->groups= led->groups; + map->which_mods= led->which_mods; + map->mods.mask= led->real_mods; + map->mods.real_mods= led->real_mods; + map->mods.vmods= led->vmods; + map->ctrls= led->ctrls; + if (last) last->defs.next= &next->defs; + else unbound= next; + led->defs.next= NULL; + uFree(led); + } + } + } + if (unboundRtrn) { + *unboundRtrn= unbound; + } + else if (unbound) { + for (led=unbound;led!=NULL;led=next) { + next= (LEDInfo *)led->defs.next; + uFree(led); + } + } + return True; +} diff --git a/xkbcomp/indicators.h b/xkbcomp/indicators.h new file mode 100644 index 0000000..041cacc --- /dev/null +++ b/xkbcomp/indicators.h @@ -0,0 +1,95 @@ +/* $Xorg: indicators.h,v 1.3 2000/08/17 19:54:32 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef INDICATORS_H +#define INDICATORS_H 1 + +#define _LED_Index (1<<0) +#define _LED_Mods (1<<1) +#define _LED_Groups (1<<2) +#define _LED_Ctrls (1<<3) +#define _LED_Explicit (1<<4) +#define _LED_Automatic (1<<5) +#define _LED_DrivesKbd (1<<6) + +#define _LED_NotBound 255 + +typedef struct _LEDInfo { + CommonInfo defs; + Atom name; + unsigned char indicator; + unsigned char flags; + unsigned char which_mods; + unsigned char real_mods; + unsigned short vmods; + unsigned char which_groups; + unsigned char groups; + unsigned int ctrls; +} LEDInfo; + +extern void ClearIndicatorMapInfo( + Display * /* dpy */, + LEDInfo * /* info */ +); + + +extern LEDInfo *AddIndicatorMap( + LEDInfo * /* oldLEDs */, + LEDInfo * /* newLED */ +); + +extern int SetIndicatorMapField( + LEDInfo * /* led */, + XkbDescPtr /* xkb */, + char * /* field */, + ExprDef * /* arrayNdx */, + ExprDef * /* value */ +); + +extern LEDInfo *HandleIndicatorMapDef( + IndicatorMapDef * /* stmt */, + XkbDescPtr /* xkb */, + LEDInfo * /* dflt */, + LEDInfo * /* oldLEDs */, + unsigned /* mergeMode */ +); + +extern Bool CopyIndicatorMapDefs( + XkbFileInfo * /* result */, + LEDInfo * /* leds */, + LEDInfo ** /* unboundRtrn */ +); + +extern Bool BindIndicators( + XkbFileInfo * /* result */, + Bool /* force */, + LEDInfo * /* unbound */, + LEDInfo ** /* unboundRtrn */ +); + +#endif /* INDICATORS_H */ diff --git a/xkbcomp/keycodes.c b/xkbcomp/keycodes.c new file mode 100644 index 0000000..6b2fdd8 --- /dev/null +++ b/xkbcomp/keycodes.c @@ -0,0 +1,749 @@ +/* $Xorg: keycodes.c,v 1.4 2000/08/17 19:54:32 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "keycodes.h" +#include "misc.h" +#include "alias.h" + +char * +longText(unsigned long val,unsigned format) +{ +char buf[4]; + + LongToKeyName(val,buf); + return XkbKeyNameText(buf,format); +} + +/***====================================================================***/ + +void +LongToKeyName(unsigned long val,char *name) +{ + name[0]= ((val>>24)&0xff); + name[1]= ((val>>16)&0xff); + name[2]= ((val>>8)&0xff); + name[3]= (val&0xff); + return; +} + +/***====================================================================***/ + +typedef struct _IndicatorNameInfo { + CommonInfo defs; + int ndx; + Atom name; + Bool virtual; +} IndicatorNameInfo; + +typedef struct _KeyNamesInfo { + char * name; + int errorCount; + unsigned fileID; + unsigned merge; + int computedMin; + int computedMax; + int explicitMin; + int explicitMax; + int effectiveMin; + int effectiveMax; + unsigned long names[XkbMaxLegalKeyCode+1]; + unsigned files[XkbMaxLegalKeyCode+1]; + unsigned char has_alt_forms[XkbMaxLegalKeyCode+1]; + IndicatorNameInfo * leds; + AliasInfo * aliases; +} KeyNamesInfo; + +static void +InitIndicatorNameInfo(IndicatorNameInfo *ii,KeyNamesInfo *info) +{ + ii->defs.defined= 0; + ii->defs.merge= info->merge; + ii->defs.fileID= info->fileID; + ii->defs.next= NULL; + ii->ndx= 0; + ii->name= None; + ii->virtual= False; + return; +} + +static void +ClearIndicatorNameInfo(IndicatorNameInfo *ii,KeyNamesInfo *info) +{ + if (ii==info->leds) { + ClearCommonInfo(&ii->defs); + info->leds= NULL; + } + return; +} + +static IndicatorNameInfo * +NextIndicatorName(KeyNamesInfo *info) +{ +IndicatorNameInfo * ii; + + ii= uTypedAlloc(IndicatorNameInfo); + if (ii) { + InitIndicatorNameInfo(ii,info); + info->leds= (IndicatorNameInfo *)AddCommonInfo(&info->leds->defs, + (CommonInfo *)ii); + } + return ii; +} + +static IndicatorNameInfo * +FindIndicatorByIndex(KeyNamesInfo *info,int ndx) +{ +IndicatorNameInfo * old; + + for (old= info->leds;old!=NULL;old=(IndicatorNameInfo *)old->defs.next) { + if (old->ndx==ndx) + return old; + } + return NULL; +} + +static IndicatorNameInfo * +FindIndicatorByName(KeyNamesInfo *info,Atom name) +{ +IndicatorNameInfo * old; + + for (old= info->leds;old!=NULL;old=(IndicatorNameInfo *)old->defs.next) { + if (old->name==name) + return old; + } + return NULL; +} + +static Bool +AddIndicatorName(KeyNamesInfo *info,IndicatorNameInfo *new) +{ +IndicatorNameInfo *old; +Bool replace; +char * action; + + replace= (new->defs.merge==MergeReplace)|| + (new->defs.merge==MergeOverride); + old= FindIndicatorByName(info,new->name); + if (old) { + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple indicators named %s\n", + XkbAtomText(NULL,new->name,XkbMessage)); + if (old->ndx==new->ndx) { + if (old->virtual!=new->virtual) { + if (replace) + old->virtual= new->virtual; + action= "Using %s instead of %s\n"; + } + else { + action= "Identical definitions ignored\n"; + } + ACTION2(action,(old->virtual?"virtual":"real"), + (old->virtual?"real":"virtual")); + return True; + } + else { + if (replace) action= "Ignoring %d, using %d\n"; + else action= "Using %d, ignoring %d\n"; + ACTION2(action,old->ndx,new->ndx); + } + if (replace) { + if (info->leds==old) + info->leds= (IndicatorNameInfo *)old->defs.next; + else { + IndicatorNameInfo *tmp; + tmp= info->leds; + for (;tmp!=NULL;tmp=(IndicatorNameInfo *)tmp->defs.next) { + if (tmp->defs.next==(CommonInfo *)old) { + tmp->defs.next= old->defs.next; + break; + } + } + } + uFree(old); + } + } + } + old= FindIndicatorByIndex(info,new->ndx); + if (old) { + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple names for indicator %d\n",new->ndx); + if ((old->name==new->name)&&(old->virtual==new->virtual)) + action= "Identical definitions ignored\n"; + else { + char *oldType,*newType; + Atom using,ignoring; + if (old->virtual) oldType= "virtual indicator"; + else oldType= "real indicator"; + if (new->virtual) newType= "virtual indicator"; + else newType= "real indicator"; + if (replace) { + using= new->name; + ignoring= old->name; + } + else { + using= old->name; + ignoring= new->name; + } + ACTION4("Using %s %s, ignoring %s %s\n", + oldType,XkbAtomText(NULL,using,XkbMessage), + newType,XkbAtomText(NULL,ignoring,XkbMessage)); + } + } + if (replace) { + old->name= new->name; + old->virtual= new->virtual; + } + return True; + } + old= new; + new= NextIndicatorName(info); + if (!new) { + WSGO1("Couldn't allocate name for indicator %d\n",new->ndx); + ACTION("Ignored\n"); + return False; + } + new->name= old->name; + new->ndx= old->ndx; + new->virtual= old->virtual; + return True; +} + +static void +ClearKeyNamesInfo(KeyNamesInfo *info) +{ + if (info->name!=NULL) + uFree(info->name); + info->name= NULL; + info->computedMax= info->explicitMax= info->explicitMin= -1; + info->computedMin= 256; + info->effectiveMin= 8; + info->effectiveMax= 255; + bzero((char *)info->names,sizeof(info->names)); + bzero((char *)info->files,sizeof(info->files)); + bzero((char *)info->has_alt_forms,sizeof(info->has_alt_forms)); + if (info->leds) + ClearIndicatorNameInfo(info->leds,info); + if (info->aliases) + ClearAliases(&info->aliases); + return; +} + +static void +InitKeyNamesInfo(KeyNamesInfo *info) +{ + info->name= NULL; + info->leds= NULL; + info->aliases= NULL; + ClearKeyNamesInfo(info); + info->errorCount= 0; + return; +} + +static int +FindKeyByLong(KeyNamesInfo *info,unsigned long name) +{ +register int i; + + for (i=info->effectiveMin;i<=info->effectiveMax;i++) { + if (info->names[i]==name) + return i; + } + return 0; +} + +static Bool +AddKeyName( KeyNamesInfo * info, + int kc, + char * name, + unsigned merge, + unsigned fileID, + Bool reportCollisions) +{ +int old; +unsigned long lval; + + if ((kceffectiveMin)||(kc>info->effectiveMax)) { + ERROR2("Illegal keycode %d for name <%s>\n",kc,name); + ACTION2("Must be in the range %d-%d inclusive\n",info->effectiveMin, + info->effectiveMax); + return False; + } + if (kccomputedMin) info->computedMin= kc; + if (kc>info->computedMax) info->computedMax= kc; + lval= KeyNameToLong(name); + + if (reportCollisions) { + reportCollisions= ((warningLevel>7)|| + ((warningLevel>0)&&(fileID==info->files[kc]))); + } + + if (info->names[kc]!=0) { + char buf[6]; + + LongToKeyName(info->names[kc],buf); + buf[4]= '\0'; + if (info->names[kc]==lval) { + if (info->has_alt_forms[kc] || (merge==MergeAltForm)) { + info->has_alt_forms[kc]= True; + } + else if (reportCollisions) { + WARN("Multiple identical key name definitions\n"); + ACTION2("Later occurences of \"<%s> = %d\" ignored\n",buf,kc); + } + return True; + } + if (merge==MergeAugment) { + if (reportCollisions) { + WARN1("Multiple names for keycode %d\n",kc); + ACTION2("Using <%s>, ignoring <%s>\n",buf,name); + } + return True; + } + else { + if (reportCollisions) { + WARN1("Multiple names for keycode %d\n",kc); + ACTION2("Using <%s>, ignoring <%s>\n",name,buf); + } + info->names[kc]= 0; + info->files[kc]= 0; + } + } + old= FindKeyByLong(info,lval); + if ((old!=0)&&(old!=kc)) { + if (merge==MergeOverride) { + info->names[old]= 0; + info->files[old]= 0; + info->has_alt_forms[old]= True; + if (reportCollisions) { + WARN1("Key name <%s> assigned to multiple keys\n",name); + ACTION2("Using %d, ignoring %d\n",kc,old); + } + } + else if (merge!=MergeAltForm) { + if ((reportCollisions)&&(warningLevel>3)) { + WARN1("Key name <%s> assigned to multiple keys\n",name); + ACTION2("Using %d, ignoring %d\n",old,kc); + ACTION("Use 'alternate' keyword to assign the same name to multiple keys\n"); + } + return True; + } + else { + info->has_alt_forms[old]= True; + } + } + info->names[kc]= lval; + info->files[kc]= fileID; + info->has_alt_forms[kc]= (merge==MergeAltForm); + return True; +} + +/***====================================================================***/ + +static void +MergeIncludedKeycodes(KeyNamesInfo *into,KeyNamesInfo *from,unsigned merge) +{ +register int i; +char buf[5]; + + if (from->errorCount>0) { + into->errorCount+= from->errorCount; + return; + } + if (into->name==NULL) { + into->name= from->name; + from->name= NULL; + } + for (i=from->computedMin;i<=from->computedMax;i++) { + unsigned thisMerge; + if (from->names[i]==0) + continue; + LongToKeyName(from->names[i],buf); + buf[4]= '\0'; + if (from->has_alt_forms[i]) + thisMerge= MergeAltForm; + else thisMerge= merge; + if (!AddKeyName(into,i,buf,thisMerge,from->fileID,False)) + into->errorCount++; + } + if (from->leds) { + IndicatorNameInfo *led,*next; + for (led=from->leds;led!=NULL;led=next) { + if (merge!=MergeDefault) + led->defs.merge= merge; + if (!AddIndicatorName(into,led)) + into->errorCount++; + next= (IndicatorNameInfo *)led->defs.next; + } + } + if (!MergeAliases(&into->aliases,&from->aliases,merge)) + into->errorCount++; + if (from->explicitMin>0) { + if ((into->explicitMin<0)||(into->explicitMin>from->explicitMin)) + into->effectiveMin= into->explicitMin= from->explicitMin; + } + if (from->explicitMax>0) { + if ((into->explicitMax<0)||(into->explicitMaxexplicitMax)) + into->effectiveMax= into->explicitMax= from->explicitMax; + } + return; +} + +typedef void (*FileHandler)( + XkbFile * /* rtrn */, + XkbDescPtr /* xkb */, + unsigned /* merge */, + KeyNamesInfo * /* included */ +); + +static Bool +HandleIncludeKeycodes( IncludeStmt * stmt, + XkbDescPtr xkb, + KeyNamesInfo * info, + FileHandler hndlr) +{ +unsigned newMerge; +XkbFile * rtrn; +KeyNamesInfo included; +Bool haveSelf; + + haveSelf= False; + if ((stmt->file==NULL)&&(stmt->map==NULL)) { + haveSelf= True; + included= *info; + bzero(info,sizeof(KeyNamesInfo)); + } + else if (strcmp(stmt->file,"computed")==0) { + xkb->flags|= AutoKeyNames; + info->explicitMin= XkbMinLegalKeyCode; + info->explicitMax= XkbMaxLegalKeyCode; + return (info->errorCount==0); + } + else if (ProcessIncludeFile(stmt,XkmKeyNamesIndex,&rtrn,&newMerge)) { + InitKeyNamesInfo(&included); + (*hndlr)(rtrn,xkb,MergeOverride,&included); + if (stmt->stmt!=NULL) { + if (included.name!=NULL) + uFree(included.name); + included.name= stmt->stmt; + stmt->stmt= NULL; + } + } + else { + info->errorCount+= 10; + return False; + } + if ((stmt->next!=NULL)&&(included.errorCount<1)) { + IncludeStmt * next; + unsigned op; + KeyNamesInfo next_incl; + + for (next=stmt->next;next!=NULL;next=next->next) { + if ((next->file==NULL)&&(next->map==NULL)) { + haveSelf= True; + MergeIncludedKeycodes(&included,info,next->merge); + ClearKeyNamesInfo(info); + } + else if (ProcessIncludeFile(next,XkmKeyNamesIndex,&rtrn,&op)) { + InitKeyNamesInfo(&next_incl); + (*hndlr)(rtrn,xkb,MergeOverride,&next_incl); + MergeIncludedKeycodes(&included,&next_incl,op); + ClearKeyNamesInfo(&next_incl); + } + else { + info->errorCount+= 10; + return False; + } + } + } + if (haveSelf) + *info= included; + else { + MergeIncludedKeycodes(info,&included,newMerge); + ClearKeyNamesInfo(&included); + } + return (info->errorCount==0); +} + +static int +HandleKeycodeDef( KeycodeDef * stmt, + XkbDescPtr xkb, + unsigned merge, + KeyNamesInfo * info) +{ +int code; +ExprResult result; + + if (!ExprResolveInteger(stmt->value,&result,NULL,NULL)) { + ACTION1("No value keycode assigned to name <%s>\n",stmt->name); + return 0; + } + code= result.ival; + if ((codeeffectiveMin)||(code>info->effectiveMax)) { + ERROR2("Illegal keycode %d for name <%s>\n",code,stmt->name); + ACTION2("Must be in the range %d-%d inclusive\n",info->effectiveMin, + info->effectiveMax); + return 0; + } + if (stmt->merge!=MergeDefault) { + if (stmt->merge==MergeReplace) + merge= MergeOverride; + else merge= stmt->merge; + } + return AddKeyName(info,code,stmt->name,merge,info->fileID,True); +} + +#define MIN_KEYCODE_DEF 0 +#define MAX_KEYCODE_DEF 1 + +static int +HandleKeyNameVar(VarDef *stmt,XkbDescPtr xkb,unsigned merge,KeyNamesInfo *info) +{ +ExprResult tmp,field; +ExprDef * arrayNdx; +int which; + + if (ExprResolveLhs(stmt->name,&tmp,&field,&arrayNdx)==0) + return 0; /* internal error, already reported */ + + if (tmp.str!=NULL) { + ERROR1("Unknown element %s encountered\n",tmp.str); + ACTION1("Default for field %s ignored\n",field.str); + return 0; + } + if (uStrCaseCmp(field.str,"minimum")==0) which= MIN_KEYCODE_DEF; + else if (uStrCaseCmp(field.str,"maximum")==0) which= MAX_KEYCODE_DEF; + else { + ERROR("Unknown field encountered\n"); + ACTION1("Assigment to field %s ignored\n",field.str); + return 0; + } + if (arrayNdx!=NULL) { + ERROR1("The %s setting is not an array\n",field.str); + ACTION("Illegal array reference ignored\n"); + return 0; + } + + if (ExprResolveInteger(stmt->value,&tmp,NULL,NULL)==0) { + ACTION1("Assignment to field %s ignored\n",field.str); + return 0; + } + if ((tmp.ivalXkbMaxLegalKeyCode)) { + ERROR3("Illegal keycode %d (must be in the range %d-%d inclusive)\n", + tmp.ival,XkbMinLegalKeyCode,XkbMaxLegalKeyCode); + ACTION1("Value of \"%s\" not changed\n",field.str); + return 0; + } + if (which==MIN_KEYCODE_DEF) { + if ((info->explicitMax>0)&&(info->explicitMaxexplicitMax); + ACTION("Minimum key code value not changed\n"); + return 0; + } + if ((info->computedMax>0)&&(info->computedMincomputedMin); + ACTION("Minimum key code value not changed\n"); + return 0; + } + info->explicitMin= tmp.ival; + info->effectiveMin= tmp.ival; + } + if (which==MAX_KEYCODE_DEF) { + if ((info->explicitMin>0)&&(info->explicitMin>tmp.ival)) { + ERROR2("Maximum code (%d) must be >= minimum key code (%d)\n", + tmp.ival,info->explicitMin); + ACTION("Maximum code value not changed\n"); + return 0; + } + if ((info->computedMax>0)&&(info->computedMax>tmp.ival)) { + ERROR2("Maximum code (%d) must be >= highest defined key (%d)\n", + tmp.ival,info->computedMax); + ACTION("Maximum code value not changed\n"); + return 0; + } + info->explicitMax= tmp.ival; + info->effectiveMax= tmp.ival; + } + return 1; +} + +static int +HandleIndicatorNameDef( IndicatorNameDef * def, + XkbDescPtr xkb, + unsigned merge, + KeyNamesInfo * info) +{ +IndicatorNameInfo ii; +ExprResult tmp; + + if ((def->ndx<1)||(def->ndx>XkbNumIndicators)) { + info->errorCount++; + ERROR1("Name specified for illegal indicator index %d\n",def->ndx); + ACTION("Ignored\n"); + return False; + } + InitIndicatorNameInfo(&ii,info); + ii.ndx= def->ndx; + if (!ExprResolveString(def->name,&tmp,NULL,NULL)) { + char buf[20]; + sprintf(buf,"%d",def->ndx); + info->errorCount++; + return ReportBadType("indicator","name",buf,"string"); + } + ii.name= XkbInternAtom(NULL,tmp.str,False); + ii.virtual= def->virtual; + if (!AddIndicatorName(info,&ii)) + return False; + return True; +} + +static void +HandleKeycodesFile( XkbFile * file, + XkbDescPtr xkb, + unsigned merge, + KeyNamesInfo * info) +{ +ParseCommon *stmt; + + info->name= uStringDup(file->name); + stmt= file->defs; + while (stmt) { + switch (stmt->stmtType) { + case StmtInclude: + if (!HandleIncludeKeycodes((IncludeStmt *)stmt,xkb,info, + HandleKeycodesFile)) + info->errorCount++; + break; + case StmtKeycodeDef: + if (!HandleKeycodeDef((KeycodeDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + case StmtKeyAliasDef: + if (!HandleAliasDef((KeyAliasDef *)stmt, + merge,info->fileID,&info->aliases)) + info->errorCount++; + break; + case StmtVarDef: + if (!HandleKeyNameVar((VarDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + case StmtIndicatorNameDef: + if (!HandleIndicatorNameDef((IndicatorNameDef *)stmt,xkb, + merge,info)) { + info->errorCount++; + } + break; + case StmtInterpDef: + case StmtVModDef: + ERROR("Keycode files may define key and indicator names only\n"); + ACTION1("Ignoring definition of %s\n", + ((stmt->stmtType==StmtInterpDef)? + "a symbol interpretation": + "virtual modifiers")); + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleKeycodesFile\n", + stmt->stmtType); + break; + } + stmt= stmt->next; + if (info->errorCount>10) { +#ifdef NOISY + ERROR("Too many errors\n"); +#endif + ACTION1("Abandoning keycodes file \"%s\"\n",file->topName); + break; + } + } + return; +} + +Bool +CompileKeycodes(XkbFile *file,XkbFileInfo *result,unsigned merge) +{ +KeyNamesInfo info; +XkbDescPtr xkb; + + xkb= result->xkb; + InitKeyNamesInfo(&info); + HandleKeycodesFile(file,xkb,merge,&info); + + if (info.errorCount==0) { + if (info.explicitMin>0) + xkb->min_key_code= info.effectiveMin; + else xkb->min_key_code= info.computedMin; + if (info.explicitMax>0) + xkb->max_key_code= info.effectiveMax; + else xkb->max_key_code= info.computedMax; + if (XkbAllocNames(xkb,XkbKeyNamesMask|XkbIndicatorNamesMask,0,0)==Success) { + register int i; + xkb->names->keycodes= XkbInternAtom(xkb->dpy,info.name,False); + uDEBUG2(1,"key range: %d..%d\n",xkb->min_key_code,xkb->max_key_code); + for (i=info.computedMin;i<=info.computedMax;i++) { + LongToKeyName(info.names[i],xkb->names->keys[i].name); + uDEBUG2(2,"key %d = %s\n",i, + XkbKeyNameText(xkb->names->keys[i].name,XkbMessage)); + } + } + else { + WSGO("Cannot create XkbNamesRec in CompileKeycodes\n"); + return False; + } + if (info.leds) { + IndicatorNameInfo *ii; + if (XkbAllocIndicatorMaps(xkb)!=Success) { + WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n"); + ACTION("Physical indicators not set\n"); + } + for (ii=info.leds;ii!=NULL;ii=(IndicatorNameInfo *)ii->defs.next){ + xkb->names->indicators[ii->ndx-1]= + XkbInternAtom(xkb->dpy, + XkbAtomGetString(NULL,ii->name),False); + if (xkb->indicators!=NULL) { + register unsigned bit; + bit= 1<<(ii->ndx-1); + if (ii->virtual) + xkb->indicators->phys_indicators&= ~bit; + else xkb->indicators->phys_indicators|= bit; + } + } + } + if (info.aliases) + ApplyAliases(xkb,False,&info.aliases); + return True; + } + ClearKeyNamesInfo(&info); + return False; +} diff --git a/xkbcomp/keycodes.h b/xkbcomp/keycodes.h new file mode 100644 index 0000000..9333718 --- /dev/null +++ b/xkbcomp/keycodes.h @@ -0,0 +1,44 @@ +/* $Xorg: keycodes.h,v 1.3 2000/08/17 19:54:32 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef KEYCODES_H +#define KEYCODES_H 1 + +#define KeyNameToLong(n) ((((unsigned long)n[0])<<24)|(((unsigned long)n[1])<<16)|(((unsigned long)n[2])<<8)|n[3]) + +extern char * longText( + unsigned long /* val */, + unsigned /* format */ +); + +extern void LongToKeyName( + unsigned long /* val */, + char * /* name_rtrn */ +); + +#endif /* KEYCODES_H */ diff --git a/xkbcomp/keymap.c b/xkbcomp/keymap.c new file mode 100644 index 0000000..86e9c9e --- /dev/null +++ b/xkbcomp/keymap.c @@ -0,0 +1,168 @@ +/* $Xorg: keymap.c,v 1.3 2000/08/17 19:54:32 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "vmod.h" +#include "action.h" +#include "misc.h" +#include "indicators.h" + +#define KEYCODES 0 +#define GEOMETRY 1 +#define TYPES 2 +#define COMPAT 3 +#define SYMBOLS 4 +#define MAX_SECTIONS 5 + +XkbFile * sections[MAX_SECTIONS]; + +Bool +CompileKeymap(XkbFile *file,XkbFileInfo *result,unsigned merge) +{ +unsigned have; +Bool ok; +unsigned required,legal; +unsigned mainType; +char * mainName; +LEDInfo * unbound= NULL; + + bzero(sections,MAX_SECTIONS*sizeof(XkbFile *)); + mainType= file->type; + mainName= file->name; + switch (mainType) { + case XkmSemanticsFile: + required= XkmSemanticsRequired; + legal= XkmSemanticsLegal; + break; + case XkmLayoutFile: + required= XkmLayoutRequired; + legal= XkmKeymapLegal; + break; + case XkmKeymapFile: + required= XkmKeymapRequired; + legal= XkmKeymapLegal; + break; + default: + ERROR1("Cannot compile %s alone into an XKM file\n", + XkbConfigText(mainType,XkbMessage)); + return False; + } + have= 0; + ok= 1; + file= (XkbFile *)file->defs; + while ((file)&&(ok)) { + file->topName= mainName; + if ((have&(1<type))!=0) { + ERROR2("More than one %s section in a %s file\n", + XkbConfigText(file->type,XkbMessage), + XkbConfigText(mainType,XkbMessage)); + ACTION("All sections after the first ignored\n"); + ok= False; + } + else if ((1<type)&(~legal)) { + ERROR2("Cannot define %s in a %s file\n", + XkbConfigText(file->type,XkbMessage), + XkbConfigText(mainType,XkbMessage)); + ok= False; + } + else switch (file->type) { + case XkmSemanticsFile: + case XkmLayoutFile: + case XkmKeymapFile: + WSGO2("Illegal %s configuration in a %s file\n", + XkbConfigText(file->type,XkbMessage), + XkbConfigText(mainType,XkbMessage)); + ACTION("Ignored\n"); + ok= False; + break; + case XkmKeyNamesIndex: + sections[KEYCODES]= file; + break; + case XkmTypesIndex: + sections[TYPES]= file; + break; + case XkmSymbolsIndex: + sections[SYMBOLS]= file; + break; + case XkmCompatMapIndex: + sections[COMPAT]= file; + break; + case XkmGeometryIndex: + case XkmGeometryFile: + sections[GEOMETRY]= file; + break; + case XkmVirtualModsIndex: + case XkmIndicatorsIndex: + WSGO1("Found an isolated %s section\n", + XkbConfigText(file->type,XkbMessage)); + break; + default: + WSGO1("Unknown file type %d\n",file->type); + break; + } + if (ok) + have|= (1<type); + file= (XkbFile*)file->common.next; + } + if (ok) { + if (ok && (sections[KEYCODES]!=NULL)) + ok= CompileKeycodes(sections[KEYCODES],result,MergeOverride); + if (ok && (sections[GEOMETRY]!=NULL)) + ok= CompileGeometry(sections[GEOMETRY],result,MergeOverride); + if (ok && (sections[TYPES]!=NULL)) + ok= CompileKeyTypes(sections[TYPES],result,MergeOverride); + if (ok && (sections[COMPAT]!=NULL)) + ok=CompileCompatMap(sections[COMPAT],result,MergeOverride,&unbound); + if (ok && (sections[SYMBOLS]!=NULL)) + ok= CompileSymbols(sections[SYMBOLS],result,MergeOverride); + } + if (!ok) + return False; + result->defined= have; + if (required&(~have)) { + register int i,bit; + unsigned missing; + missing= required&(~have); + for (i=0,bit=1;missing!=0;i++,bit<<=1) { + if (missing&bit) { + ERROR2("Missing %s section in a %s file\n", + XkbConfigText(i,XkbMessage), + XkbConfigText(mainType,XkbMessage)); + missing&=~bit; + } + } + ACTION1("Description of %s not compiled\n", + XkbConfigText(mainType,XkbMessage)); + ok= False; + } + ok= BindIndicators(result,True,unbound,NULL); + return ok; +} + diff --git a/xkbcomp/keytypes.c b/xkbcomp/keytypes.c new file mode 100644 index 0000000..e436136 --- /dev/null +++ b/xkbcomp/keytypes.c @@ -0,0 +1,1159 @@ +/* $Xorg: keytypes.c,v 1.3 2000/08/17 19:54:32 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/keytypes.c,v 1.4 2001/01/17 23:45:44 dawes Exp $ */ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "vmod.h" +#include "action.h" +#include "misc.h" + +typedef struct _PreserveInfo { + CommonInfo defs; + short matchingMapIndex; + unsigned char indexMods; + unsigned char preMods; + unsigned short indexVMods; + unsigned short preVMods; +} PreserveInfo; + +#define _KT_Name (1<<0) +#define _KT_Mask (1<<1) +#define _KT_Map (1<<2) +#define _KT_Preserve (1<<3) +#define _KT_LevelNames (1<<4) + +typedef struct _KeyTypeInfo { + CommonInfo defs; + Display * dpy; + Atom name; + int fileID; + unsigned mask; + unsigned vmask; + Bool groupInfo; + int numLevels; + int nEntries; + int szEntries; + XkbKTMapEntryPtr entries; + PreserveInfo * preserve; + int szNames; + Atom * lvlNames; +} KeyTypeInfo; + +typedef struct _KeyTypesInfo { + Display * dpy; + char * name; + int errorCount; + int fileID; + unsigned stdPresent; + int nTypes; + KeyTypeInfo * types; + KeyTypeInfo dflt; + VModInfo vmods; +} KeyTypesInfo; + +Atom tok_ONE_LEVEL; +Atom tok_TWO_LEVEL; +Atom tok_ALPHABETIC; +Atom tok_KEYPAD; + +/***====================================================================***/ + +#define ReportTypeShouldBeArray(t,f) \ + ReportShouldBeArray("key type",(f),TypeTxt(t)) +#define ReportTypeBadType(t,f,w) \ + ReportBadType("key type",(f),TypeTxt(t),(w)) + +/***====================================================================***/ + +extern Bool AddMapEntry( + XkbDescPtr /* xkb */, + KeyTypeInfo * /* type */, + XkbKTMapEntryPtr /* new */, + Bool /* clobber */, + Bool /* report */ +); + +extern Bool AddPreserve( + XkbDescPtr /* xkb */, + KeyTypeInfo * /* type */, + PreserveInfo * /* new */, + Bool /* clobber */, + Bool /* report */ +); + +extern Bool AddLevelName( + KeyTypeInfo * /* type */, + unsigned /* level */, + Atom /* name */, + Bool /* clobber */, + Bool /* report */ +); + +#define MapEntryTxt(t,x,e) \ + XkbVModMaskText((t)->dpy,(x),(e)->mods.real_mods,(e)->mods.vmods,XkbMessage) +#define PreserveIndexTxt(t,x,p) \ + XkbVModMaskText((t)->dpy,(x),(p)->indexMods,(p)->indexVMods,XkbMessage) +#define PreserveTxt(t,x,p) \ + XkbVModMaskText((t)->dpy,(x),(p)->preMods,(p)->preVMods,XkbMessage) +#define TypeTxt(t) XkbAtomText((t)->dpy,(t)->name,XkbMessage) +#define TypeMaskTxt(t,x) \ + XkbVModMaskText((t)->dpy,(x),(t)->mask,(t)->vmask,XkbMessage) + +/***====================================================================***/ + +static void +InitKeyTypesInfo(KeyTypesInfo *info,XkbDescPtr xkb,KeyTypesInfo *from) +{ + tok_ONE_LEVEL= XkbInternAtom(NULL,"ONE_LEVEL",False); + tok_TWO_LEVEL= XkbInternAtom(NULL,"TWO_LEVEL",False); + tok_ALPHABETIC= XkbInternAtom(NULL,"ALPHABETIC",False); + tok_KEYPAD= XkbInternAtom(NULL,"KEYPAD",False); + info->dpy= NULL; + info->name= uStringDup("default"); + info->errorCount= 0; + info->stdPresent= 0; + info->nTypes= 0; + info->types= NULL; + info->dflt.defs.defined= 0; + info->dflt.defs.fileID= 0; + info->dflt.defs.merge= MergeOverride; + info->dflt.defs.next= NULL; + info->dflt.name= None; + info->dflt.mask= 0; + info->dflt.vmask= 0; + info->dflt.groupInfo= False; + info->dflt.numLevels= 1; + info->dflt.nEntries= info->dflt.szEntries= 0; + info->dflt.entries= NULL; + info->dflt.szNames= 0; + info->dflt.lvlNames= NULL; + info->dflt.preserve= NULL; + InitVModInfo(&info->vmods,xkb); + if (from!=NULL) { + info->dpy= from->dpy; + info->dflt= from->dflt; + if (from->dflt.entries) { + info->dflt.entries= uTypedCalloc(from->dflt.szEntries, + XkbKTMapEntryRec); + if (info->dflt.entries) { + unsigned sz = from->dflt.nEntries*sizeof(XkbKTMapEntryRec); + memcpy(info->dflt.entries,from->dflt.entries,sz); + } + } + if (from->dflt.lvlNames) { + info->dflt.lvlNames= uTypedCalloc(from->dflt.szNames,Atom); + if (info->dflt.lvlNames) { + register unsigned sz = from->dflt.szNames*sizeof(Atom); + memcpy(info->dflt.lvlNames,from->dflt.lvlNames,sz); + } + } + if (from->dflt.preserve) { + PreserveInfo *old,*new,*last; + last= NULL; + old= from->dflt.preserve; + for (;old;old=(PreserveInfo *)old->defs.next) { + new= uTypedAlloc(PreserveInfo); + if (!new) + return; + *new= *old; + new->defs.next= NULL; + if (last) last->defs.next= (CommonInfo *)new; + else info->dflt.preserve= new; + last= new; + } + } + } + return; +} + +static void +FreeKeyTypeInfo(KeyTypeInfo *type) +{ + if (type->entries!=NULL) { + uFree(type->entries); + type->entries= NULL; + } + if (type->lvlNames!=NULL) { + uFree(type->lvlNames); + type->lvlNames= NULL; + } + if (type->preserve!=NULL) { + ClearCommonInfo(&type->preserve->defs); + type->preserve= NULL; + } + return; +} + +static void +FreeKeyTypesInfo(KeyTypesInfo *info) +{ + info->dpy= NULL; + if (info->name) + uFree(info->name); + info->name= NULL; + if (info->types) { + register KeyTypeInfo *type; + for (type= info->types;type;type=(KeyTypeInfo *)type->defs.next) { + FreeKeyTypeInfo(type); + } + info->types= (KeyTypeInfo *)ClearCommonInfo(&info->types->defs); + } + FreeKeyTypeInfo(&info->dflt); + return; +} + +static KeyTypeInfo * +NextKeyType(KeyTypesInfo *info) +{ +KeyTypeInfo * type; + + type= uTypedAlloc(KeyTypeInfo); + if (type!=NULL) { + bzero(type,sizeof(KeyTypeInfo)); + type->defs.fileID= info->fileID; + type->dpy= info->dpy; + info->types= (KeyTypeInfo *)AddCommonInfo(&info->types->defs, + (CommonInfo *)type); + info->nTypes++; + } + return type; +} + +static KeyTypeInfo * +FindMatchingKeyType(KeyTypesInfo *info,KeyTypeInfo *new) +{ +KeyTypeInfo *old; + + for (old=info->types;old;old=(KeyTypeInfo *)old->defs.next) { + if (old->name==new->name) + return old; + } + return NULL; +} + +static Bool +ReportTypeBadWidth(char *type,int has,int needs) +{ + ERROR3("Key type \"%s\" has %d levels, must have %d\n",type,has,needs); + ACTION("Illegal type definition ignored\n"); + return False; +} + +static Bool +AddKeyType(XkbDescPtr xkb,KeyTypesInfo *info,KeyTypeInfo *new) +{ +KeyTypeInfo * old; + + if (new->name==tok_ONE_LEVEL) { + if (new->numLevels>1) + return ReportTypeBadWidth("ONE_LEVEL",new->numLevels,1); + info->stdPresent|= XkbOneLevelMask; + } + else if (new->name==tok_TWO_LEVEL) { + if (new->numLevels>2) + return ReportTypeBadWidth("TWO_LEVEL",new->numLevels,2); + else if (new->numLevels<2) + new->numLevels= 2; + info->stdPresent|= XkbTwoLevelMask; + } + else if (new->name==tok_ALPHABETIC) { + if (new->numLevels>2) + return ReportTypeBadWidth("ALPHABETIC",new->numLevels,2); + else if (new->numLevels<2) + new->numLevels= 2; + info->stdPresent|= XkbAlphabeticMask; + } + else if (new->name==tok_KEYPAD) { + if (new->numLevels>2) + return ReportTypeBadWidth("KEYPAD",new->numLevels,2); + else if (new->numLevels<2) + new->numLevels= 2; + info->stdPresent|= XkbKeypadMask; + } + + old= FindMatchingKeyType(info,new); + if (old!=NULL) { + Bool report; + if ((new->defs.merge==MergeReplace)||(new->defs.merge==MergeOverride)) { + KeyTypeInfo *next= (KeyTypeInfo *)old->defs.next; + if (((old->defs.fileID==new->defs.fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + WARN1("Multiple definitions of the %s key type\n", + XkbAtomGetString(NULL,new->name)); + ACTION("Earlier definition ignored\n"); + } + FreeKeyTypeInfo(old); + *old= *new; + new->szEntries= new->nEntries= 0; + new->entries= NULL; + new->preserve= NULL; + new->lvlNames= NULL; + old->defs.next= &next->defs; + return True; + } + report= (old->defs.fileID==new->defs.fileID)&&(warningLevel>0); + if (report) { + WARN1("Multiple definitions of the %s key type\n", + XkbAtomGetString(NULL,new->name)); + ACTION("Later definition ignored\n"); + } + FreeKeyTypeInfo(new); + return True; + } + old= NextKeyType(info); + if (old==NULL) + return False; + *old= *new; + old->defs.next= NULL; + new->nEntries= new->szEntries= 0; + new->entries= NULL; + new->szNames= 0; + new->lvlNames= NULL; + new->preserve= NULL; + return True; +} + +/***====================================================================***/ + +static void +MergeIncludedKeyTypes( KeyTypesInfo * into, + KeyTypesInfo * from, + unsigned merge, + XkbDescPtr xkb) +{ +KeyTypeInfo * type; + + if (from->errorCount>0) { + into->errorCount+= from->errorCount; + return; + } + if (into->name==NULL) { + into->name= from->name; + from->name= NULL; + } + for (type=from->types;type;type=(KeyTypeInfo *)type->defs.next) { + if (merge!=MergeDefault) + type->defs.merge= merge; + if (!AddKeyType(xkb,into,type)) + into->errorCount++; + } + into->stdPresent|= from->stdPresent; + return; +} + +typedef void (*FileHandler)( + XkbFile * /* file */, + XkbDescPtr /* xkb */, + unsigned /* merge */, + KeyTypesInfo * /* included */ +); + +static Bool +HandleIncludeKeyTypes( IncludeStmt * stmt, + XkbDescPtr xkb, + KeyTypesInfo * info, + FileHandler hndlr) +{ +unsigned newMerge; +XkbFile * rtrn; +KeyTypesInfo included; +Bool haveSelf; + + haveSelf= False; + if ((stmt->file==NULL)&&(stmt->map==NULL)) { + haveSelf= True; + included= *info; + bzero(info,sizeof(KeyTypesInfo)); + } + else if (ProcessIncludeFile(stmt,XkmTypesIndex,&rtrn,&newMerge)) { + InitKeyTypesInfo(&included,xkb,info); + included.fileID= included.dflt.defs.fileID= rtrn->id; + included.dflt.defs.merge= newMerge; + + (*hndlr)(rtrn,xkb,newMerge,&included); + if (stmt->stmt!=NULL) { + if (included.name!=NULL) + uFree(included.name); + included.name= stmt->stmt; + stmt->stmt= NULL; + } + } + else { + info->errorCount+= 10; + return False; + } + if ((stmt->next!=NULL)&&(included.errorCount<1)) { + IncludeStmt * next; + unsigned op; + KeyTypesInfo next_incl; + + for (next=stmt->next;next!=NULL;next=next->next) { + if ((next->file==NULL)&&(next->map==NULL)) { + haveSelf= True; + MergeIncludedKeyTypes(&included,info,next->merge,xkb); + FreeKeyTypesInfo(info); + } + else if (ProcessIncludeFile(next,XkmTypesIndex,&rtrn,&op)) { + InitKeyTypesInfo(&next_incl,xkb,&included); + next_incl.fileID= next_incl.dflt.defs.fileID= rtrn->id; + next_incl.dflt.defs.merge= op; + (*hndlr)(rtrn,xkb,op,&next_incl); + MergeIncludedKeyTypes(&included,&next_incl,op,xkb); + FreeKeyTypesInfo(&next_incl); + } + else { + info->errorCount+= 10; + return False; + } + } + } + if (haveSelf) + *info= included; + else { + MergeIncludedKeyTypes(info,&included,newMerge,xkb); + FreeKeyTypesInfo(&included); + } + return (info->errorCount==0); +} + +/***====================================================================***/ + +static XkbKTMapEntryPtr +FindMatchingMapEntry(KeyTypeInfo *type,unsigned mask,unsigned vmask) +{ +register int i; +XkbKTMapEntryPtr entry; + + for (i=0,entry=type->entries;inEntries;i++,entry++) { + if ((entry->mods.real_mods==mask)&&(entry->mods.vmods==vmask)) + return entry; + } + return NULL; +} + +static void +DeleteLevel1MapEntries(KeyTypeInfo *type) +{ +register int i,n; + + for (i=0;inEntries;i++) { + if (type->entries[i].level==0) { + for (n=i;nnEntries-1;n++) { + type->entries[n]= type->entries[n+1]; + } + type->nEntries--; + } + } + return; +} + +static XkbKTMapEntryPtr +NextMapEntry(KeyTypeInfo *type) +{ + if (type->entries==NULL) { + type->entries= uTypedCalloc(2,XkbKTMapEntryRec); + if (type->entries==NULL) { + ERROR1("Couldn't allocate map entries for %s\n",TypeTxt(type)); + ACTION("Map entries lost\n"); + return NULL; + } + type->szEntries= 2; + type->nEntries= 0; + } + else if (type->nEntries>=type->szEntries) { + type->szEntries*=2; + type->entries= uTypedRecalloc(type->entries, + type->nEntries,type->szEntries, + XkbKTMapEntryRec); + if (type->entries==NULL) { + ERROR1("Couldn't reallocate map entries for %s\n",TypeTxt(type)); + ACTION("Map entries lost\n"); + return NULL; + } + } + return &type->entries[type->nEntries++]; +} + +Bool +AddPreserve( XkbDescPtr xkb, + KeyTypeInfo * type, + PreserveInfo * new, + Bool clobber, + Bool report) +{ +PreserveInfo *old; + + old= type->preserve; + while (old!=NULL) { + if ((old->indexMods!=new->indexMods)|| + (old->indexVMods!=new->indexVMods)) { + old= (PreserveInfo *)old->defs.next; + continue; + } + if ((old->preMods==new->preMods)&&(old->preVMods==new->preVMods)) { + if (warningLevel>9) { + WARN2("Identical definitions for preserve[%s] in %s\n", + PreserveIndexTxt(type,xkb,old),TypeTxt(type)); + ACTION("Ignored\n"); + } + return True; + } + if (report && (warningLevel>0)) { + char *str; + WARN2("Multiple definitions for preserve[%s] in %s\n", + PreserveIndexTxt(type,xkb,old),TypeTxt(type)); + + if (clobber) str= PreserveTxt(type,xkb,new); + else str= PreserveTxt(type,xkb,old); + ACTION1("Using %s, ",str); + if (clobber) str= PreserveTxt(type,xkb,old); + else str= PreserveTxt(type,xkb,new); + INFO1("ignoring %s\n",str); + } + if (clobber) { + old->preMods= new->preMods; + old->preVMods= new->preVMods; + } + return True; + } + old= uTypedAlloc(PreserveInfo); + if (!old) { + WSGO1("Couldn't allocate preserve in %s\n",TypeTxt(type)); + ACTION1("Preserve[%s] lost\n",PreserveIndexTxt(type,xkb,old)); + return False; + } + *old= *new; + old->matchingMapIndex= -1; + type->preserve=(PreserveInfo*)AddCommonInfo(&type->preserve->defs,&old->defs); + return True; +} + +Bool +AddMapEntry( XkbDescPtr xkb, + KeyTypeInfo * type, + XkbKTMapEntryPtr new, + Bool clobber, + Bool report) +{ +XkbKTMapEntryPtr old; + + if ((old=FindMatchingMapEntry(type,new->mods.real_mods,new->mods.vmods))) { + if (report&&(old->level!=new->level)) { + unsigned use,ignore; + if (clobber) { + use= new->level+1; + ignore= old->level+1; + } + else { + use= old->level+1; + ignore= new->level+1; + } + WARN2("Multiple map entries for %s in %s\n", + MapEntryTxt(type,xkb,new),TypeTxt(type)); + ACTION2("Using %d, ignoring %d\n",use,ignore); + } + else if (warningLevel>9) { + WARN3("Multiple occurences of map[%s]= %d in %s\n", + MapEntryTxt(type,xkb,new),new->level+1,TypeTxt(type)); + ACTION("Ignored\n"); + return True; + } + if (clobber) + old->level= new->level; + return True; + } + if ((old=NextMapEntry(type))==NULL) + return False; /* allocation failure, already reported */ + if (new->level>=type->numLevels) + type->numLevels= new->level+1; + if (new->mods.vmods==0) old->active= True; + else old->active= False; + old->mods.mask= new->mods.real_mods; + old->mods.real_mods= new->mods.real_mods; + old->mods.vmods= new->mods.vmods; + old->level= new->level; + return True; +} + +static LookupEntry lnames[] = { + { "level1", 1 }, + { "level2", 2 }, + { "level3", 3 }, + { "level4", 4 }, + { "level5", 5 }, + { "level6", 6 }, + { "level7", 7 }, + { "level8", 8 }, + { NULL, 0 } +}; + +static Bool +SetMapEntry( KeyTypeInfo * type, + XkbDescPtr xkb, + ExprDef * arrayNdx, + ExprDef * value) +{ +ExprResult rtrn; +XkbKTMapEntryRec entry; + + if (arrayNdx==NULL) + return ReportTypeShouldBeArray(type,"map entry"); + if (!ExprResolveModMask(arrayNdx,&rtrn,LookupVModMask,(XPointer)xkb)) + return ReportTypeBadType(type,"map entry","modifier mask"); + entry.mods.real_mods= rtrn.uval&0xff; + entry.mods.vmods= (rtrn.uval>>8)&0xffff; + if ((entry.mods.real_mods&(~type->mask))|| + ((entry.mods.vmods&(~type->vmask))!=0)) { + if (warningLevel>0) { + WARN1("Map entry for unused modifiers in %s\n",TypeTxt(type)); + ACTION1("Using %s instead of ",XkbVModMaskText(type->dpy,xkb, + entry.mods.real_mods&type->mask, + entry.mods.vmods&type->vmask, + XkbMessage)); + INFO1("%s\n",MapEntryTxt(type,xkb,&entry)); + } + entry.mods.real_mods&= type->mask; + entry.mods.vmods&= type->vmask; + } + if (!ExprResolveInteger(value,&rtrn,SimpleLookup,(XPointer)lnames)) { + ERROR("Level specifications in a key type must be integer\n"); + ACTION("Ignoring malformed level specification\n"); + return False; + } + if ((rtrn.ival<1)||(rtrn.ival>XkbMaxShiftLevel+1)) { + ERROR3("Shift level %d out of range (1..%d) in key type %s\n", + XkbMaxShiftLevel+1, + rtrn.ival,TypeTxt(type)); + ACTION1("Ignoring illegal definition of map[%s]\n", + MapEntryTxt(type,xkb,&entry)); + return False; + } + entry.level= rtrn.ival-1; + return AddMapEntry(xkb,type,&entry,True,True); +} + +static Bool +SetPreserve( KeyTypeInfo * type, + XkbDescPtr xkb, + ExprDef * arrayNdx, + ExprDef * value) +{ +ExprResult rtrn; +PreserveInfo new; + + if (arrayNdx==NULL) + return ReportTypeShouldBeArray(type,"preserve entry"); + if (!ExprResolveModMask(arrayNdx,&rtrn,LookupVModMask,(XPointer)xkb)) + return ReportTypeBadType(type,"preserve entry","modifier mask"); + new.defs= type->defs; + new.defs.next= NULL; + new.indexMods= rtrn.uval&0xff; + new.indexVMods= (rtrn.uval>>8)&0xffff; + if ((new.indexMods&(~type->mask))||(new.indexVMods&(~type->vmask))) { + if (warningLevel>0) { + WARN1("Preserve for modifiers not used by the %s type\n", + TypeTxt(type)); + ACTION1("Index %s converted to ",PreserveIndexTxt(type,xkb,&new)); + } + new.indexMods&= type->mask; + new.indexVMods&= type->vmask; + if (warningLevel>0) + INFO1("%s\n",PreserveIndexTxt(type,xkb,&new)); + } + if (!ExprResolveModMask(value,&rtrn,LookupVModMask,(XPointer)xkb)) { + ERROR("Preserve value in a key type is not a modifier mask\n"); + ACTION2("Ignoring preserve[%s] in type %s\n", + PreserveIndexTxt(type,xkb,&new), + TypeTxt(type)); + return False; + } + new.preMods= rtrn.uval&0xff; + new.preVMods= (rtrn.uval>>16)&0xffff; + if ((new.preMods&(~new.indexMods))||(new.preVMods&&(~new.indexVMods))) { + if (warningLevel>0) { + WARN2("Illegal value for preserve[%s] in type %s\n", + PreserveTxt(type,xkb,&new), + TypeTxt(type)); + ACTION1("Converted %s to ",PreserveIndexTxt(type,xkb,&new)); + } + new.preMods&= new.indexMods; + new.preVMods&= new.indexVMods; + if (warningLevel>0) { + INFO1("%s\n",PreserveIndexTxt(type,xkb,&new)); + } + } + return AddPreserve(xkb,type,&new,True,True); +} + +/***====================================================================***/ + +Bool +AddLevelName( KeyTypeInfo * type, + unsigned level, + Atom name, + Bool clobber, + Bool report) +{ + if ((type->lvlNames==NULL)||(type->szNames<=level)) { + type->lvlNames= + uTypedRecalloc(type->lvlNames,type->szNames,level+1,Atom); + if (type->lvlNames==NULL) { + ERROR1("Couldn't allocate level names for type %s\n",TypeTxt(type)); + ACTION("Level names lost\n"); + type->szNames= 0; + return False; + } + type->szNames= level+1; + } + else if (type->lvlNames[level]==name) { + if (warningLevel>9) { + WARN2("Duplicate names for level %d of key type %s\n",level+1, + TypeTxt(type)); + ACTION("Ignored\n"); + } + return True; + } + else if (type->lvlNames[level]!=None) { + if (warningLevel>0) { + char *old,*new; + old= XkbAtomText(type->dpy,type->lvlNames[level],XkbMessage); + new= XkbAtomText(type->dpy,name,XkbMessage); + WARN2("Multiple names for level %d of key type %s\n",level+1, + TypeTxt(type)); + if (clobber) + ACTION2("Using %s, ignoring %s\n",new,old); + else ACTION2("Using %s, ignoring %s\n",old,new); + } + if (!clobber) + return True; + } + if (level>=type->numLevels) + type->numLevels= level+1; + type->lvlNames[level]= name; + return True; +} + +static Bool +SetLevelName(KeyTypeInfo *type,ExprDef *arrayNdx,ExprDef *value) +{ +ExprResult rtrn; +unsigned level; + + if (arrayNdx==NULL) + return ReportTypeShouldBeArray(type,"level name"); + if (!ExprResolveInteger(arrayNdx,&rtrn,SimpleLookup,(XPointer)lnames)) + return ReportTypeBadType(type,"level name","integer"); + if ((rtrn.ival<1)||(rtrn.ival>XkbMaxShiftLevel+1)) { + ERROR3("Level name %d out of range (1..%d) in key type %s\n", + rtrn.ival, + XkbMaxShiftLevel+1, + XkbAtomText(type->dpy,type->name,XkbMessage)); + ACTION("Ignoring illegal level name definition\n"); + return False; + } + level= rtrn.ival-1; + if (!ExprResolveString(value,&rtrn,NULL,NULL)) { + ERROR2("Non-string name for level %d in key type %s\n",level+1, + XkbAtomText(type->dpy,type->name,XkbMessage)); + ACTION("Ignoring illegal level name definition\n"); + return False; + } + return + AddLevelName(type,level,XkbInternAtom(NULL,rtrn.str,False),True,True); +} + +/***====================================================================***/ + +static Bool +SetKeyTypeField( KeyTypeInfo * type, + XkbDescPtr xkb, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + KeyTypesInfo * info) +{ +ExprResult tmp; + + if (uStrCaseCmp(field,"modifiers")==0) { + unsigned mods,vmods; + if (arrayNdx!=NULL) { + WARN("The modifiers field of a key type is not an array\n"); + ACTION("Illegal array subscript ignored\n"); + } + if (!ExprResolveModMask(value,&tmp,LookupVModMask,(XPointer)xkb)) { + ERROR("Key type mask field must be a modifier mask\n"); + ACTION("Key type definition ignored\n"); + return False; + } + mods= tmp.uval&0xff; + vmods= (tmp.uval>>8)&0xffff; + if (type->defs.defined&_KT_Mask) { + WARN1("Multiple modifier mask definitions for key type %s\n", + XkbAtomText(type->dpy,type->name,XkbMessage)); + ACTION1("Using %s, ",TypeMaskTxt(type,xkb)); + INFO1("ignoring %s\n",XkbVModMaskText(type->dpy,xkb,mods, + vmods, + XkbMessage)); + return False; + } + type->mask= mods; + type->vmask= vmods; + type->defs.defined|= _KT_Mask; + return True; + } + else if (uStrCaseCmp(field,"map")==0) { + type->defs.defined|= _KT_Map; + return SetMapEntry(type,xkb,arrayNdx,value); + } + else if (uStrCaseCmp(field,"preserve")==0) { + type->defs.defined|= _KT_Preserve; + return SetPreserve(type,xkb,arrayNdx,value); + } + else if ((uStrCaseCmp(field,"levelname")==0)|| + (uStrCaseCmp(field,"level_name")==0)) { + type->defs.defined|= _KT_LevelNames; + return SetLevelName(type,arrayNdx,value); + } + ERROR2("Unknown field %s in key type %s\n",field,TypeTxt(type)); + ACTION("Definition ignored\n"); + return False; +} + +static Bool +HandleKeyTypeVar(VarDef *stmt,XkbDescPtr xkb,KeyTypesInfo *info) +{ +ExprResult elem,field; +ExprDef * arrayNdx; + + if (!ExprResolveLhs(stmt->name,&elem,&field,&arrayNdx)) + return False; /* internal error, already reported */ + if (elem.str&&(uStrCaseCmp(elem.str,"type")==0)) + return SetKeyTypeField(&info->dflt,xkb,field.str,arrayNdx,stmt->value, + info); + if (elem.str!=NULL) { + ERROR1("Default for unknown element %s\n",uStringText(elem.str)); + ACTION1("Value for field %s ignored\n",uStringText(field.str)); + } + else if (field.str!=NULL) { + ERROR1("Default defined for unknown field %s\n",uStringText(field.str)); + ACTION("Ignored\n"); + } + return False; +} + +static int +HandleKeyTypeBody( VarDef * def, + XkbDescPtr xkb, + KeyTypeInfo * type, + KeyTypesInfo * info) +{ +int ok= 1; +ExprResult tmp,field; +ExprDef * arrayNdx; + + for (;def!=NULL;def= (VarDef *)def->common.next) { + if ((def->name)&&(def->name->type==ExprFieldRef)) { + ok= HandleKeyTypeVar(def,xkb,info); + continue; + } + ok= ExprResolveLhs(def->name,&tmp,&field,&arrayNdx); + if (ok) + ok= SetKeyTypeField(type,xkb,field.str,arrayNdx,def->value,info); + } + return ok; +} + +static int +HandleKeyTypeDef( KeyTypeDef * def, + XkbDescPtr xkb, + unsigned merge, + KeyTypesInfo * info) +{ +register int i; +KeyTypeInfo type; + + if (def->merge!=MergeDefault) + merge= def->merge; + + type.defs.defined= 0; + type.defs.fileID= info->fileID; + type.defs.merge= merge; + type.defs.next= 0; + type.dpy= info->dpy; + type.name= def->name; + type.mask= info->dflt.mask; + type.vmask= info->dflt.vmask; + type.groupInfo= info->dflt.groupInfo; + type.numLevels= 1; + type.nEntries= type.szEntries= 0; + type.entries= NULL; + type.szNames= 0; + type.lvlNames= NULL; + type.preserve= NULL; + + if (!HandleKeyTypeBody(def->body,xkb,&type,info)) { + info->errorCount++; + return False; + } + + /* now copy any appropriate map, preserve or level names from the */ + /* default type */ + for (i=0;idflt.nEntries;i++) { + XkbKTMapEntryPtr dflt; + dflt= &info->dflt.entries[i]; + if (((dflt->mods.real_mods&type.mask)==dflt->mods.real_mods)&& + ((dflt->mods.vmods&type.vmask)==dflt->mods.vmods)) { + AddMapEntry(xkb,&type,dflt,False,False); + } + } + if (info->dflt.preserve) { + PreserveInfo *dflt= info->dflt.preserve; + while (dflt) { + if (((dflt->indexMods&type.mask)==dflt->indexMods)&& + ((dflt->indexVMods&type.vmask)==dflt->indexVMods)) { + AddPreserve(xkb,&type,dflt,False,False); + } + dflt= (PreserveInfo *)dflt->defs.next; + } + } + for (i=0;idflt.szNames;i++) { + if ((idflt.lvlNames[i]!=None)) { + AddLevelName(&type,i,info->dflt.lvlNames[i],False,False); + } + } + if (!AddKeyType(xkb,info,&type)) { + info->errorCount++; + return False; + } + return True; +} + +static void +HandleKeyTypesFile( XkbFile * file, + XkbDescPtr xkb, + unsigned merge, + KeyTypesInfo * info) +{ +ParseCommon *stmt; + + info->name= uStringDup(file->name); + stmt= file->defs; + while (stmt) { + switch (stmt->stmtType) { + case StmtInclude: + if (!HandleIncludeKeyTypes((IncludeStmt *)stmt,xkb,info, + HandleKeyTypesFile)) + info->errorCount++; + break; + case StmtKeyTypeDef: + if (!HandleKeyTypeDef((KeyTypeDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + case StmtVarDef: + if (!HandleKeyTypeVar((VarDef *)stmt,xkb,info)) + info->errorCount++; + break; + case StmtVModDef: + if (!HandleVModDef((VModDef *)stmt,merge,&info->vmods)) + info->errorCount++; + break; + case StmtKeyAliasDef: + ERROR("Key type files may not include other declarations\n"); + ACTION("Ignoring definition of key alias\n"); + info->errorCount++; + break; + case StmtKeycodeDef: + ERROR("Key type files may not include other declarations\n"); + ACTION("Ignoring definition of key name\n"); + info->errorCount++; + break; + case StmtInterpDef: + ERROR("Key type files may not include other declarations\n"); + ACTION("Ignoring definition of symbol interpretation\n"); + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleKeyTypesFile\n", + stmt->stmtType); + break; + } + stmt= stmt->next; + if (info->errorCount>10) { +#ifdef NOISY + ERROR("Too many errors\n"); +#endif + ACTION1("Abandoning keytypes file \"%s\"\n",file->topName); + break; + } + } + return; +} + +static Bool +CopyDefToKeyType(XkbDescPtr xkb,XkbKeyTypePtr type,KeyTypeInfo *def) +{ +register int i; +PreserveInfo *pre; + + for (pre=def->preserve;pre!=NULL;pre=(PreserveInfo *)pre->defs.next) { + XkbKTMapEntryPtr match; + XkbKTMapEntryRec tmp; + tmp.mods.real_mods= pre->indexMods; + tmp.mods.vmods= pre->indexVMods; + tmp.level= 0; + AddMapEntry(xkb,def,&tmp,False,False); + match= FindMatchingMapEntry(def,pre->indexMods,pre->indexVMods); + if (!match) { + WSGO("Couldn't find matching entry for preserve\n"); + ACTION("Aborting\n"); + return False; + } + pre->matchingMapIndex= match-def->entries; + } + type->mods.real_mods= def->mask; + type->mods.vmods= def->vmask; + type->num_levels= def->numLevels; + type->map_count= def->nEntries; + type->map= def->entries; + if (def->preserve) { + type->preserve= uTypedCalloc(type->map_count,XkbModsRec); + if (!type->preserve) { + WARN("Couldn't allocate preserve array in CopyDefToKeyType\n"); + ACTION1("Preserve setting for type %s lost\n", + XkbAtomText(def->dpy,def->name,XkbMessage)); + } + else { + pre= def->preserve; + for (;pre!=NULL;pre=(PreserveInfo *)pre->defs.next) { + int ndx= pre->matchingMapIndex; + type->preserve[ndx].mask= pre->preMods; + type->preserve[ndx].real_mods= pre->preMods; + type->preserve[ndx].vmods= pre->preVMods; + } + } + } + else type->preserve= NULL; + type->name= (Atom)def->name; + if (def->szNames>0) { + type->level_names= uTypedCalloc(def->numLevels,Atom); + + /* assert def->szNames<=def->numLevels */ + for (i=0;iszNames;i++) { + type->level_names[i]= (Atom)def->lvlNames[i]; + } + } + else { + type->level_names= NULL; + } + + def->nEntries= def->szEntries= 0; + def->entries= NULL; + return XkbComputeEffectiveMap(xkb,type,NULL); +} + +Bool +CompileKeyTypes(XkbFile *file,XkbFileInfo *result,unsigned merge) +{ +KeyTypesInfo info; +XkbDescPtr xkb; + + xkb= result->xkb; + InitKeyTypesInfo(&info,xkb,NULL); + info.fileID= file->id; + HandleKeyTypesFile(file,xkb,merge,&info); + + if (info.errorCount==0) { + register int i; + register KeyTypeInfo *def; + register XkbKeyTypePtr type,next; + + if (info.name!=None) { + if (XkbAllocNames(xkb,XkbTypesNameMask,0,0)==Success) + xkb->names->types= XkbInternAtom(xkb->dpy,info.name,False); + else { + WSGO("Couldn't allocate space for types name\n"); + ACTION2("Name \"%s\" (from %s) NOT assigned\n",scanFile, + info.name); + } + } + i= info.nTypes; + if ((info.stdPresent&XkbOneLevelMask)==0) + i++; + if ((info.stdPresent&XkbTwoLevelMask)==0) + i++; + if ((info.stdPresent&XkbKeypadMask)==0) + i++; + if ((info.stdPresent&XkbAlphabeticMask)==0) + i++; + if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) { + WSGO("Couldn't allocate client map\n"); + ACTION("Exiting\n"); + return False; + } + xkb->map->num_types= i; + if (XkbAllRequiredTypes&(~info.stdPresent)) { + unsigned missing,keypadVMod; + + missing= XkbAllRequiredTypes&(~info.stdPresent); + keypadVMod= FindKeypadVMod(xkb); + if (XkbInitCanonicalKeyTypes(xkb,missing,keypadVMod)!=Success) { + WSGO("Couldn't initialize canonical key types\n"); + ACTION("Exiting\n"); + return False; + } + if (missing&XkbOneLevelMask) + xkb->map->types[XkbOneLevelIndex].name= tok_ONE_LEVEL; + if (missing&XkbTwoLevelMask) + xkb->map->types[XkbTwoLevelIndex].name= tok_TWO_LEVEL; + if (missing&XkbAlphabeticMask) + xkb->map->types[XkbAlphabeticIndex].name= tok_ALPHABETIC; + if (missing&XkbKeypadMask) + xkb->map->types[XkbKeypadIndex].name= tok_KEYPAD; + } + next= &xkb->map->types[XkbLastRequiredType+1]; + for (i=0,def=info.types;iname==tok_ONE_LEVEL) + type= &xkb->map->types[XkbOneLevelIndex]; + else if (def->name==tok_TWO_LEVEL) + type= &xkb->map->types[XkbTwoLevelIndex]; + else if (def->name==tok_ALPHABETIC) + type= &xkb->map->types[XkbAlphabeticIndex]; + else if (def->name==tok_KEYPAD) + type= &xkb->map->types[XkbKeypadIndex]; + else type= next++; + DeleteLevel1MapEntries(def); + if (!CopyDefToKeyType(xkb,type,def)) + return False; + def= (KeyTypeInfo *)def->defs.next; + } + return True; + } + return False; +} + diff --git a/xkbcomp/listing.c b/xkbcomp/listing.c new file mode 100644 index 0000000..cc887b8 --- /dev/null +++ b/xkbcomp/listing.c @@ -0,0 +1,462 @@ +/* $Xorg: listing.c,v 1.5 2001/02/09 02:05:49 xorgcvs Exp $ */ +/************************************************************ + Copyright 1996 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/*********************************************************** + +Copyright 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +******************************************************************/ +/* $XFree86: xc/programs/xkbcomp/listing.c,v 3.9 2001/12/14 20:01:57 dawes Exp $ */ + + +#include +#include +#include +#include +#include + +#if defined(sgi) +#include +#endif + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR listingDebug +#include "xkbcomp.h" +#include +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include +#else +#define _POSIX_SOURCE +#include +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#ifdef WIN32 +#define PATH_MAX 512 +#else +#include +#endif +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + +#ifdef WIN32 +#include +#define FileName(file) file.cFileName +#undef TEXT +#undef ALTERNATE +#else +#define FileName(file) file->d_name +#ifndef X_NOT_POSIX +#include +#else +#ifdef SYSV +#include +#else +#ifdef USG +#include +#else +#include +#ifndef dirent +#define dirent direct +#endif +#endif +#endif +#endif +#endif + +#include "xkbpath.h" +#include "parseutils.h" +#include "misc.h" +#include "tokens.h" +#include + +#define lowbit(x) ((x) & (-(x))) + +static int szListing= 0; +static int nListed= 0; +static int nFilesListed= 0; + +typedef struct _Listing { + char * file; + char * map; +} Listing; + +static int szMapOnly; +static int nMapOnly; +static char ** mapOnly; + +static Listing * list= NULL; + +/***====================================================================***/ + +int +AddMapOnly(char *map) +{ + if (nMapOnly>=szMapOnly) { + if (szMapOnly<1) szMapOnly= 5; + else szMapOnly*= 2; + mapOnly= uTypedRealloc(list,szMapOnly,char *); + if (!mapOnly) { + WSGO("Couldn't allocate list of maps\n"); + return 0; + } + } + mapOnly[nMapOnly++]= map; + return 1; +} + +int +AddListing(char *file,char *map) +{ + if (nListed>=szListing) { + if (szListing<1) szListing= 10; + else szListing*= 2; + list= uTypedRealloc(list,szListing,Listing); + if (!list) { + WSGO("Couldn't allocate list of files and maps\n"); + ACTION("Exiting\n"); + exit(1); + } + } + + list[nListed].file= file; + list[nListed].map= map; + nListed++; + if (file!=NULL) + nFilesListed++; + return 1; +} + +/***====================================================================***/ + +static void +ListFile(FILE *outFile,char *fileName,XkbFile *map) +{ +register unsigned flags; +char * mapName; + + flags= map->flags; + if ((flags&XkbLC_Hidden)&&(!(verboseLevel&WantHiddenMaps))) + return; + if ((flags&XkbLC_Partial)&&(!(verboseLevel&WantPartialMaps))) + return; + if (verboseLevel&WantLongListing) { + fprintf(outFile,(flags&XkbLC_Hidden)?"h":"-"); + fprintf(outFile,(flags&XkbLC_Default)?"d":"-"); + fprintf(outFile,(flags&XkbLC_Partial)?"p":"-"); + fprintf(outFile,"----- "); + if (map->type==XkmSymbolsIndex) { + fprintf(outFile,(flags&XkbLC_AlphanumericKeys)?"a":"-"); + fprintf(outFile,(flags&XkbLC_ModifierKeys)?"m":"-"); + fprintf(outFile,(flags&XkbLC_KeypadKeys)?"k":"-"); + fprintf(outFile,(flags&XkbLC_FunctionKeys)?"f":"-"); + fprintf(outFile,(flags&XkbLC_AlternateGroup)?"g":"-"); + fprintf(outFile,"--- "); + } + else fprintf(outFile,"-------- "); + } + mapName= map->name; + if ((!(verboseLevel&WantFullNames))&&((flags&XkbLC_Default)!=0)) + mapName= NULL; + if (dirsToStrip>0) { + char *tmp,*last; + int i; + for (i=0,tmp=last=fileName;(i9) + fprintf(stderr,"should list:\n"); +#endif + for (i=0;i9) { + fprintf(stderr,"%s(%s)\n",(list[i].file?list[i].file:"*"), + (list[i].map?list[i].map:"*")); + } +#endif + oldWarningLevel= warningLevel; + warningLevel= 0; + if (list[i].file) { + struct stat sbuf; + + if (stat(list[i].file,&sbuf)<0) { + if (oldWarningLevel>5) + WARN1("Couldn't open \"%s\"\n",list[i].file); + continue; + } + if (S_ISDIR(sbuf.st_mode)) { + if (verboseLevel&ListRecursive) + AddDirectory(list[i].file,NULL,NULL,NULL); + continue; + } + + inputFile= fopen(list[i].file,"r"); + if (!inputFile) { + if (oldWarningLevel>5) + WARN1("Couldn't open \"%s\"\n",list[i].file); + continue; + } + setScanState(list[i].file, 1); + if (XKBParseFile(inputFile,&rtrn)&&(rtrn!=NULL)) { + mapName= list[i].map; + mapToUse= rtrn; + for (;mapToUse;mapToUse= (XkbFile *)mapToUse->common.next) { + if (!MapMatches(mapToUse->name,mapName)) + continue; + ListFile(outFile,list[i].file,mapToUse); + } + } + fclose(inputFile); + } + warningLevel= oldWarningLevel; + } + return 1; +} + diff --git a/xkbcomp/misc.c b/xkbcomp/misc.c new file mode 100644 index 0000000..1d6f7b4 --- /dev/null +++ b/xkbcomp/misc.c @@ -0,0 +1,501 @@ +/* $Xorg: misc.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/misc.c,v 3.4 2001/01/17 23:45:44 dawes Exp $ */ + +#include "xkbcomp.h" +#include "xkbpath.h" +#include "tokens.h" +#include "keycodes.h" +#include "misc.h" +#include +#include "parseutils.h" + +#include + +/***====================================================================***/ + +Bool +ProcessIncludeFile( IncludeStmt * stmt, + unsigned file_type, + XkbFile ** file_rtrn, + unsigned * merge_rtrn) +{ +FILE *file; +XkbFile *rtrn,*mapToUse; +char oldFile[1024]; +int oldLine = lineNum; + + rtrn= XkbFindFileInCache(stmt->file,file_type,&stmt->path); + if (rtrn==NULL) { + file= XkbFindFileInPath(stmt->file,file_type,&stmt->path); + if (file==NULL) { + ERROR2("Can't find file \"%s\" for %s include\n",stmt->file, + XkbDirectoryForInclude(file_type)); + ACTION("Exiting\n"); + return False; + } + strcpy(oldFile,scanFile); + oldLine= lineNum; + setScanState(stmt->file,1); + if (debugFlags&2) + INFO1("About to parse include file %s\n",stmt->file); + if ((XKBParseFile(file,&rtrn)==0)||(rtrn==NULL)) { + setScanState(oldFile,oldLine); + ERROR1("Error interpreting include file \"%s\"\n",stmt->file); + ACTION("Exiting\n"); + fclose(file); + return False; + } + fclose(file); + XkbAddFileToCache(stmt->file,file_type,stmt->path,rtrn); + } + mapToUse= rtrn; + if (stmt->map!=NULL) { + while ((mapToUse)&&((!uStringEqual(mapToUse->name,stmt->map))|| + (mapToUse->type!=file_type))) { + mapToUse= (XkbFile *)mapToUse->common.next; + } + if (!mapToUse) { + ERROR3("No %s named \"%s\" in the include file \"%s\"\n", + XkbConfigText(file_type,XkbMessage), + stmt->map,stmt->file); + ACTION("Exiting\n"); + return False; + } + } + else if ((rtrn->common.next!=NULL)&&(warningLevel>5)) { + WARN1("No map in include statement, but \"%s\" contains several\n", + stmt->file); + ACTION1("Using first defined map, \"%s\"\n",rtrn->name); + } + setScanState(oldFile,oldLine); + if (mapToUse->type!=file_type) { + ERROR2("Include file wrong type (expected %s, got %s)\n", + XkbConfigText(file_type,XkbMessage), + XkbConfigText(mapToUse->type,XkbMessage)); + ACTION1("Include file \"%s\" ignored\n",stmt->file); + return False; + } + /* FIXME: we have to check recursive includes here (or somewhere) */ + + mapToUse->compiled= True; + *file_rtrn= mapToUse; + *merge_rtrn= stmt->merge; + return True; +} + +/***====================================================================***/ + +int +ReportNotArray(char *type,char *field,char *name) +{ + ERROR2("The %s %s field is not an array\n",type,field); + ACTION1("Ignoring illegal assignment in %s\n",name); + return False; +} + +int +ReportShouldBeArray(char *type,char *field,char *name) +{ + ERROR2("Missing subscript for %s %s\n",type,field); + ACTION1("Ignoring illegal assignment in %s\n",name); + return False; +} + +int +ReportBadType(char *type,char *field,char *name,char *wanted) +{ + ERROR3("The %s %s field must be a %s\n",type,field,wanted); + ACTION1("Ignoring illegal assignment in %s\n",name); + return False; +} + +int +ReportBadIndexType(char *type,char *field,char *name,char *wanted) +{ + ERROR3("Index for the %s %s field must be a %s\n",type,field,wanted); + ACTION1("Ignoring assignment to illegal field in %s\n",name); + return False; +} + +int +ReportBadField(char *type,char *field,char *name) +{ + ERROR3("Unknown %s field %s in %s\n",type,field,name); + ACTION1("Ignoring assignment to unknown field in %s\n",name); + return False; +} + +int +ReportMultipleDefs(char *type,char *field,char *name) +{ + WARN3("Multiple definitions of %s in %s \"%s\"\n",field,type,name); + ACTION("Using last definition\n"); + return False; +} + +/***====================================================================***/ + +Bool +UseNewField( unsigned field, + CommonInfo * oldDefs, + CommonInfo * newDefs, + unsigned * pCollide) +{ +Bool useNew; + + useNew= False; + if (oldDefs->defined&field) { + if (newDefs->defined&field) { + if (((oldDefs->fileID==newDefs->fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + *pCollide|= field; + } + if (newDefs->merge!=MergeAugment) + useNew= True; + } + } + else if (newDefs->defined&field) + useNew= True; + return useNew; +} + +Bool +MergeNewField( unsigned field, + CommonInfo * oldDefs, + CommonInfo * newDefs, + unsigned * pCollide) +{ + if ((oldDefs->defined&field)&&(newDefs->defined&field)) { + if (((oldDefs->fileID==newDefs->fileID)&&(warningLevel>0))|| + (warningLevel>9)) { + *pCollide|= field; + } + if (newDefs->merge==MergeAugment) + return True; + } + return False; +} + +XPointer +ClearCommonInfo(CommonInfo *cmn) +{ + if (cmn!=NULL) { + CommonInfo *this,*next; + for (this=cmn;this!=NULL;this=next) { + next= this->next; + uFree(this); + } + } + return NULL; +} + +XPointer +AddCommonInfo(CommonInfo *old,CommonInfo *new) +{ +CommonInfo * first; + + first= old; + while ( old && old->next ) { + old= old->next; + } + new->next= NULL; + if (old) { + old->next= new; + return (XPointer)first; + } + return (XPointer)new; +} + +/***====================================================================***/ + +typedef struct _KeyNameDesc { + KeySym level1; + KeySym level2; + char name[5]; + Bool used; +} KeyNameDesc; + +KeyNameDesc dfltKeys[] = { + { XK_Escape, NoSymbol, "ESC\0" }, + { XK_quoteleft, XK_asciitilde, "TLDE" }, + { XK_1, XK_exclam, "AE01" }, + { XK_2, XK_at, "AE02" }, + { XK_3, XK_numbersign, "AE03" }, + { XK_4, XK_dollar, "AE04" }, + { XK_5, XK_percent, "AE05" }, + { XK_6, XK_asciicircum, "AE06" }, + { XK_7, XK_ampersand, "AE07" }, + { XK_8, XK_asterisk, "AE08" }, + { XK_9, XK_parenleft, "AE09" }, + { XK_0, XK_parenright, "AE10" }, + { XK_minus, XK_underscore, "AE11" }, + { XK_equal, XK_plus, "AE12" }, + { XK_BackSpace, NoSymbol, "BKSP" }, + { XK_Tab, NoSymbol, "TAB\0" }, + { XK_q, XK_Q, "AD01" }, + { XK_w, XK_W, "AD02" }, + { XK_e, XK_E, "AD03" }, + { XK_r, XK_R, "AD04" }, + { XK_t, XK_T, "AD05" }, + { XK_y, XK_Y, "AD06" }, + { XK_u, XK_U, "AD07" }, + { XK_i, XK_I, "AD08" }, + { XK_o, XK_O, "AD09" }, + { XK_p, XK_P, "AD10" }, + { XK_bracketleft, XK_braceleft, "AD11" }, + { XK_bracketright,XK_braceright, "AD12" }, + { XK_Return, NoSymbol, "RTRN" }, + { XK_Caps_Lock, NoSymbol, "CAPS" }, + { XK_a, XK_A, "AC01" }, + { XK_s, XK_S, "AC02" }, + { XK_d, XK_D, "AC03" }, + { XK_f, XK_F, "AC04" }, + { XK_g, XK_G, "AC05" }, + { XK_h, XK_H, "AC06" }, + { XK_j, XK_J, "AC07" }, + { XK_k, XK_K, "AC08" }, + { XK_l, XK_L, "AC09" }, + { XK_semicolon, XK_colon, "AC10" }, + { XK_quoteright, XK_quotedbl, "AC11" }, + { XK_Shift_L, NoSymbol, "LFSH" }, + { XK_z, XK_Z, "AB01" }, + { XK_x, XK_X, "AB02" }, + { XK_c, XK_C, "AB03" }, + { XK_v, XK_V, "AB04" }, + { XK_b, XK_B, "AB05" }, + { XK_n, XK_N, "AB06" }, + { XK_m, XK_M, "AB07" }, + { XK_comma, XK_less, "AB08" }, + { XK_period, XK_greater, "AB09" }, + { XK_slash, XK_question, "AB10" }, + { XK_backslash, XK_bar, "BKSL" }, + { XK_Control_L, NoSymbol, "LCTL" }, + { XK_space, NoSymbol, "SPCE" }, + { XK_Shift_R, NoSymbol, "RTSH" }, + { XK_Alt_L, NoSymbol, "LALT" }, + { XK_space, NoSymbol, "SPCE" }, + { XK_Control_R, NoSymbol, "RCTL" }, + { XK_Alt_R, NoSymbol, "RALT" }, + { XK_F1, NoSymbol, "FK01" }, + { XK_F2, NoSymbol, "FK02" }, + { XK_F3, NoSymbol, "FK03" }, + { XK_F4, NoSymbol, "FK04" }, + { XK_F5, NoSymbol, "FK05" }, + { XK_F6, NoSymbol, "FK06" }, + { XK_F7, NoSymbol, "FK07" }, + { XK_F8, NoSymbol, "FK08" }, + { XK_F9, NoSymbol, "FK09" }, + { XK_F10, NoSymbol, "FK10" }, + { XK_F11, NoSymbol, "FK11" }, + { XK_F12, NoSymbol, "FK12" }, + { XK_Print, NoSymbol, "PRSC" }, + { XK_Scroll_Lock, NoSymbol, "SCLK" }, + { XK_Pause, NoSymbol, "PAUS" }, + { XK_Insert, NoSymbol, "INS\0" }, + { XK_Home, NoSymbol, "HOME" }, + { XK_Prior, NoSymbol, "PGUP" }, + { XK_Delete, NoSymbol, "DELE" }, + { XK_End, NoSymbol, "END" }, + { XK_Next, NoSymbol, "PGDN" }, + { XK_Up, NoSymbol, "UP\0\0" }, + { XK_Left, NoSymbol, "LEFT" }, + { XK_Down, NoSymbol, "DOWN" }, + { XK_Right, NoSymbol, "RGHT" }, + { XK_Num_Lock, NoSymbol, "NMLK" }, + { XK_KP_Divide, NoSymbol, "KPDV" }, + { XK_KP_Multiply, NoSymbol, "KPMU" }, + { XK_KP_Subtract, NoSymbol, "KPSU" }, + { NoSymbol, XK_KP_7, "KP7\0" }, + { NoSymbol, XK_KP_8, "KP8\0" }, + { NoSymbol, XK_KP_9, "KP9\0" }, + { XK_KP_Add, NoSymbol, "KPAD" }, + { NoSymbol, XK_KP_4, "KP4\0" }, + { NoSymbol, XK_KP_5, "KP5\0" }, + { NoSymbol, XK_KP_6, "KP6\0" }, + { NoSymbol, XK_KP_1, "KP1\0" }, + { NoSymbol, XK_KP_2, "KP2\0" }, + { NoSymbol, XK_KP_3, "KP3\0" }, + { XK_KP_Enter, NoSymbol, "KPEN" }, + { NoSymbol, XK_KP_0, "KP0\0" }, + { XK_KP_Delete, NoSymbol, "KPDL" }, + { XK_less, XK_greater, "LSGT" }, + { XK_KP_Separator,NoSymbol, "KPCO" }, + { XK_Find, NoSymbol, "FIND" }, + { NoSymbol, NoSymbol, "\0\0\0\0" } +}; + +Status +ComputeKbdDefaults(XkbDescPtr xkb) +{ +Status rtrn; +register int i,tmp,nUnknown; +KeyNameDesc * name; +KeySym * syms; + + if ((xkb->names==NULL)||(xkb->names->keys==NULL)) { + if ((rtrn=XkbAllocNames(xkb,XkbKeyNamesMask,0,0))!=Success) + return rtrn; + } + for (name=dfltKeys;(name->name[0]!='\0');name++) { + name->used= False; + } + nUnknown= 0; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + tmp= XkbKeyNumSyms(xkb,i); + if ((xkb->names->keys[i].name[0]=='\0')&&(tmp>0)) { + tmp= XkbKeyGroupsWidth(xkb,i); + syms= XkbKeySymsPtr(xkb,i); + for (name=dfltKeys;(name->name[0]!='\0');name++) { + Bool match= True; + if (((name->level1!=syms[0])&&(name->level1!=NoSymbol))|| + ((name->level2!=NoSymbol)&&(tmp<2))|| + ((name->level2!=syms[1])&&(name->level2!=NoSymbol))) { + match= False; + } + if (match) { + if (!name->used) { + memcpy(xkb->names->keys[i].name,name->name, + XkbKeyNameLength); + name->used= True; + } + else { + if (warningLevel>2) { + WARN1("Several keys match pattern for %s\n", + XkbKeyNameText(name->name,XkbMessage)); + ACTION2("Using for key %d\n",nUnknown,i); + } + sprintf(xkb->names->keys[i].name,"U%03d",nUnknown++); + } + break; + } + } + if (xkb->names->keys[i].name[0]=='\0') { + if (warningLevel>2) { + WARN1("Key %d does not match any defaults\n",i); + ACTION1("Using name \n",nUnknown); + sprintf(xkb->names->keys[i].name,"U%03d",nUnknown++); + } + } + } + } + return Success; +} + +Bool +FindNamedKey( XkbDescPtr xkb, + unsigned long name, + unsigned int * kc_rtrn, + Bool use_aliases, + Bool create, + int start_from) +{ +register unsigned n; + + if (start_frommin_key_code) { + start_from= xkb->min_key_code; + } + else if (start_from>xkb->max_key_code) { + return False; + } + + *kc_rtrn= 0; /* some callers rely on this */ + if (xkb&&xkb->names&&xkb->names->keys) { + for (n=start_from;n<=xkb->max_key_code;n++) { + unsigned long tmp; + tmp= KeyNameToLong(xkb->names->keys[n].name); + if (tmp==name) { + *kc_rtrn= n; + return True; + } + } + if (use_aliases) { + unsigned long new_name; + if (FindKeyNameForAlias(xkb,name,&new_name)) + return FindNamedKey(xkb,new_name,kc_rtrn,False,create,0); + } + } + if (create) { + if ((!xkb->names)||(!xkb->names->keys)) { + if (xkb->min_key_codemin_key_code= XkbMinLegalKeyCode; + xkb->max_key_code= XkbMaxLegalKeyCode; + } + if (XkbAllocNames(xkb,XkbKeyNamesMask,0,0)!=Success) { + if (warningLevel>0) { + WARN("Couldn't allocate key names in FindNamedKey\n"); + ACTION1("Key \"%s\" not automatically created\n", + longText(name,XkbMessage)); + } + return False; + } + } + for (n=xkb->min_key_code;n<=xkb->max_key_code;n++) { + if (xkb->names->keys[n].name[0]=='\0') { + char buf[XkbKeyNameLength+1]; + LongToKeyName(name,buf); + memcpy(xkb->names->keys[n].name,buf,XkbKeyNameLength); + *kc_rtrn= n; + return True; + } + } + } + return False; +} + +Bool +FindKeyNameForAlias(XkbDescPtr xkb,unsigned long lname,unsigned long *real_name) +{ +register int i; +char name[XkbKeyNameLength+1]; + + if (xkb&&xkb->geom&&xkb->geom->key_aliases) { + XkbKeyAliasPtr a; + a= xkb->geom->key_aliases; + LongToKeyName(lname,name); + name[XkbKeyNameLength]= '\0'; + for (i=0;igeom->num_key_aliases;i++,a++) { + if (strncmp(name,a->alias,XkbKeyNameLength)==0) { + *real_name= KeyNameToLong(a->real); + return True; + } + } + } + if (xkb&&xkb->names&&xkb->names->key_aliases) { + XkbKeyAliasPtr a; + a= xkb->names->key_aliases; + LongToKeyName(lname,name); + name[XkbKeyNameLength]= '\0'; + for (i=0;inames->num_key_aliases;i++,a++) { + if (strncmp(name,a->alias,XkbKeyNameLength)==0) { + *real_name= KeyNameToLong(a->real); + return True; + } + } + } + return False; +} diff --git a/xkbcomp/misc.h b/xkbcomp/misc.h new file mode 100644 index 0000000..5546169 --- /dev/null +++ b/xkbcomp/misc.h @@ -0,0 +1,126 @@ +/* $Xorg: misc.h,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef MISC_H +#define MISC_H 1 + +typedef struct _CommonInfo { + unsigned short defined; + unsigned char fileID; + unsigned char merge; + struct _CommonInfo * next; +} CommonInfo; + +extern Bool UseNewField( + unsigned /* field */, + CommonInfo * /* oldDefs */, + CommonInfo * /* newDefs */, + unsigned * /* pCollide */ +); + +extern Bool MergeNewField( + unsigned /* field */, + CommonInfo * /* oldDefs */, + CommonInfo * /* newDefs */, + unsigned * /* pCollide */ +); + +extern XPointer ClearCommonInfo( + CommonInfo * /* cmn */ +); + +extern XPointer AddCommonInfo( + CommonInfo * /* old */, + CommonInfo * /* new */ +); + +extern int ReportNotArray( + char * /* type */, + char * /* field */, + char * /* name */ +); + +extern int ReportShouldBeArray( + char * /* type */, + char * /* field */, + char * /* name */ +); + +extern int ReportBadType( + char * /* type */, + char * /* field */, + char * /* name */, + char * /* wanted */ +); + +extern int ReportBadIndexType( + char * /* type */, + char * /* field */, + char * /* name */, + char * /* wanted */ +); + +extern int ReportBadField( + char * /* type */, + char * /* field */, + char * /* name */ +); + +extern int ReportMultipleDefs( + char * /* type */, + char * /* field */, + char * /* which */ +); + +extern Bool ProcessIncludeFile( + IncludeStmt * /* stmt */, + unsigned /* file_type */, + XkbFile ** /* file_rtrn */, + unsigned * /* merge_rtrn */ +); + +extern Status ComputeKbdDefaults( + XkbDescPtr /* xkb */ +); + +extern Bool FindNamedKey( + XkbDescPtr /* xkb */, + unsigned long /* name */, + unsigned int * /* kc_rtrn */, + Bool /* use_aliases */, + Bool /* create */, + int /* start_from */ +); + +extern Bool FindKeyNameForAlias( + XkbDescPtr /* xkb */, + unsigned long /* lname */, + unsigned long * /* real_name */ +); + +#endif /* MISC_H */ diff --git a/xkbcomp/mkinstalldirs b/xkbcomp/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xkbcomp/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xkbcomp/parseutils.c b/xkbcomp/parseutils.c new file mode 100644 index 0000000..bae18f9 --- /dev/null +++ b/xkbcomp/parseutils.c @@ -0,0 +1,748 @@ +/* $Xorg: parseutils.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR parseDebug +#include "parseutils.h" +#include "xkbpath.h" +#include +#include +#include + +XkbFile *rtrnValue; + +ParseCommon * +AppendStmt(ParseCommon *to,ParseCommon *append) +{ +ParseCommon *start= to; + + if (append==NULL) + return to; + while ((to!=NULL) && (to->next!=NULL)) { + to= to->next; + } + if (to) { + to->next= append; + return start; + } + return append; +} + +ExprDef * +ExprCreate(unsigned op,unsigned type) +{ +ExprDef *expr; + expr= uTypedAlloc(ExprDef); + if (expr) { + expr->common.stmtType= StmtExpr; + expr->common.next= NULL; + expr->op= op; + expr->type= type; + } + else { + FATAL("Couldn't allocate expression in parser\n"); + /* NOTREACHED */ + } + return expr; +} + +ExprDef * +ExprCreateUnary(unsigned op,unsigned type,ExprDef *child) +{ +ExprDef *expr; + expr= uTypedAlloc(ExprDef); + if (expr) { + expr->common.stmtType= StmtExpr; + expr->common.next= NULL; + expr->op= op; + expr->type= type; + expr->value.child= child; + } + else { + FATAL("Couldn't allocate expression in parser\n"); + /* NOTREACHED */ + } + return expr; +} + +ExprDef * +ExprCreateBinary(unsigned op,ExprDef *left,ExprDef *right) +{ +ExprDef *expr; + expr= uTypedAlloc(ExprDef); + if (expr) { + expr->common.stmtType= StmtExpr; + expr->common.next= NULL; + expr->op= op; + if ((op==OpAssign)||(left->type==TypeUnknown)) + expr->type= right->type; + else if ((left->type==right->type)||(right->type==TypeUnknown)) + expr->type= left->type; + else expr->type= TypeUnknown; + expr->value.binary.left= left; + expr->value.binary.right= right; + } + else { + FATAL("Couldn't allocate expression in parser\n"); + /* NOTREACHED */ + } + return expr; +} + +KeycodeDef * +KeycodeCreate(char *name,ExprDef *value) +{ +KeycodeDef *def; + + def= uTypedAlloc(KeycodeDef); + if (def) { + def->common.stmtType= StmtKeycodeDef; + def->common.next= NULL; + strncpy(def->name,name,XkbKeyNameLength); + def->name[XkbKeyNameLength]= '\0'; + def->value= value; + } + else { + FATAL("Couldn't allocate key name definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +KeyAliasDef * +KeyAliasCreate(char *alias,char *real) +{ +KeyAliasDef *def; + + def= uTypedAlloc(KeyAliasDef); + if (def) { + def->common.stmtType= StmtKeyAliasDef; + def->common.next= NULL; + strncpy(def->alias,alias,XkbKeyNameLength); + def->alias[XkbKeyNameLength]= '\0'; + strncpy(def->real,real,XkbKeyNameLength); + def->real[XkbKeyNameLength]= '\0'; + } + else { + FATAL("Couldn't allocate key alias definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +VModDef * +VModCreate(Atom name,ExprDef *value) +{ +VModDef *def; + def= uTypedAlloc(VModDef); + if (def) { + def->common.stmtType= StmtVModDef; + def->common.next= NULL; + def->name= name; + def->value= value; + } + else { + FATAL("Couldn't allocate variable definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +VarDef * +VarCreate(ExprDef *name,ExprDef *value) +{ +VarDef *def; + def= uTypedAlloc(VarDef); + if (def) { + def->common.stmtType= StmtVarDef; + def->common.next= NULL; + def->name= name; + def->value= value; + } + else { + FATAL("Couldn't allocate variable definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +VarDef * +BoolVarCreate(Atom nameToken,unsigned set) +{ +ExprDef *name,*value; + + name= ExprCreate(ExprIdent,TypeUnknown); + name->value.str= nameToken; + value= ExprCreate(ExprValue,TypeBoolean); + value->value.uval= set; + return VarCreate(name,value); +} + +InterpDef * +InterpCreate(KeySym sym,ExprDef *match) +{ +InterpDef *def; + + def= uTypedAlloc(InterpDef); + if (def) { + def->common.stmtType= StmtInterpDef; + def->common.next= NULL; + def->sym= sym; + def->match= match; + } + else { + FATAL("Couldn't allocate interp definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +KeyTypeDef * +KeyTypeCreate(Atom name,VarDef *body) +{ +KeyTypeDef *def; + + def= uTypedAlloc(KeyTypeDef); + if (def) { + def->common.stmtType= StmtKeyTypeDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->name= name; + def->body= body; + } + else { + FATAL("Couldn't allocate key type definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +SymbolsDef * +SymbolsCreate(char *keyName,ExprDef *symbols) +{ +SymbolsDef *def; + + def= uTypedAlloc(SymbolsDef); + if (def) { + def->common.stmtType= StmtSymbolsDef; + def->common.next= NULL; + def->merge= MergeDefault; + bzero(def->keyName,5); + strncpy(def->keyName,keyName,4); + def->symbols= symbols; + } + else { + FATAL("Couldn't allocate symbols definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +GroupCompatDef * +GroupCompatCreate(int group,ExprDef *val) +{ +GroupCompatDef *def; + + def= uTypedAlloc(GroupCompatDef); + if (def) { + def->common.stmtType= StmtGroupCompatDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->group= group; + def->def= val; + } + else { + FATAL("Couldn't allocate group compat definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +ModMapDef * +ModMapCreate(Atom modifier,ExprDef *keys) +{ +ModMapDef *def; + + def= uTypedAlloc(ModMapDef); + if (def) { + def->common.stmtType= StmtModMapDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->modifier= modifier; + def->keys= keys; + } + else { + FATAL("Couldn't allocate mod mask definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +IndicatorMapDef * +IndicatorMapCreate(Atom name,VarDef *body) +{ +IndicatorMapDef *def; + + def= uTypedAlloc(IndicatorMapDef); + if (def) { + def->common.stmtType= StmtIndicatorMapDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->name= name; + def->body= body; + } + else { + FATAL("Couldn't allocate indicator map definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +IndicatorNameDef * +IndicatorNameCreate(int ndx,ExprDef *name,Bool virtual) +{ +IndicatorNameDef *def; + + def= uTypedAlloc(IndicatorNameDef); + if (def) { + def->common.stmtType= StmtIndicatorNameDef; + def->common.next= NULL; + def->merge= MergeDefault; + def->ndx= ndx; + def->name= name; + def->virtual= virtual; + } + else { + FATAL("Couldn't allocate indicator index definition in parser\n"); + /* NOTREACHED */ + } + return def; +} + +ExprDef * +ActionCreate(Atom name,ExprDef *args) +{ +ExprDef *act; + + act= uTypedAlloc(ExprDef); + if (act) { + act->common.stmtType= StmtExpr; + act->common.next= NULL; + act->op= ExprActionDecl; + act->value.action.name= name; + act->value.action.args= args; + return act; + } + FATAL("Couldn't allocate ActionDef in parser\n"); + return NULL; +} + +ExprDef * +CreateKeysymList(KeySym sym) +{ +ExprDef *def; + + def= ExprCreate(ExprKeysymList,TypeSymbols); + if (def) { + def->value.list.nSyms= 1; + def->value.list.szSyms= 2; + def->value.list.syms= uTypedCalloc(2,KeySym); + if (def->value.list.syms!=NULL) { + def->value.list.syms[0]= sym; + return def; + } + } + FATAL("Couldn't allocate expression for keysym list in parser\n"); + return NULL; +} + +ShapeDef * +ShapeDeclCreate(Atom name,OutlineDef *outlines) +{ +ShapeDef * shape; +OutlineDef * ol; + + shape= uTypedAlloc(ShapeDef); + if (shape!=NULL) { + bzero(shape,sizeof(ShapeDef)); + shape->common.stmtType= StmtShapeDef; + shape->common.next= NULL; + shape->merge= MergeDefault; + shape->name= name; + shape->nOutlines= 0; + shape->outlines= outlines; + for (ol=outlines;ol!=NULL;ol= (OutlineDef *)ol->common.next) { + if (ol->nPoints>0) + shape->nOutlines++; + } + } + return shape; +} + +OutlineDef * +OutlineCreate(Atom field,ExprDef *points) +{ +OutlineDef * outline; +ExprDef * pt; + + outline= uTypedAlloc(OutlineDef); + if (outline!=NULL) { + bzero(outline,sizeof(OutlineDef)); + outline->common.stmtType= StmtOutlineDef; + outline->common.next= NULL; + outline->field= field; + outline->nPoints= 0; + if (points->op==ExprCoord) { + for (pt=points;pt!=NULL;pt= (ExprDef *)pt->common.next) { + outline->nPoints++; + } + } + outline->points= points; + } + return outline; +} + +KeyDef * +KeyDeclCreate(char *name,ExprDef *expr) +{ +KeyDef * key; + + key= uTypedAlloc(KeyDef); + if (key!=NULL) { + bzero(key,sizeof(KeyDef)); + key->common.stmtType= StmtKeyDef; + key->common.next= NULL; + if (name) key->name= name; + else key->expr= expr; + } + return key; +} + +KeyDef * +KeyDeclMerge(KeyDef *into,KeyDef *from) +{ + into->expr= (ExprDef *)AppendStmt(&into->expr->common,&from->expr->common); + from->expr= NULL; + uFree(from); + return into; +} + +RowDef * +RowDeclCreate(KeyDef * keys) +{ +RowDef * row; +KeyDef * key; + + row= uTypedAlloc(RowDef); + if (row!=NULL) { + bzero(row,sizeof(RowDef)); + row->common.stmtType= StmtRowDef; + row->common.next= NULL; + row->nKeys= 0; + row->keys= keys; + for (key=keys;key!=NULL;key=(KeyDef *)key->common.next) { + if (key->common.stmtType==StmtKeyDef) + row->nKeys++; + } + } + return row; +} + +SectionDef * +SectionDeclCreate(Atom name,RowDef *rows) +{ +SectionDef * section; +RowDef * row; + + section= uTypedAlloc(SectionDef); + if (section!=NULL) { + bzero(section,sizeof(SectionDef)); + section->common.stmtType= StmtSectionDef; + section->common.next= NULL; + section->name= name; + section->nRows= 0; + section->rows= rows; + for (row=rows;row!=NULL;row=(RowDef *)row->common.next) { + if (row->common.stmtType==StmtRowDef) + section->nRows++; + } + } + return section; +} + +OverlayKeyDef * +OverlayKeyCreate(char * under,char *over) +{ +OverlayKeyDef * key; + + key= uTypedAlloc(OverlayKeyDef); + if (key!=NULL) { + bzero(key,sizeof(OverlayKeyDef)); + key->common.stmtType= StmtOverlayKeyDef; + strncpy(key->over,over,XkbKeyNameLength); + strncpy(key->under,under,XkbKeyNameLength); + if (over) uFree(over); + if (under) uFree(under); + } + return key; +} + +OverlayDef * +OverlayDeclCreate(Atom name,OverlayKeyDef *keys) +{ +OverlayDef * ol; +OverlayKeyDef * key; + + ol= uTypedAlloc(OverlayDef); + if (ol!=NULL) { + bzero(ol,sizeof(OverlayDef)); + ol->common.stmtType= StmtOverlayDef; + ol->name= name; + ol->keys= keys; + for (key=keys;key!=NULL;key=(OverlayKeyDef *)key->common.next) { + ol->nKeys++; + } + } + return ol; +} + +DoodadDef * +DoodadCreate(unsigned type,Atom name,VarDef *body) +{ +DoodadDef * doodad; + + doodad= uTypedAlloc(DoodadDef); + if (doodad!=NULL) { + bzero(doodad,sizeof(DoodadDef)); + doodad->common.stmtType= StmtDoodadDef; + doodad->common.next= NULL; + doodad->type= type; + doodad->name= name; + doodad->body= body; + } + return doodad; +} + +ExprDef * +AppendKeysymList(ExprDef *list,KeySym sym) +{ + if (list->value.list.nSyms>=list->value.list.szSyms) { + list->value.list.szSyms*=2; + list->value.list.syms= uTypedRecalloc(list->value.list.syms, + list->value.list.nSyms, + list->value.list.szSyms, + KeySym); + if (list->value.list.syms==NULL) { + FATAL("Couldn't resize list of symbols for append\n"); + return NULL; + } + } + list->value.list.syms[list->value.list.nSyms++]= sym; + return list; +} + +int +LookupKeysym(char *str,KeySym *sym_rtrn) +{ +KeySym sym; + + if ((!str)||(uStrCaseCmp(str,"any")==0)||(uStrCaseCmp(str,"nosymbol")==0)) { + *sym_rtrn= NoSymbol; + return 1; + } + else if ((uStrCaseCmp(str,"none")==0)||(uStrCaseCmp(str,"voidsymbol")==0)) { + *sym_rtrn= XK_VoidSymbol; + return 1; + } + sym= XStringToKeysym(str); + if (sym!=NoSymbol) { + *sym_rtrn= sym; + return 1; + } + return 0; +} + +IncludeStmt * +IncludeCreate(char *str,unsigned merge) +{ +IncludeStmt * incl,*first; +char * file,*map,*stmt,*tmp, *extra_data; +char nextop; +Bool haveSelf; + + haveSelf= False; + incl= first= NULL; + file= map= NULL; + tmp= str; + stmt= uStringDup(str); + while ((tmp)&&(*tmp)) { + if (XkbParseIncludeMap(&tmp,&file,&map,&nextop,&extra_data)) { + if ((file==NULL)&&(map==NULL)) { + if (haveSelf) + goto BAIL; + haveSelf= True; + } + if (first==NULL) + first= incl= uTypedAlloc(IncludeStmt); + else { + incl->next= uTypedAlloc(IncludeStmt); + incl= incl->next; + } + if (incl) { + incl->common.stmtType= StmtInclude; + incl->common.next= NULL; + incl->merge= merge; + incl->stmt= NULL; + incl->file= file; + incl->map= map; + incl->modifier= extra_data; + incl->path= NULL; + incl->next= NULL; + } + else { + WSGO("Allocation failure in IncludeCreate\n"); + ACTION("Using only part of the include\n"); + break; + } + if (nextop=='|') merge= MergeAugment; + else merge= MergeOverride; + } + else { + goto BAIL; + } + } + if (first) first->stmt= stmt; + else if (stmt) uFree(stmt); + return first; +BAIL: + ERROR1("Illegal include statement \"%s\"\n",stmt); + ACTION("Ignored\n"); + while (first) { + incl= first->next; + if (first->file) uFree(first->file); + if (first->map) uFree(first->map); + if (first->modifier) uFree(first->modifier); + if (first->path) uFree(first->path); + first->file= first->map= first->path= NULL; + uFree(first); + first= incl; + } + if (stmt) + uFree(stmt); + return NULL; +} + +#ifdef DEBUG +void +PrintStmtAddrs(ParseCommon *stmt) +{ + fprintf(stderr,"0x%x",stmt); + if (stmt) { + do { + fprintf(stderr,"->0x%x",stmt->next); + stmt= stmt->next; + } while (stmt); + } + fprintf(stderr,"\n"); +} +#endif + +static void +CheckDefaultMap(XkbFile *maps) +{ +XkbFile * dflt,*tmp; + + dflt= NULL; + for (tmp=maps,dflt=NULL;tmp!=NULL;tmp=(XkbFile *)tmp->common.next) { + if (tmp->flags&XkbLC_Default) { + if (dflt==NULL) + dflt= tmp; + else { + if (warningLevel>2) { + WARN1("Multiple default components in %s\n", + (scanFile?scanFile:"(unknown)")); + ACTION2("Using %s, ignoring %s\n", + (dflt->name?dflt->name:"(first)"), + (tmp->name?tmp->name:"(subsequent)")); + } + tmp->flags&= (~XkbLC_Default); + } + } + } + return; +} + +int +XKBParseFile(FILE *file,XkbFile **pRtrn) +{ + if (file) { + yyin= file; + rtrnValue= NULL; + if (yyparse()==0) { + *pRtrn= rtrnValue; + CheckDefaultMap(rtrnValue); + rtrnValue= NULL; + return 1; + } + *pRtrn= NULL; + return 0; + } + *pRtrn= NULL; + return 1; +} + +XkbFile * +CreateXKBFile(int type,char *name,ParseCommon *defs,unsigned flags) +{ +XkbFile * file; +static int fileID; + + file= uTypedAlloc(XkbFile); + if (file) { + XkbEnsureSafeMapName(name); + bzero(file,sizeof(XkbFile)); + file->type= type; + file->topName= uStringDup(name); + file->name= name; + file->defs= defs; + file->id= fileID++; + file->compiled= False; + file->flags= flags; + } + return file; +} + +unsigned +StmtSetMerge(ParseCommon *stmt,unsigned merge) +{ + if ((merge==MergeAltForm) && (stmt->stmtType!=StmtKeycodeDef)) { + yyerror("illegal use of 'alternate' merge mode"); + merge= MergeDefault; + } + return merge; +} diff --git a/xkbcomp/parseutils.h b/xkbcomp/parseutils.h new file mode 100644 index 0000000..2f29e9e --- /dev/null +++ b/xkbcomp/parseutils.h @@ -0,0 +1,248 @@ +/* $Xorg: parseutils.h,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef XKBPARSE_H +#define XKBPARSE_H 1 + +#ifndef DEBUG_VAR +#define DEBUG_VAR parseDebug +#endif + +#include "xkbcomp.h" + +extern char *scanStr; +extern int scanInt; +extern int lineNum; + +extern XkbFile *rtrnValue; + +#ifdef DEBUG +#define d(str) fprintf(stderr,"%s\n",str); +#define d1(str,a) fprintf(stderr,str,a); +#define d2(str,a,b) fprintf(stderr,str,a,b); +#else +#define d(str) +#define d1(str,a) +#define d2(str,a,b) +#endif + + +extern ParseCommon *AppendStmt( + ParseCommon * /* to */, + ParseCommon * /* append */ +); + +extern ExprDef *ExprCreate( + unsigned /* op */, + unsigned /* type */ +); + +extern ExprDef *ExprCreateUnary( + unsigned /* op */, + unsigned /* type */, + ExprDef * /* child */ +); + +extern ExprDef *ExprCreateBinary( + unsigned /* op */, + ExprDef * /* left */, + ExprDef * /* right */ +); + +extern KeycodeDef *KeycodeCreate( + char * /* name */, + ExprDef * /* value */ +); + +extern KeyAliasDef *KeyAliasCreate( + char * /* alias */, + char * /* real */ +); + +extern VModDef *VModCreate( + Atom /* name */, + ExprDef * /* value */ +); + +extern VarDef *VarCreate( + ExprDef * /* name */, + ExprDef * /* value */ +); + +extern VarDef *BoolVarCreate( + Atom /* nameToken */, + unsigned /* set */ +); + +extern InterpDef *InterpCreate( + KeySym /* sym */, + ExprDef * /* match */ +); + +extern KeyTypeDef *KeyTypeCreate( + Atom /* name */, + VarDef * /* body */ +); + +extern SymbolsDef *SymbolsCreate( + char * /* keyName */, + ExprDef * /* symbols */ +); + +extern GroupCompatDef *GroupCompatCreate( + int /* group */, + ExprDef * /* def */ +); + +extern ModMapDef *ModMapCreate( + Atom /* modifier */, + ExprDef * /* keys */ +); + +extern IndicatorMapDef *IndicatorMapCreate( + Atom /* name */, + VarDef * /* body */ +); + +extern IndicatorNameDef *IndicatorNameCreate( + int /* ndx */, + ExprDef * /* name */, + Bool /* virtual */ +); + +extern ExprDef *ActionCreate( + Atom /* name */, + ExprDef * /* args */ +); + +extern ExprDef *CreateKeysymList( + KeySym /* sym */ +); + +extern ShapeDef *ShapeDeclCreate( + Atom /* name */, + OutlineDef * /* outlines */ +); + +extern OutlineDef *OutlineCreate( + Atom /* field */, + ExprDef * /* points */ +); + +extern KeyDef *KeyDeclCreate( + char * /* name */, + ExprDef * /* expr */ +); + +extern KeyDef *KeyDeclMerge( + KeyDef * /* into */, + KeyDef * /* from */ +); + +extern RowDef *RowDeclCreate( + KeyDef * /* keys */ +); + +extern SectionDef *SectionDeclCreate( + Atom /* name */, + RowDef * /* rows */ +); + +extern OverlayKeyDef *OverlayKeyCreate( + char * /* under */, + char * /* over */ +); + +extern OverlayDef *OverlayDeclCreate( + Atom /* name */, + OverlayKeyDef * /* rows */ +); + +extern DoodadDef *DoodadCreate( + unsigned /* type */, + Atom /* name */, + VarDef * /* body */ +); + +extern ExprDef *AppendKeysymList( + ExprDef * /* list */, + KeySym /* sym */ +); + +extern int LookupKeysym( + char * /* str */, + KeySym * /* sym_rtrn */ +); + +extern IncludeStmt *IncludeCreate( + char * /* str */, + unsigned /* merge */ +); + +extern unsigned StmtSetMerge( + ParseCommon * /* stmt */, + unsigned /* merge */ +); + +#ifdef DEBUG +extern void PrintStmtAddrs( + ParseCommon * /* stmt */ +); +#endif + +extern int XKBParseFile( + FILE * /* file */, + XkbFile ** /* pRtrn */ +); + +extern XkbFile *CreateXKBFile( + int /* type */, + char * /* name */, + ParseCommon * /* defs */, + unsigned /* flags */ +); + +extern void yyerror( + char * /* s */ +); + +extern int yywrap( + void +); + +extern int yylex(void); +extern int yyparse(void); + +extern int setScanState( + char * /* file */, + int /* line */ +); + +extern FILE *yyin; + +#endif /* XKBPARSE_H */ diff --git a/xkbcomp/symbols.c b/xkbcomp/symbols.c new file mode 100644 index 0000000..75c2aaa --- /dev/null +++ b/xkbcomp/symbols.c @@ -0,0 +1,1921 @@ +/* $Xorg: symbols.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/symbols.c,v 3.15 2003/04/19 12:25:31 pascal Exp $ */ + +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" + +#include +#include +#include + +#include "expr.h" +#include "vmod.h" +#include "action.h" +#include "keycodes.h" +#include "misc.h" +#include "alias.h" + +extern Atom tok_ONE_LEVEL; +extern Atom tok_TWO_LEVEL; +extern Atom tok_KEYPAD; + +/***====================================================================***/ + +#define RepeatYes 1 +#define RepeatNo 0 +#define RepeatUndefined ~((unsigned)0) + +#define _Key_Syms (1<<0) +#define _Key_Acts (1<<1) +#define _Key_Repeat (1<<2) +#define _Key_Behavior (1<<3) +#define _Key_Type_Dflt (1<<4) +#define _Key_Types (1<<5) +#define _Key_GroupInfo (1<<6) +#define _Key_VModMap (1<<7) + +typedef struct _KeyInfo { + CommonInfo defs; + unsigned long name; + unsigned char groupInfo; + unsigned char typesDefined; + unsigned char symsDefined; + unsigned char actsDefined; + short numLevels[XkbNumKbdGroups]; + KeySym * syms[XkbNumKbdGroups]; + XkbAction * acts[XkbNumKbdGroups]; + Atom types[XkbNumKbdGroups]; + unsigned repeat; + XkbBehavior behavior; + unsigned short vmodmap; + unsigned long nameForOverlayKey; + unsigned long allowNone; + Atom dfltType; +} KeyInfo; + +static void +InitKeyInfo(KeyInfo *info) +{ +register int i; +static char dflt[4]= "*"; + + info->defs.defined= 0; + info->defs.fileID= 0; + info->defs.merge= MergeOverride; + info->defs.next= NULL; + info->name= KeyNameToLong(dflt); + info->groupInfo= 0; + info->typesDefined= info->symsDefined= info->actsDefined= 0; + for (i=0;inumLevels[i]= 0; + info->types[i]= None; + info->syms[i]= NULL; + info->acts[i]= NULL; + } + info->dfltType= None; + info->behavior.type= XkbKB_Default; + info->behavior.data= 0; + info->vmodmap= 0; + info->nameForOverlayKey= 0; + info->repeat= RepeatUndefined; + info->allowNone= 0; + return; +} + +static void +FreeKeyInfo(KeyInfo *info) +{ +register int i; + + info->defs.defined= 0; + info->defs.fileID= 0; + info->defs.merge= MergeOverride; + info->defs.next= NULL; + info->groupInfo= 0; + info->typesDefined= info->symsDefined= info->actsDefined= 0; + for (i=0;inumLevels[i]= 0; + info->types[i]= None; + if (info->syms[i]!=NULL) + uFree(info->syms[i]); + info->syms[i]= NULL; + if (info->acts[i]!=NULL) + uFree(info->acts[i]); + info->acts[i]= NULL; + } + info->dfltType= None; + info->behavior.type= XkbKB_Default; + info->behavior.data= 0; + info->vmodmap= 0; + info->nameForOverlayKey= 0; + info->repeat= RepeatUndefined; + return; +} + +static Bool +CopyKeyInfo(KeyInfo *old,KeyInfo *new,Bool clearOld) +{ +register int i; + + *new= *old; + new->defs.next= NULL; + if (clearOld) { + for (i=0;inumLevels[i]= 0; + old->syms[i]= NULL; + old->acts[i]= NULL; + } + } + else { + int width; + for (i=0;inumLevels[i]; + if (old->syms[i]!=NULL) { + new->syms[i]= uTypedCalloc(width,KeySym); + if (!new->syms[i]) { + new->syms[i]= NULL; + new->numLevels[i]= 0; + return False; + } + memcpy((char *)new->syms[i],(char *)old->syms[i], + width*sizeof(KeySym)); + } + if (old->acts[i]!=NULL) { + new->acts[i]= uTypedCalloc(width,XkbAction); + if (!new->acts[i]) { + new->acts[i]= NULL; + return False; + } + memcpy((char *)new->acts[i],(char *)old->acts[i], + width*sizeof(XkbAction)); + } + } + } + return True; +} + +/***====================================================================***/ + +typedef struct _ModMapEntry { + CommonInfo defs; + Bool haveSymbol; + int modifier; + union { + unsigned long keyName; + KeySym keySym; + } u; +} ModMapEntry; + +#define SYMBOLS_INIT_SIZE 110 +#define SYMBOLS_CHUNK 20 +typedef struct _SymbolsInfo { + char * name; + int errorCount; + unsigned fileID; + unsigned merge; + unsigned explicit_group; + unsigned groupInfo; + unsigned szKeys; + unsigned nKeys; + KeyInfo * keys; + KeyInfo dflt; + VModInfo vmods; + ActionInfo * action; + Atom groupNames[XkbNumKbdGroups]; + + ModMapEntry * modMap; + AliasInfo * aliases; +} SymbolsInfo; + +static void +InitSymbolsInfo(SymbolsInfo *info,XkbDescPtr xkb) +{ +register int i; + + tok_ONE_LEVEL= XkbInternAtom(NULL,"ONE_LEVEL",False); + tok_TWO_LEVEL= XkbInternAtom(NULL,"TWO_LEVEL",False); + tok_KEYPAD= XkbInternAtom(NULL,"KEYPAD",False); + info->name= NULL; + info->explicit_group= 0; + info->errorCount= 0; + info->fileID= 0; + info->merge= MergeOverride; + info->groupInfo= 0; + info->szKeys= SYMBOLS_INIT_SIZE; + info->nKeys= 0; + info->keys= uTypedCalloc(SYMBOLS_INIT_SIZE,KeyInfo); + info->modMap= NULL; + for (i=0;igroupNames[i]= None; + InitKeyInfo(&info->dflt); + InitVModInfo(&info->vmods,xkb); + info->action= NULL; + info->aliases= NULL; + return; +} + +static void +FreeSymbolsInfo(SymbolsInfo *info) +{ +register int i; + + if (info->name) + uFree(info->name); + info->name= NULL; + if (info->keys) { + for (i=0;inKeys;i++) { + FreeKeyInfo(&info->keys[i]); + } + uFree(info->keys); + info->keys= NULL; + } + if (info->modMap) { + ClearCommonInfo(&info->modMap->defs); + info->modMap= NULL; + } + if (info->aliases) { + ClearAliases(&info->aliases); + info->aliases= NULL; + } + bzero((char *)info,sizeof(SymbolsInfo)); + return; +} + +static Bool +ResizeKeyGroup( KeyInfo * key, + unsigned group, + unsigned atLeastSize, + Bool forceActions) +{ +Bool tooSmall; +unsigned newWidth; + + tooSmall= (key->numLevels[group]numLevels[group]; + + if ((key->syms[group]==NULL)||tooSmall) { + key->syms[group]= uTypedRecalloc(key->syms[group], + key->numLevels[group],newWidth, + KeySym); + if (!key->syms[group]) + return False; + } + if (((forceActions)&&(tooSmall||(key->acts[group]==NULL)))|| + (tooSmall&&(key->acts[group]!=NULL))) { + key->acts[group]= uTypedRecalloc(key->acts[group], + key->numLevels[group],newWidth, + XkbAction); + if (!key->acts[group]) + return False; + } + key->numLevels[group]= newWidth; + return True; +} + +static Bool +MergeKeyGroups( SymbolsInfo * info, + KeyInfo * into, + KeyInfo * from, + unsigned group) +{ +KeySym * resultSyms; +XkbAction * resultActs; +int resultWidth; +register int i; +Bool report,clobber; + + clobber= (from->defs.merge!=MergeAugment); + report= (warningLevel>9)|| + ((into->defs.fileID==from->defs.fileID)&&(warningLevel>0)); + if (into->numLevels[group]>=from->numLevels[group]) { + resultSyms= into->syms[group]; + resultActs= into->acts[group]; + resultWidth= into->numLevels[group]; + } + else { + resultSyms= from->syms[group]; + resultActs= from->acts[group]; + resultWidth= from->numLevels[group]; + } + if (resultSyms==NULL) { + resultSyms= uTypedCalloc(resultWidth,KeySym); + if (!resultSyms) { + WSGO("Could not allocate symbols for group merge\n"); + ACTION2("Group %d of key %s not merged\n",group, + longText(into->name,XkbMessage)); + return False; + } + } + if ((resultActs==NULL)&&(into->acts[group]||from->acts[group])) { + resultActs= uTypedCalloc(resultWidth,XkbAction); + if (!resultActs) { + WSGO("Could not allocate actions for group merge\n"); + ACTION2("Group %d of key %s not merged\n",group, + longText(into->name,XkbMessage)); + return False; + } + } + for (i=0;isyms[group] && (inumLevels[group])) + fromSym= from->syms[group][i]; + else fromSym= NoSymbol; + if (into->syms[group] && (inumLevels[group])) + toSym= into->syms[group][i]; + else toSym= NoSymbol; + if ((fromSym==NoSymbol)||(fromSym==toSym)) + resultSyms[i]= toSym; + else if (toSym==NoSymbol) + resultSyms[i]= fromSym; + else { + KeySym use,ignore; + if (clobber) { use= fromSym; ignore= toSym; } + else { use= toSym; ignore= fromSym; } + if (report) { + WARN3("Multiple symbols for level %d/group %d on key %s\n", + i+1,group+1,longText(into->name,XkbMessage)); + ACTION2("Using %s, ignoring %s\n",XkbKeysymText(use,XkbMessage), + XkbKeysymText(ignore,XkbMessage)); + } + resultSyms[i]= use; + } + if (resultActs!=NULL) { + XkbAction *fromAct,*toAct; + fromAct= (from->acts[group]?&from->acts[group][i]:NULL); + toAct= (into->acts[group]?&into->acts[group][i]:NULL); + if (((fromAct==NULL)||(fromAct->type==XkbSA_NoAction))&& + (toAct!=NULL)) { + resultActs[i]= *toAct; + } + else if (((toAct==NULL)||(toAct->type==XkbSA_NoAction))&& + (fromAct!=NULL)) { + resultActs[i]= *fromAct; + } + else { + XkbAction *use,*ignore; + if (clobber) { use= fromAct; ignore= toAct; } + else { use= toAct; ignore= fromAct; } + if (report) { + WARN3("Multiple actions for level %d/group %d on key %s\n", + i+1,group+1,longText(into->name,XkbMessage)); + ACTION2("Using %s, ignoring %s\n", + XkbActionTypeText(use->type,XkbMessage), + XkbActionTypeText(ignore->type,XkbMessage)); + } + resultActs[i]= *use; + } + } + } + if ((into->syms[group]!=NULL)&&(resultSyms!=into->syms[group])) + uFree(into->syms[group]); + if ((from->syms[group]!=NULL)&&(resultSyms!=from->syms[group])) + uFree(from->syms[group]); + if ((into->acts[group]!=NULL)&&(resultActs!=into->acts[group])) + uFree(into->acts[group]); + if ((from->acts[group]!=NULL)&&(resultActs!=from->acts[group])) + uFree(from->acts[group]); + into->numLevels[group]= resultWidth; + into->syms[group]= resultSyms; + from->syms[group]= NULL; + into->acts[group]= resultActs; + from->acts[group]= NULL; + into->symsDefined|= (1<symsDefined&= ~(1<actsDefined|= (1<actsDefined&= ~(1<defs.merge==MergeReplace) { + for (i=0;inumLevels[i]!=0) { + if (into->syms[i]) + uFree(into->syms[i]); + if (into->acts[i]) + uFree(into->acts[i]); + } + } + *into= *from; + bzero(from,sizeof(KeyInfo)); + return True; + } + report= ((warningLevel>9)|| + ((into->defs.fileID==from->defs.fileID)&&(warningLevel>0))); + for (i=0;inumLevels[i]>0) { + if (into->numLevels[i]==0) { + into->numLevels[i]= from->numLevels[i]; + into->syms[i]= from->syms[i]; + into->acts[i]= from->acts[i]; + into->symsDefined|= (1<syms[i]= NULL; + from->acts[i]= NULL; + from->numLevels[i]= 0; + from->symsDefined&= ~(1<syms[i]) into->defs.defined|= _Key_Syms; + if (into->acts[i]) into->defs.defined|= _Key_Acts; + } + else { + if (report) { + if (into->syms[i]) collide|= _Key_Syms; + if (into->acts[i]) collide|= _Key_Acts; + } + MergeKeyGroups(info,into,from,(unsigned)i); + } + } + if (from->types[i]!=None) { + if ((into->types[i]!=None)&&(report)&& + (into->types[i]!=from->types[i])) { + Atom use,ignore; + collide|= _Key_Types; + if (from->defs.merge!=MergeAugment) { + use= from->types[i]; + ignore= into->types[i]; + } + else { + use= into->types[i]; + ignore= from->types[i]; + } + WARN2("Multiple definitions for group %d type of key %s\n", + i,longText(into->name,XkbMessage)); + ACTION2("Using %s, ignoring %s\n", + XkbAtomText(NULL,use,XkbMessage), + XkbAtomText(NULL,ignore,XkbMessage)); + } + if ((from->defs.merge!=MergeAugment)||(into->types[i]==None)) { + into->types[i]= from->types[i]; + } + } + } + if (UseNewField(_Key_Behavior,&into->defs,&from->defs,&collide)) { + into->behavior= from->behavior; + into->nameForOverlayKey= from->nameForOverlayKey; + into->defs.defined|= _Key_Behavior; + } + if (UseNewField(_Key_VModMap,&into->defs,&from->defs,&collide)) { + into->vmodmap= from->vmodmap; + into->defs.defined|= _Key_VModMap; + } + if (UseNewField(_Key_Repeat,&into->defs,&from->defs,&collide)) { + into->repeat= from->repeat; + into->defs.defined|= _Key_Repeat; + } + if (UseNewField(_Key_Type_Dflt,&into->defs,&from->defs,&collide)) { + into->dfltType= from->dfltType; + into->defs.defined|= _Key_Type_Dflt; + } + if (UseNewField(_Key_GroupInfo,&into->defs,&from->defs,&collide)) { + into->groupInfo= from->groupInfo; + into->defs.defined|= _Key_GroupInfo; + } + if ( collide ) { + WARN1("Symbol map for key %s redefined\n", + longText(into->name,XkbMessage)); + ACTION1("Using %s definition for conflicting fields\n", + (from->defs.merge==MergeAugment?"first":"last")); + } + return True; +} + +static Bool +AddKeySymbols(SymbolsInfo *info,KeyInfo *key,XkbDescPtr xkb) +{ +register int i; +unsigned long real_name; + + for (i=0;inKeys;i++) { + if (info->keys[i].name==key->name) + return MergeKeys(info,&info->keys[i],key); + } + if(FindKeyNameForAlias(xkb, key->name, &real_name)) { + for (i=0;inKeys;i++) { + if (info->keys[i].name==real_name) + return MergeKeys(info,&info->keys[i],key); + } + } + if (info->nKeys>=info->szKeys) { + info->szKeys+= SYMBOLS_CHUNK; + info->keys= uTypedRecalloc(info->keys,info->nKeys,info->szKeys,KeyInfo); + if (!info->keys) { + WSGO("Could not allocate key symbols descriptions\n"); + ACTION("Some key symbols definitions may be lost\n"); + return False; + } + } + return CopyKeyInfo(key,&info->keys[info->nKeys++],True); +} + +static Bool +AddModMapEntry(SymbolsInfo *info,ModMapEntry *new) +{ +ModMapEntry * mm; +Bool clobber; + + clobber= (new->defs.merge!=MergeAugment); + for (mm=info->modMap;mm!=NULL;mm= (ModMapEntry *)mm->defs.next) { + if (new->haveSymbol&&mm->haveSymbol&&(new->u.keySym==mm->u.keySym)) { + unsigned use,ignore; + if (mm->modifier!=new->modifier) { + if (clobber) { + use= new->modifier; + ignore= mm->modifier; + } + else { + use= mm->modifier; + ignore= new->modifier; + } + ERROR1("%s added to symbol map for multiple modifiers\n", + XkbKeysymText(new->u.keySym,XkbMessage)); + ACTION2("Using %s, ignoring %s.\n", + XkbModIndexText(use,XkbMessage), + XkbModIndexText(ignore,XkbMessage)); + mm->modifier= use; + } + return True; + } + if ((!new->haveSymbol)&&(!mm->haveSymbol)&& + (new->u.keyName==mm->u.keyName)) { + unsigned use,ignore; + if (mm->modifier!=new->modifier) { + if (clobber) { + use= new->modifier; + ignore= mm->modifier; + } + else { + use= mm->modifier; + ignore= new->modifier; + } + ERROR1("Key %s added to map for multiple modifiers\n", + longText(new->u.keyName,XkbMessage)); + ACTION2("Using %s, ignoring %s.\n", + XkbModIndexText(use,XkbMessage), + XkbModIndexText(ignore,XkbMessage)); + mm->modifier= use; + } + return True; + } + } + mm= uTypedAlloc(ModMapEntry); + if (mm==NULL) { + WSGO("Could not allocate modifier map entry\n"); + ACTION1("Modifier map for %s will be incomplete\n", + XkbModIndexText(new->modifier,XkbMessage)); + return False; + } + *mm= *new; + mm->defs.next= &info->modMap->defs; + info->modMap= mm; + return True; +} + +/***====================================================================***/ + +static void +MergeIncludedSymbols(SymbolsInfo *into,SymbolsInfo *from, + unsigned merge,XkbDescPtr xkb) +{ +register int i; +KeyInfo * key; + + if (from->errorCount>0) { + into->errorCount+= from->errorCount; + return; + } + if (into->name==NULL) { + into->name= from->name; + from->name= NULL; + } + for (i=0;igroupNames[i]!=None) { + if ((merge!=MergeAugment)||(into->groupNames[i]==None)) + into->groupNames[i]= from->groupNames[i]; + } + } + for (i=0,key=from->keys;inKeys;i++,key++) { + if (merge!=MergeDefault) + key->defs.merge= merge; + if (!AddKeySymbols(into,key,xkb)) + into->errorCount++; + } + if (from->modMap!=NULL) { + ModMapEntry *mm,*next; + for (mm=from->modMap;mm!=NULL;mm=next) { + if (merge!=MergeDefault) + mm->defs.merge= merge; + if (!AddModMapEntry(into,mm)) + into->errorCount++; + next= (ModMapEntry *)mm->defs.next; + uFree(mm); + } + from->modMap= NULL; + } + if (!MergeAliases(&into->aliases,&from->aliases,merge)) + into->errorCount++; + return; +} + +typedef void (*FileHandler)( + XkbFile * /* rtrn */, + XkbDescPtr /* xkb */, + unsigned /* merge */, + SymbolsInfo * /* included */ +); + +static Bool +HandleIncludeSymbols( IncludeStmt * stmt, + XkbDescPtr xkb, + SymbolsInfo * info, + FileHandler hndlr) +{ +unsigned newMerge; +XkbFile * rtrn; +SymbolsInfo included; +Bool haveSelf; + + haveSelf= False; + if ((stmt->file==NULL)&&(stmt->map==NULL)) { + haveSelf= True; + included= *info; + bzero(info,sizeof(SymbolsInfo)); + } + else if (ProcessIncludeFile(stmt,XkmSymbolsIndex,&rtrn,&newMerge)) { + InitSymbolsInfo(&included,xkb); + included.fileID= included.dflt.defs.fileID= rtrn->id; + included.merge= included.dflt.defs.merge= MergeOverride; + if (stmt->modifier) { + included.explicit_group= atoi(stmt->modifier) - 1; + } else { + included.explicit_group= info->explicit_group; + } + (*hndlr)(rtrn,xkb,MergeOverride,&included); + if (stmt->stmt!=NULL) { + if (included.name!=NULL) + uFree(included.name); + included.name= stmt->stmt; + stmt->stmt= NULL; + } + } + else { + info->errorCount+= 10; + return False; + } + if ((stmt->next!=NULL)&&(included.errorCount<1)) { + IncludeStmt * next; + unsigned op; + SymbolsInfo next_incl; + + for (next=stmt->next;next!=NULL;next=next->next) { + if ((next->file==NULL)&&(next->map==NULL)) { + haveSelf= True; + MergeIncludedSymbols(&included,info,next->merge,xkb); + FreeSymbolsInfo(info); + } + else if (ProcessIncludeFile(next,XkmSymbolsIndex,&rtrn,&op)) { + InitSymbolsInfo(&next_incl,xkb); + next_incl.fileID= next_incl.dflt.defs.fileID= rtrn->id; + next_incl.merge= next_incl.dflt.defs.merge= MergeOverride; + if (next->modifier) { + next_incl.explicit_group= atoi(next->modifier) - 1; + } else { + next_incl.explicit_group= info->explicit_group; + } + (*hndlr)(rtrn,xkb,MergeOverride,&next_incl); + MergeIncludedSymbols(&included,&next_incl,op,xkb); + FreeSymbolsInfo(&next_incl); + } + else { + info->errorCount+= 10; + return False; + } + } + } + if (haveSelf) + *info= included; + else { + MergeIncludedSymbols(info,&included,newMerge,xkb); + FreeSymbolsInfo(&included); + } + return (info->errorCount==0); +} + +static LookupEntry groupNames[]= { + { "group1", 1 }, + { "group2", 2 }, + { "group3", 3 }, + { "group4", 4 }, + { "group5", 5 }, + { "group6", 6 }, + { "group7", 7 }, + { "group8", 8 }, + { NULL, 0 } +}; + + +#define SYMBOLS 1 +#define ACTIONS 2 + +static Bool +GetGroupIndex( KeyInfo * key, + ExprDef * arrayNdx, + unsigned what, + unsigned * ndx_rtrn) +{ +char * name; +ExprResult tmp; + + if (what==SYMBOLS) name= "symbols"; + else name= "actions"; + + if (arrayNdx==NULL) { + register int i; + unsigned defined; + if (what==SYMBOLS) defined= key->symsDefined; + else defined= key->actsDefined; + + for (i=0;iname,XkbMessage), + XkbNumKbdGroups+1); + ACTION1("Ignoring %s defined for extra groups\n",name); + return False; + } + if (!ExprResolveInteger(arrayNdx,&tmp,SimpleLookup,(XPointer)groupNames)) { + ERROR2("Illegal group index for %s of key %s\n",name, + longText(key->name,XkbMessage)); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { + ERROR3("Group index for %s of key %s is out of range (1..%d)\n",name, + longText(key->name,XkbMessage), + XkbNumKbdGroups+1); + ACTION2("Ignoring %s for group %d\n",name,tmp.uval); + return False; + } + *ndx_rtrn= tmp.uval-1; + return True; +} + +static Bool +AddSymbolsToKey( KeyInfo * key, + XkbDescPtr xkb, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SymbolsInfo * info) +{ +unsigned ndx,nSyms; +int i; + + if (!GetGroupIndex(key,arrayNdx,SYMBOLS,&ndx)) + return False; + if (value==NULL) { + key->symsDefined|= (1<op!=ExprKeysymList) { + ERROR1("Expected a list of symbols, found %s\n",exprOpText(value->op)); + ACTION2("Ignoring symbols for group %d of %s\n",ndx, + longText(key->name,XkbMessage)); + return False; + } + if (key->syms[ndx]!=NULL) { + WSGO2("Symbols for key %s, group %d already defined\n", + longText(key->name,XkbMessage), + ndx); + return False; + } + nSyms= value->value.list.nSyms; + if (((key->numLevels[ndx]syms[ndx]==NULL))&& + (!ResizeKeyGroup(key,ndx,nSyms,False))) { + WSGO2("Could not resize group %d of key %s\n",ndx, + longText(key->name,XkbMessage)); + ACTION("Symbols lost\n"); + return False; + } + key->symsDefined|= (1<syms[ndx],(char *)value->value.list.syms, + nSyms*sizeof(KeySym)); + for (i=key->numLevels[ndx]-1;(i>=0)&&(key->syms[ndx][i]==NoSymbol);i--) { + key->numLevels[ndx]--; + } + return True; +} + +static Bool +AddActionsToKey( KeyInfo * key, + XkbDescPtr xkb, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SymbolsInfo * info) +{ +register int i; +unsigned ndx,nActs; +ExprDef * act; +XkbAnyAction * toAct; + + if (!GetGroupIndex(key,arrayNdx,ACTIONS,&ndx)) + return False; + + if (value==NULL) { + key->actsDefined|= (1<op!=ExprActionList) { + WSGO1("Bad expression type (%d) for action list value\n",value->op); + ACTION2("Ignoring actions for group %d of %s\n",ndx, + longText(key->name,XkbMessage)); + return False; + } + if (key->acts[ndx]!=NULL) { + WSGO2("Actions for key %s, group %d already defined\n", + longText(key->name,XkbMessage), + ndx); + return False; + } + for (nActs=0,act= value->value.child;act!=NULL;nActs++) { + act= (ExprDef *)act->common.next; + } + if (nActs<1) { + WSGO("Action list but not actions in AddActionsToKey\n"); + return False; + } + if (((key->numLevels[ndx]acts[ndx]==NULL))&& + (!ResizeKeyGroup(key,ndx,nActs,True))) { + WSGO2("Could not resize group %d of key %s\n",ndx, + longText(key->name,XkbMessage)); + ACTION("Actions lost\n"); + return False; + } + key->actsDefined|= (1<acts[ndx]; + act= value->value.child; + for (i=0;iaction)) { + ERROR1("Illegal action definition for %s\n", + longText(key->name,XkbMessage)); + ACTION2("Action for group %d/level %d ignored\n",ndx+1,i+1); + } + act= (ExprDef *)act->common.next; + } + return True; +} + +static int +SetAllowNone(KeyInfo *key,ExprDef *arrayNdx,ExprDef *value) +{ +ExprResult tmp; +unsigned radio_groups= 0; + + if (arrayNdx==NULL) { + radio_groups= XkbAllRadioGroupsMask; + } + else { + if (!ExprResolveInteger(arrayNdx,&tmp,RadioLookup,NULL)){ + ERROR("Illegal index in group name definition\n"); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + if ((tmp.uval<1)||(tmp.uval>XkbMaxRadioGroups)) { + ERROR1("Illegal radio group specified (must be 1..%d)\n", + XkbMaxRadioGroups+1); + ACTION1("Value of \"allow none\" for group %d ignored\n",tmp.uval); + return False; + } + radio_groups|= (1<<(tmp.uval-1)); + } + if (!ExprResolveBoolean(value,&tmp,NULL,NULL)) { + ERROR1("Illegal \"allow none\" value for %s\n", + longText(key->name,XkbMessage)); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) key->allowNone|= radio_groups; + else key->allowNone&= ~radio_groups; + return True; +} + + +static LookupEntry lockingEntries[] = { + { "true", XkbKB_Lock }, + { "yes", XkbKB_Lock }, + { "on", XkbKB_Lock }, + { "false", XkbKB_Default }, + { "no", XkbKB_Default }, + { "off", XkbKB_Default }, + { "permanent", XkbKB_Lock|XkbKB_Permanent }, + { NULL, 0 } +}; + +static LookupEntry repeatEntries[]= { + { "true", RepeatYes }, + { "yes", RepeatYes }, + { "on", RepeatYes }, + { "false", RepeatNo }, + { "no", RepeatNo }, + { "off", RepeatNo }, + { "default", RepeatUndefined }, + { NULL, 0 } +}; + +static LookupEntry rgEntries[]= { + { "none", 0 }, + { NULL, 0 } +}; + +static Bool +SetSymbolsField( KeyInfo * key, + XkbDescPtr xkb, + char * field, + ExprDef * arrayNdx, + ExprDef * value, + SymbolsInfo * info) +{ +Bool ok= True; +ExprResult tmp; + + if (uStrCaseCmp(field,"type")==0) { + ExprResult ndx; + if ((!ExprResolveString(value,&tmp,NULL,NULL))&&(warningLevel>0)) { + WARN("The type field of a key symbol map must be a string\n"); + ACTION("Ignoring illegal type definition\n"); + } + if (arrayNdx==NULL) { + key->dfltType= XkbInternAtom(NULL,tmp.str,False); + key->defs.defined|= _Key_Type_Dflt; + } + else if (!ExprResolveInteger(arrayNdx,&ndx,SimpleLookup, + (XPointer)groupNames)) { + ERROR1("Illegal group index for type of key %s\n", + longText(key->name,XkbMessage)); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + else if ((ndx.uval<1)||(ndx.uval>XkbNumKbdGroups)) { + ERROR2("Group index for type of key %s is out of range (1..%d)\n", + longText(key->name,XkbMessage), + XkbNumKbdGroups+1); + ACTION1("Ignoring type for group %d\n",ndx.uval); + return False; + } + else { + key->types[ndx.uval-1]= XkbInternAtom(NULL,tmp.str,False); + key->typesDefined|= (1<<(ndx.uval-1)); + } + } + else if (uStrCaseCmp(field,"symbols")==0) + return AddSymbolsToKey(key,xkb,field,arrayNdx,value,info); + else if (uStrCaseCmp(field,"actions")==0) + return AddActionsToKey(key,xkb,field,arrayNdx,value,info); + else if ((uStrCaseCmp(field,"vmods")==0)|| + (uStrCaseCmp(field,"virtualmods")==0)|| + (uStrCaseCmp(field,"virtualmodifiers")==0)) { + ok= ExprResolveModMask(value,&tmp,LookupVModMask,(XPointer)xkb); + if (ok) { + key->vmodmap= (tmp.uval>>8); + key->defs.defined|= _Key_VModMap; + } + else { + ERROR1("Expected a virtual modifier mask, found %s\n", + exprOpText(value->op)); + ACTION1("Ignoring virtual modifiers definition for key %s\n", + longText(key->name,XkbMessage)); + } + } + else if ((uStrCaseCmp(field,"locking")==0)||(uStrCaseCmp(field,"lock")==0)|| + (uStrCaseCmp(field,"locks")==0)) { + ok= ExprResolveEnum(value,&tmp,lockingEntries); + if (ok) + key->behavior.type= tmp.uval; + key->defs.defined|= _Key_Behavior; + } + else if ((uStrCaseCmp(field,"radiogroup")==0)|| + (uStrCaseCmp(field,"permanentradiogroup")==0)) { + Bool permanent= False; + if (uStrCaseCmp(field,"permanentradiogroup")==0) + permanent= True; + ok= ExprResolveInteger(value,&tmp,SimpleLookup,(XPointer)rgEntries); + if (!ok) { + ERROR1("Illegal radio group specification for %s\n", + longText(key->name,XkbMessage)); + ACTION("Non-integer radio group ignored\n"); + return False; + } + if (tmp.uval==0) { + key->behavior.type= XkbKB_Default; + key->behavior.data= 0; + return ok; + } + if ((tmp.uval<1)||(tmp.uval>XkbMaxRadioGroups)) { + ERROR1("Radio group specification for %s out of range (1..32)\n", + longText(key->name,XkbMessage)); + ACTION1("Illegal radio group %d ignored\n",tmp.uval); + return False; + } + key->behavior.type= XkbKB_RadioGroup|(permanent?XkbKB_Permanent:0); + key->behavior.data= tmp.uval-1; + if (key->allowNone&(1<<(tmp.uval-1))) + key->behavior.data|= XkbKB_RGAllowNone; + key->defs.defined|= _Key_Behavior; + } + else if (uStrCaseEqual(field,"allownone")) { + ok= SetAllowNone(key,arrayNdx,value); + } + else if (uStrCasePrefix("overlay",field)|| + uStrCasePrefix("permanentoverlay",field)) { + Bool permanent= False; + char *which; + int overlayNdx; + if (uStrCasePrefix("permanent",field)) { + permanent= True; + which= &field[sizeof("permanentoverlay")-1]; + } + else { + which= &field[sizeof("overlay")-1]; + } + if (sscanf(which,"%d",&overlayNdx)==1) { + if (((overlayNdx<1)||(overlayNdx>2))&&(warningLevel>0)) { + ERROR2("Illegal overlay %d specified for %s\n", + overlayNdx, + longText(key->name,XkbMessage)); + ACTION("Ignored\n"); + return False; + } + } + else if (*which=='\0') + overlayNdx=1; + else if (warningLevel>0) { + ERROR2("Illegal overlay \"%s\" specified for %s\n", + which, + longText(key->name,XkbMessage)); + ACTION("Ignored\n"); + return False; + } + ok= ExprResolveKeyName(value,&tmp,NULL,NULL); + if (!ok) { + ERROR1("Illegal overlay key specification for %s\n", + longText(key->name,XkbMessage)); + ACTION("Overlay key must be specified by name\n"); + return False; + } + if (overlayNdx==1) key->behavior.type= XkbKB_Overlay1; + else key->behavior.type= XkbKB_Overlay2; + if (permanent) + key->behavior.type|= XkbKB_Permanent; + + key->behavior.data= 0; + key->nameForOverlayKey= KeyNameToLong(tmp.keyName.name); + key->defs.defined|= _Key_Behavior; + } + else if ((uStrCaseCmp(field,"repeating")==0)|| + (uStrCaseCmp(field,"repeats")==0)|| + (uStrCaseCmp(field,"repeat")==0)){ + ok= ExprResolveEnum(value,&tmp,repeatEntries); + if (!ok) { + ERROR1("Illegal repeat setting for %s\n", + longText(key->name,XkbMessage)); + ACTION("Non-boolean repeat setting ignored\n"); + return False; + } + key->repeat= tmp.uval; + key->defs.defined|= _Key_Repeat; + } + else if ((uStrCaseCmp(field,"groupswrap")==0)|| + (uStrCaseCmp(field,"wrapgroups")==0)) { + ok= ExprResolveBoolean(value,&tmp,NULL,NULL); + if (!ok) { + ERROR1("Illegal groupsWrap setting for %s\n", + longText(key->name,XkbMessage)); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) key->groupInfo= XkbWrapIntoRange; + else key->groupInfo= XkbClampIntoRange; + key->defs.defined|= _Key_GroupInfo; + } + else if ((uStrCaseCmp(field,"groupsclamp")==0)|| + (uStrCaseCmp(field,"clampgroups")==0)) { + ok= ExprResolveBoolean(value,&tmp,NULL,NULL); + if (!ok) { + ERROR1("Illegal groupsClamp setting for %s\n", + longText(key->name,XkbMessage)); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) key->groupInfo= XkbClampIntoRange; + else key->groupInfo= XkbWrapIntoRange; + key->defs.defined|= _Key_GroupInfo; + } + else if ((uStrCaseCmp(field,"groupsredirect")==0)|| + (uStrCaseCmp(field,"redirectgroups")==0)) { + if (!ExprResolveInteger(value,&tmp,SimpleLookup,(XPointer)groupNames)) { + ERROR1("Illegal group index for redirect of key %s\n", + longText(key->name,XkbMessage)); + ACTION("Definition with non-integer group ignored\n"); + return False; + } + if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { + ERROR2("Out-of-range (1..%d) group for redirect of key %s\n", + XkbNumKbdGroups, + longText(key->name,XkbMessage)); + ERROR1("Ignoring illegal group %d\n",tmp.uval); + return False; + } + key->groupInfo= XkbSetGroupInfo(0,XkbRedirectIntoRange,tmp.uval-1); + key->defs.defined|= _Key_GroupInfo; + } + else { + ERROR1("Unknown field %s in a symbol interpretation\n",field); + ACTION("Definition ignored\n"); + ok= False; + } + return ok; +} + +static int +SetGroupName(SymbolsInfo *info,ExprDef *arrayNdx,ExprDef *value) +{ +ExprResult tmp,name; + + if ((arrayNdx==NULL)&&(warningLevel>0)) { + WARN("You must specify an index when specifying a group name\n"); + ACTION("Group name definition without array subscript ignored\n"); + return False; + } + if (!ExprResolveInteger(arrayNdx,&tmp,SimpleLookup,(XPointer)groupNames)) { + ERROR("Illegal index in group name definition\n"); + ACTION("Definition with non-integer array index ignored\n"); + return False; + } + if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { + ERROR1("Attempt to specify name for illegal group (must be 1..%d)\n", + XkbNumKbdGroups+1); + ACTION1("Name for group %d ignored\n",tmp.uval); + return False; + } + if (!ExprResolveString(value,&name,NULL,NULL)) { + ERROR("Group name must be a string\n"); + ACTION1("Illegal name for group %d ignored\n",tmp.uval); + return False; + } + info->groupNames[tmp.uval-1+info->explicit_group]= + XkbInternAtom(NULL,name.str,False); + + return True; +} + +static int +HandleSymbolsVar(VarDef *stmt,XkbDescPtr xkb,SymbolsInfo *info) +{ +ExprResult elem,field,tmp; +ExprDef * arrayNdx; + + if (ExprResolveLhs(stmt->name,&elem,&field,&arrayNdx)==0) + return 0; /* internal error, already reported */ + if (elem.str&&(uStrCaseCmp(elem.str,"key")==0)) { + return SetSymbolsField(&info->dflt,xkb,field.str,arrayNdx,stmt->value, + info); + } + else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"name")==0)|| + (uStrCaseCmp(field.str,"groupname")==0))) { + return SetGroupName(info,arrayNdx,stmt->value); + } + else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"groupswrap")==0)|| + (uStrCaseCmp(field.str,"wrapgroups")==0))) { + if (!ExprResolveBoolean(stmt->value,&tmp,NULL,NULL)) { + ERROR("Illegal setting for global groupsWrap\n"); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) info->groupInfo= XkbWrapIntoRange; + else info->groupInfo= XkbClampIntoRange; + return True; + } + else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"groupsclamp")==0)|| + (uStrCaseCmp(field.str,"clampgroups")==0))) { + if (!ExprResolveBoolean(stmt->value,&tmp,NULL,NULL)) { + ERROR("Illegal setting for global groupsClamp\n"); + ACTION("Non-boolean value ignored\n"); + return False; + } + if (tmp.uval) info->groupInfo= XkbClampIntoRange; + else info->groupInfo= XkbWrapIntoRange; + return True; + } + else if ((elem.str==NULL)&&((uStrCaseCmp(field.str,"groupsredirect")==0)|| + (uStrCaseCmp(field.str,"redirectgroups")==0))) { + if (!ExprResolveInteger(stmt->value,&tmp, + SimpleLookup,(XPointer)groupNames)) { + ERROR("Illegal group index for global groupsRedirect\n"); + ACTION("Definition with non-integer group ignored\n"); + return False; + } + if ((tmp.uval<1)||(tmp.uval>XkbNumKbdGroups)) { + ERROR1("Out-of-range (1..%d) group for global groupsRedirect\n", + XkbNumKbdGroups); + ACTION1("Ignoring illegal group %d\n",tmp.uval); + return False; + } + info->groupInfo= XkbSetGroupInfo(0,XkbRedirectIntoRange,tmp.uval); + return True; + } + else if ((elem.str==NULL)&&(uStrCaseCmp(field.str,"allownone")==0)) { + return SetAllowNone(&info->dflt,arrayNdx,stmt->value); + } + return SetActionField(xkb,elem.str,field.str,arrayNdx,stmt->value, + &info->action); +} + +static Bool +HandleSymbolsBody( VarDef * def, + XkbDescPtr xkb, + KeyInfo * key, + SymbolsInfo * info) +{ +Bool ok= True; +ExprResult tmp,field; +ExprDef * arrayNdx; + + for (;def!=NULL;def= (VarDef *)def->common.next) { + if ((def->name)&&(def->name->type==ExprFieldRef)) { + ok= HandleSymbolsVar(def,xkb,info); + continue; + } + else { + if (def->name==NULL) { + if ((def->value==NULL)||(def->value->op==ExprKeysymList)) + field.str= "symbols"; + else field.str= "actions"; + arrayNdx= NULL; + } + else { + ok= ExprResolveLhs(def->name,&tmp,&field,&arrayNdx); + } + if (ok) + ok= SetSymbolsField(key,xkb,field.str,arrayNdx,def->value,info); + } + } + return ok; +} + +static Bool +SetExplicitGroup( SymbolsInfo * info, + KeyInfo * key) +{ + unsigned group = info->explicit_group; + + if (group == 0) + return True; + + if ((key->typesDefined|key->symsDefined|key->actsDefined) & ~1) { + int i; + WARN1("For the map %s an explicit group specified\n", info->name); + WARN1("but key %s has more than one group defined\n", + longText(key->name,XkbMessage)); + ACTION("All groups except first one will be ignored\n"); + for (i = 1; i < XkbNumKbdGroups ; i++) { + key->numLevels[i]= 0; + if (key->syms[i]!=NULL) + uFree(key->syms[i]); + key->syms[i]= (KeySym*) NULL; + if (key->acts[i]!=NULL) + uFree(key->acts[i]); + key->acts[i]= (XkbAction*) NULL; + key->types[i]= (Atom) 0; + } + } + key->typesDefined = key->symsDefined = key->actsDefined = 1 << group; + + key->numLevels[group]= key->numLevels[0]; + key->numLevels[0]= 0; + key->syms[group]= key->syms[0]; + key->syms[0]= (KeySym*) NULL; + key->acts[group]= key->acts[0]; + key->acts[0]= (XkbAction*) NULL; + key->types[group]= key->types[0]; + key->types[0]= (Atom) 0; + return True; +} + +static int +HandleSymbolsDef( SymbolsDef * stmt, + XkbDescPtr xkb, + unsigned merge, + SymbolsInfo * info) +{ +KeyInfo key; + + InitKeyInfo(&key); + CopyKeyInfo(&info->dflt,&key,False); + key.defs.merge= stmt->merge; + key.name= KeyNameToLong(stmt->keyName); + if (!HandleSymbolsBody((VarDef *)stmt->symbols,xkb,&key,info)) { + info->errorCount++; + return False; + } + + if (!SetExplicitGroup(info,&key)) { + info->errorCount++; + return False; + } + + if (!AddKeySymbols(info,&key,xkb)) { + info->errorCount++; + return False; + } + return True; +} + +static Bool +HandleModMapDef( ModMapDef * def, + XkbDescPtr xkb, + unsigned merge, + SymbolsInfo * info) +{ +ExprDef * key; +ModMapEntry tmp; +ExprResult rtrn; +Bool ok; + + if (!LookupModIndex(NULL,None,def->modifier,TypeInt,&rtrn)) { + ERROR("Illegal modifier map definition\n"); + ACTION1("Ignoring map for non-modifier \"%s\"\n", + XkbAtomText(NULL,def->modifier,XkbMessage)); + return False; + } + ok= True; + tmp.modifier= rtrn.uval; + for (key=def->keys;key!=NULL;key=(ExprDef *)key->common.next) { + if ((key->op==ExprValue)&&(key->type==TypeKeyName)) { + tmp.haveSymbol= False; + tmp.u.keyName= KeyNameToLong(key->value.keyName); + } + else if (ExprResolveKeySym(key,&rtrn,NULL,NULL)) { + tmp.haveSymbol= True; + tmp.u.keySym= rtrn.uval; + } + else { + ERROR("Modmap entries may contain only key names or keysyms\n"); + ACTION1("Illegal definition for %s modifier ignored\n", + XkbModIndexText(tmp.modifier,XkbMessage)); + continue; + } + + ok= AddModMapEntry(info,&tmp)&&ok; + } + return ok; +} + +static void +HandleSymbolsFile( XkbFile * file, + XkbDescPtr xkb, + unsigned merge, + SymbolsInfo * info) +{ +ParseCommon *stmt; + + info->name= uStringDup(file->name); + stmt= file->defs; + while (stmt) { + switch (stmt->stmtType) { + case StmtInclude: + if (!HandleIncludeSymbols((IncludeStmt *)stmt,xkb,info, + HandleSymbolsFile)) + info->errorCount++; + break; + case StmtSymbolsDef: + if (!HandleSymbolsDef((SymbolsDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + case StmtVarDef: + if (!HandleSymbolsVar((VarDef *)stmt,xkb,info)) + info->errorCount++; + break; + case StmtVModDef: + if (!HandleVModDef((VModDef *)stmt,merge,&info->vmods)) + info->errorCount++; + break; + case StmtInterpDef: + ERROR("Interpretation files may not include other types\n"); + ACTION("Ignoring definition of symbol interpretation\n"); + info->errorCount++; + break; + case StmtKeycodeDef: + ERROR("Interpretation files may not include other types\n"); + ACTION("Ignoring definition of key name\n"); + info->errorCount++; + break; + case StmtModMapDef: + if (!HandleModMapDef((ModMapDef *)stmt,xkb,merge,info)) + info->errorCount++; + break; + default: + WSGO1("Unexpected statement type %d in HandleSymbolsFile\n", + stmt->stmtType); + break; + } + stmt= stmt->next; + if (info->errorCount>10) { +#ifdef NOISY + ERROR("Too many errors\n"); +#endif + ACTION1("Abandoning symbols file \"%s\"\n",file->topName); + break; + } + } + return; +} + +static Bool +FindKeyForSymbol(XkbDescPtr xkb,KeySym sym,unsigned int *kc_rtrn) +{ +register int i, j; +register Bool gotOne; + + j= 0; + do { + gotOne= False; + for (i = xkb->min_key_code; i <= (int)xkb->max_key_code; i++) { + if ( j<(int)XkbKeyNumSyms(xkb,i) ) { + gotOne = True; + if ((XkbKeySym(xkb,i,j)==sym)) { + *kc_rtrn= i; + return True; + } + } + } + j++; + } while (gotOne); + return False; +} + +static Bool +FindNamedType(XkbDescPtr xkb,Atom name,unsigned *type_rtrn) +{ +register unsigned n; + + if (xkb&&xkb->map&&xkb->map->types) { + for (n=0;nmap->num_types;n++) { + if (xkb->map->types[n].name==(Atom)name) { + *type_rtrn= n; + return True; + } + } + } + return False; +} + +static Bool +KSIsLower (KeySym ks) +{ + KeySym lower, upper; + XConvertCase(ks, &lower, &upper); + + if (lower == upper) + return False; + return (ks == lower ? True : False); +} + +static Bool +KSIsUpper (KeySym ks) +{ + KeySym lower, upper; + XConvertCase(ks, &lower, &upper); + + if (lower == upper) + return False; + return (ks == upper ? True : False); +} + +static Bool +FindAutomaticType(int width,KeySym *syms,Atom *typeNameRtrn, Bool *autoType) +{ + *autoType = False; + if ((width==1)||(width==0)) { + *typeNameRtrn= XkbInternAtom(NULL,"ONE_LEVEL",False); + *autoType = True; + } else if (width == 2) { + if ( syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]) ) { + *typeNameRtrn= XkbInternAtom(NULL,"ALPHABETIC",False); + } else if ( syms && + (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])) ) { + *typeNameRtrn= XkbInternAtom(NULL,"KEYPAD",False); + *autoType = True; + } else { + *typeNameRtrn= XkbInternAtom(NULL,"TWO_LEVEL",False); + *autoType = True; + } + } else if (width <= 4 ) { + if ( syms && KSIsLower(syms[0]) && KSIsUpper(syms[1]) ) + if ( KSIsLower(syms[2]) && KSIsUpper(syms[3]) ) + *typeNameRtrn= XkbInternAtom(NULL, + "FOUR_LEVEL_ALPHABETIC",False); + else + *typeNameRtrn= XkbInternAtom(NULL, + "FOUR_LEVEL_SEMIALPHABETIC",False); + + else if ( syms && (XkbKSIsKeypad(syms[0]) || XkbKSIsKeypad(syms[1])) ) + *typeNameRtrn= XkbInternAtom(NULL, + "FOUR_LEVEL_KEYPAD",False); + else *typeNameRtrn= XkbInternAtom(NULL,"FOUR_LEVEL",False); + } + return ((width>=0)&&(width<=4)); +} + +static void +PrepareKeyDef(KeyInfo *key) +{ + int i, j, width, defined, lastGroup; + Bool identical; + + defined = key->symsDefined | key->actsDefined | key->typesDefined; + for (i = XkbNumKbdGroups - 1; i >= 0; i--) { + if (defined & (1< 0; i--) { + if (defined & (1<numLevels[0]; + if (key->typesDefined & 1) { + for (j = 0; j < width; j++) { + key->types[i] = key->types[0]; + } + key->typesDefined |= 1 << i; + } + if ((key->actsDefined & 1) && key->acts[0]) { + key->acts[i]= uTypedCalloc(width, XkbAction); + if (key->acts[i] == NULL) + continue; + memcpy((void *) key->acts[i], (void *) key->acts[0], + width * sizeof(XkbAction)); + key->actsDefined |= 1 << i; + } + if ((key->symsDefined & 1) && key->syms[0]) { + key->syms[i]= uTypedCalloc(width, KeySym); + if (key->syms[i] == NULL) + continue; + memcpy((void *) key->syms[i], (void *) key->syms[0], + width * sizeof(KeySym)); + key->symsDefined |= 1 << i; + } + if (defined & 1) { + key->numLevels[i] = key->numLevels[0]; + } + } + /* If all groups are completely identical remove them all */ + /* exept the first one. */ + identical = True; + for (i = lastGroup; i > 0; i--) { + if ((key->numLevels[i] != key->numLevels[0]) || + (key->types[i] != key->types[0])) { + identical = False; + break; + } + if ((key->syms[i] != key->syms[0]) && + (key->syms[i] == NULL || key->syms[0] == NULL || + memcmp((void*) key->syms[i], (void*) key->syms[0], + sizeof(KeySym) * key->numLevels[0])) ) { + identical = False; + break; + } + if ((key->acts[i] != key->acts[0]) && + (key->acts[i] == NULL || key->acts[0] == NULL || + memcmp((void*) key->acts[i], (void*) key->acts[0], + sizeof(XkbAction) * key->numLevels[0]))) { + identical = False; + break; + } + } + if (identical) { + for (i = lastGroup; i > 0; i--) { + key->numLevels[i]= 0; + if (key->syms[i] != NULL) + uFree(key->syms[i]); + key->syms[i]= (KeySym*) NULL; + if (key->acts[i] != NULL) + uFree(key->acts[i]); + key->acts[i]= (XkbAction*) NULL; + key->types[i]= (Atom) 0; + } + key->symsDefined &= 1; + key->actsDefined &= 1; + key->typesDefined &= 1; + } + return; +} + +static Bool +CopySymbolsDef(XkbFileInfo *result,KeyInfo *key,int start_from) +{ +register int i; +unsigned okc,kc,width,tmp,nGroups; +XkbKeyTypePtr type; +Bool haveActions,autoType,useAlias; +KeySym * outSyms; +XkbAction * outActs; +XkbDescPtr xkb; +unsigned types[XkbNumKbdGroups]; + + xkb= result->xkb; + useAlias= (start_from==0); + if (!FindNamedKey(xkb,key->name,&kc,useAlias,CreateKeyNames(xkb), + start_from)) { + if ((start_from==0)&&(warningLevel>=5)) { + WARN2("Key %s not found in %s keycodes\n", + longText(key->name,XkbMessage), + XkbAtomText(NULL,xkb->names->keycodes,XkbMessage)); + ACTION("Symbols ignored\n"); + } + return False; + } + + haveActions= False; + for (i=width=nGroups=0;inGroups)&&(((key->symsDefined|key->actsDefined)&(1<typesDefined)&(1<acts[i]) + haveActions= True; + autoType= False; + if (key->types[i]==None) { + if (key->dfltType!=None) + key->types[i]= key->dfltType; + else if (FindAutomaticType(key->numLevels[i],key->syms[i], + &key->types[i], &autoType)) { + } + else { + if (warningLevel>=5) { + WARN1("No automatic type for %d symbols\n", + (unsigned int)key->numLevels[i]); + ACTION3("Using %s for the %s key (keycode %d)\n", + XkbAtomText(NULL,key->types[i],XkbMessage), + longText(key->name,XkbMessage),kc); + } + } + } + if (FindNamedType(xkb,key->types[i],&types[i])) { + if (!autoType || key->numLevels[i] > 2) + xkb->server->explicit[kc]|= (1<=3) { + WARN1("Type \"%s\" is not defined\n", + XkbAtomText(NULL,key->types[i],XkbMessage)); + ACTION2("Using TWO_LEVEL for the %s key (keycode %d)\n", + longText(key->name,XkbMessage),kc); + } + types[i]= XkbTwoLevelIndex; + } + type= &xkb->map->types[types[i]]; + if (type->num_levelsnumLevels[i]) { + if (warningLevel>0) { + WARN4("Type \"%s\" has %d levels, but %s has %d symbols\n", + XkbAtomText(NULL,type->name,XkbMessage), + (unsigned int)type->num_levels, + longText(key->name,XkbMessage), + (unsigned int)key->numLevels[i]); + ACTION("Ignoring extra symbols\n"); + } + key->numLevels[i]= type->num_levels; + } + if (key->numLevels[i]>width) + width= key->numLevels[i]; + if (type->num_levels>width) + width= type->num_levels; + } + + i= width*nGroups; + outSyms= XkbResizeKeySyms(xkb,kc,i); + if (outSyms==NULL) { + WSGO2("Could not enlarge symbols for %s (keycode %d)\n", + longText(key->name,XkbMessage),kc); + return False; + } + if (haveActions) { + outActs= XkbResizeKeyActions(xkb,kc,i); + if (outActs==NULL) { + WSGO2("Could not enlarge actions for %s (key %d)\n", + longText(key->name,XkbMessage),kc); + return False; + } + xkb->server->explicit[kc]|= XkbExplicitInterpretMask; + } + else outActs= NULL; + if (key->defs.defined&_Key_GroupInfo) + i= key->groupInfo; + else i= xkb->map->key_sym_map[kc].group_info; + xkb->map->key_sym_map[kc].group_info= XkbSetNumGroups(i,nGroups); + xkb->map->key_sym_map[kc].width= width; + for (i=0;imap->key_sym_map[kc].kt_index[i]= types[i]; + if (key->syms[i]!=NULL) { + for (tmp=0;tmpnumLevels[i]) + outSyms[tmp]= key->syms[i][tmp]; + else outSyms[tmp]= NoSymbol; + if ((outActs!=NULL)&&(key->acts[i]!=NULL)) { + if (tmpnumLevels[i]) + outActs[tmp]= key->acts[i][tmp]; + else outActs[tmp].type= XkbSA_NoAction; + } + } + } + outSyms+= width; + if (outActs) + outActs+= width; + } + switch (key->behavior.type&XkbKB_OpMask) { + case XkbKB_Default: + break; + case XkbKB_Overlay1: + case XkbKB_Overlay2: + /* find key by name! */ + if (!FindNamedKey(xkb,key->nameForOverlayKey,&okc,True, + CreateKeyNames(xkb),0)) { + if (warningLevel>=1) { + WARN2("Key %s not found in %s keycodes\n", + longText(key->nameForOverlayKey,XkbMessage), + XkbAtomText(NULL,xkb->names->keycodes,XkbMessage)); + ACTION1("Not treating %s as an overlay key \n", + longText(key->name,XkbMessage)); + } + break; + } + key->behavior.data= okc; + default: + xkb->server->behaviors[kc]= key->behavior; + xkb->server->explicit[kc]|= XkbExplicitBehaviorMask; + break; + } + if (key->defs.defined&_Key_VModMap) { + xkb->server->vmodmap[kc]= key->vmodmap; + xkb->server->explicit[kc]|= XkbExplicitVModMapMask; + } + if (key->repeat!=RepeatUndefined) { + if (key->repeat==RepeatYes) + xkb->ctrls->per_key_repeat[kc/8]|= (1<<(kc%8)); + else xkb->ctrls->per_key_repeat[kc/8]&= ~(1<<(kc%8)); + xkb->server->explicit[kc]|= XkbExplicitAutoRepeatMask; + } + CopySymbolsDef(result,key,kc+1); + return True; +} + +static Bool +CopyModMapDef(XkbFileInfo *result,ModMapEntry *entry) +{ +unsigned kc; +XkbDescPtr xkb; + + xkb= result->xkb; + if ((!entry->haveSymbol)&&(!FindNamedKey(xkb,entry->u.keyName,&kc,True, + CreateKeyNames(xkb),0))) { + if (warningLevel>=5) { + WARN2("Key %s not found in %s keycodes\n", + longText(entry->u.keyName,XkbMessage), + XkbAtomText(NULL,xkb->names->keycodes,XkbMessage)); + ACTION1("Modifier map entry for %s not updated\n", + XkbModIndexText(entry->modifier,XkbMessage)); + } + return False; + } + else if (entry->haveSymbol&&(!FindKeyForSymbol(xkb,entry->u.keySym,&kc))) { + if (warningLevel>5) { + WARN2("Key \"%s\" not found in %s symbol map\n", + XkbKeysymText(entry->u.keySym,XkbMessage), + XkbAtomText(NULL,xkb->names->symbols,XkbMessage)); + ACTION1("Modifier map entry for %s not updated\n", + XkbModIndexText(entry->modifier,XkbMessage)); + } + return False; + } + xkb->map->modmap[kc]|= (1<modifier); + return True; +} + +Bool +CompileSymbols(XkbFile *file,XkbFileInfo *result,unsigned merge) +{ +register int i; +SymbolsInfo info; +XkbDescPtr xkb; + + xkb= result->xkb; + InitSymbolsInfo(&info,xkb); + info.dflt.defs.fileID= file->id; + info.dflt.defs.merge= merge; + HandleSymbolsFile(file,xkb,merge,&info); + + if (info.nKeys == 0) + return True; + if (info.errorCount==0) { + KeyInfo *key; + if (XkbAllocNames(xkb,XkbSymbolsNameMask|XkbGroupNamesMask,0,0) + !=Success) { + WSGO("Can not allocate names in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + if(XkbAllocClientMap(xkb,XkbKeySymsMask|XkbModifierMapMask,0)!=Success){ + WSGO("Could not allocate client map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,32)!=Success) { + WSGO("Could not allocate server map in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + if (XkbAllocControls(xkb,XkbPerKeyRepeatMask)!=Success) { + WSGO("Could not allocate controls in CompileSymbols\n"); + ACTION("Symbols not added\n"); + return False; + } + xkb->names->symbols= XkbInternAtom(xkb->dpy,info.name,False); + if (info.aliases) + ApplyAliases(xkb,False,&info.aliases); + for (i=0;inames->groups[i]= info.groupNames[i]; + } + for (key=info.keys,i=0;i3) { + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (xkb->names->keys[i].name[0]=='\0') + continue; + if (XkbKeyNumGroups(xkb,i)<1) { + char buf[5]; + memcpy(buf,xkb->names->keys[i].name,4); + buf[4]= '\0'; + WARN2("No symbols defined for <%s> (keycode %d)\n",buf,i); + } + } + } + if (info.modMap) { + ModMapEntry *mm,*next; + for (mm=info.modMap;mm!=NULL;mm=next) { + if (!CopyModMapDef(result,mm)) + info.errorCount++; + next= (ModMapEntry *)mm->defs.next; + } + } + return True; + } + return False; +} diff --git a/xkbcomp/tokens.h b/xkbcomp/tokens.h new file mode 100644 index 0000000..c63c393 --- /dev/null +++ b/xkbcomp/tokens.h @@ -0,0 +1,100 @@ +/* $Xorg: tokens.h,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +#ifndef TOKENS_H +#define TOKENS_H 1 + +#define END_OF_FILE 0 +#define ERROR_TOK 255 + +#define XKB_KEYMAP 1 +#define XKB_KEYCODES 2 +#define XKB_TYPES 3 +#define XKB_SYMBOLS 4 +#define XKB_COMPATMAP 5 +#define XKB_GEOMETRY 6 +#define XKB_SEMANTICS 7 +#define XKB_LAYOUT 8 + +#define INCLUDE 10 +#define OVERRIDE 11 +#define AUGMENT 12 +#define REPLACE 13 +#define ALTERNATE 14 + +#define VIRTUAL_MODS 20 +#define TYPE 21 +#define INTERPRET 22 +#define ACTION_TOK 23 +#define KEY 24 +#define ALIAS 25 +#define GROUP 26 +#define MODIFIER_MAP 27 +#define INDICATOR 28 +#define SHAPE 29 +#define KEYS 30 +#define ROW 31 +#define SECTION 32 +#define OVERLAY 33 +#define TEXT 34 +#define OUTLINE 35 +#define SOLID 36 +#define LOGO 37 +#define VIRTUAL 38 + +#define EQUALS 40 +#define PLUS 41 +#define MINUS 42 +#define DIVIDE 43 +#define TIMES 44 +#define OBRACE 45 +#define CBRACE 46 +#define OPAREN 47 +#define CPAREN 48 +#define OBRACKET 49 +#define CBRACKET 50 +#define DOT 51 +#define COMMA 52 +#define SEMI 53 +#define EXCLAM 54 +#define INVERT 55 + +#define STRING 60 +#define INTEGER 61 +#define FLOAT 62 +#define IDENT 63 +#define KEYNAME 64 + +#define PARTIAL 70 +#define DEFAULT 71 +#define HIDDEN 72 +#define ALPHANUMERIC_KEYS 73 +#define MODIFIER_KEYS 74 +#define KEYPAD_KEYS 75 +#define FUNCTION_KEYS 76 +#define ALTERNATE_GROUP 77 + +#endif diff --git a/xkbcomp/utils.c b/xkbcomp/utils.c new file mode 100644 index 0000000..93850d4 --- /dev/null +++ b/xkbcomp/utils.c @@ -0,0 +1,411 @@ + + /*\ + * $Xorg: utils.c,v 1.4 2000/08/17 19:54:33 cpqbld Exp $ + * + * COPYRIGHT 1990 + * DIGITAL EQUIPMENT CORPORATION + * MAYNARD, MASSACHUSETTS + * ALL RIGHTS RESERVED. + * + * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND + * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. + * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE + * FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED + * WARRANTY. + * + * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT + * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN + * ADDITION TO THAT SET FORTH ABOVE. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Digital Equipment Corporation not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + \*/ +/* $XFree86: xc/programs/xkbcomp/utils.c,v 3.6 2001/07/25 15:05:24 dawes Exp $ */ + +#include "utils.h" +#include +#include +#include + +/***====================================================================***/ + +Opaque +uAlloc(unsigned size) +{ + return((Opaque)malloc(size)); +} + +/***====================================================================***/ + +Opaque +uCalloc(unsigned n,unsigned size) +{ + return((Opaque)calloc(n,size)); +} + +/***====================================================================***/ + +Opaque +uRealloc(Opaque old,unsigned newSize) +{ + if (old==NULL) + return((Opaque)malloc(newSize)); + else return((Opaque)realloc((char *)old,newSize)); +} + +/***====================================================================***/ + +Opaque +uRecalloc(Opaque old,unsigned nOld,unsigned nNew,unsigned itemSize) +{ +char *rtrn; + + if (old==NULL) + rtrn= (char *)calloc(nNew,itemSize); + else { + rtrn= (char *)realloc((char *)old,nNew*itemSize); + if ((rtrn)&&(nNew>nOld)) { + bzero(&rtrn[nOld*itemSize],(nNew-nOld)*itemSize); + } + } + return (Opaque)rtrn; +} + +/***====================================================================***/ + +void +uFree(Opaque ptr) +{ + if (ptr!=(Opaque)NULL) + free((char *)ptr); + return; +} + +/***====================================================================***/ +/*** FUNCTION ENTRY TRACKING ***/ +/***====================================================================***/ + +static FILE *entryFile= NULL; + int uEntryLevel; + +Boolean +uSetEntryFile(char *name) +{ + if ((entryFile!=NULL)&&(entryFile!=stderr)) { + fprintf(entryFile,"switching to %s\n",name?name:"stderr"); + fclose(entryFile); + } + if (name!=NullString) entryFile= fopen(name,"w"); + else entryFile= stderr; + if (entryFile==NULL) { + entryFile= stderr; + return(False); + } + return(True); +} + +void +uEntry(int l,char *s,...) +{ +int i; +va_list args; + + for (i=0;i %p\n",rtVal); + return; +} + +/***====================================================================***/ +/*** PRINT FUNCTIONS ***/ +/***====================================================================***/ + + FILE *uDebugFile= NULL; + int uDebugIndentLevel= 0; + int uDebugIndentSize= 4; + +Boolean +uSetDebugFile(char *name) +{ + if ((uDebugFile!=NULL)&&(uDebugFile!=stderr)) { + fprintf(uDebugFile,"switching to %s\n",name?name:"stderr"); + fclose(uDebugFile); + } + if (name!=NullString) uDebugFile= fopen(name,"w"); + else uDebugFile= stderr; + if (uDebugFile==NULL) { + uDebugFile= stderr; + return(False); + } + return(True); +} + +void +uDebug(char *s,...) +{ +int i; +va_list args; + + for (i=(uDebugIndentLevel*uDebugIndentSize);i>0;i--) { + putc(' ',uDebugFile); + } + va_start(args, s); + vfprintf(uDebugFile,s,args); + va_end(args); + fflush(uDebugFile); +} + +void +uDebugNOI(char *s,...) +{ +va_list args; + + va_start(args, s); + vfprintf(uDebugFile,s,args); + va_end(args); + fflush(uDebugFile); +} + +/***====================================================================***/ + +static FILE *errorFile= NULL; +static int outCount= 0; +static char *preMsg= NULL; +static char *postMsg= NULL; +static char *prefix= NULL; + +Boolean +uSetErrorFile(char *name) +{ + if ((errorFile!=NULL)&&(errorFile!=stderr)) { + fprintf(errorFile,"switching to %s\n",name?name:"stderr"); + fclose(errorFile); + } + if (name!=NullString) errorFile= fopen(name,"w"); + else errorFile= stderr; + if (errorFile==NULL) { + errorFile= stderr; + return(False); + } + return(True); +} + +void +uInformation(char *s, ...) +{ +va_list args; + + va_start(args, s); + vfprintf(errorFile,s,args); + va_end(args); + fflush(errorFile); +} + +/***====================================================================***/ + +void +uAction(char *s, ...) +{ +va_list args; + + if (prefix!=NULL) + fprintf(errorFile,"%s",prefix); + fprintf(errorFile," "); + va_start(args, s); + vfprintf(errorFile,s,args); + va_end(args); + fflush(errorFile); +} + +/***====================================================================***/ + +void +uWarning(char *s, ...) +{ +va_list args; + + if ((outCount==0)&&(preMsg!=NULL)) + fprintf(errorFile,"%s\n",preMsg); + if (prefix!=NULL) + fprintf(errorFile,"%s",prefix); + fprintf(errorFile,"Warning: "); + va_start(args, s); + vfprintf(errorFile,s,args); + va_end(args); + fflush(errorFile); + outCount++; +} + +/***====================================================================***/ + +void +uError(char *s, ...) +{ +va_list args; + + if ((outCount==0)&&(preMsg!=NULL)) + fprintf(errorFile,"%s\n",preMsg); + if (prefix!=NULL) + fprintf(errorFile,"%s",prefix); + fprintf(errorFile,"Error: "); + va_start(args, s); + vfprintf(errorFile,s,args); + va_end(args); + fflush(errorFile); + outCount++; +} + +/***====================================================================***/ + +void +uFatalError(char *s, ...) +{ +va_list args; + + if ((outCount==0)&&(preMsg!=NULL)) + fprintf(errorFile,"%s\n",preMsg); + if (prefix!=NULL) + fprintf(errorFile,"%s",prefix); + fprintf(errorFile,"Fatal Error: "); + va_start(args, s); + vfprintf(errorFile,s,args); + va_end(args); + fprintf(errorFile," Exiting\n"); + fflush(errorFile); + outCount++; + exit(1); + /* NOTREACHED */ +} + +/***====================================================================***/ + +void +uInternalError(char *s, ...) +{ +va_list args; + + if ((outCount==0)&&(preMsg!=NULL)) + fprintf(errorFile,"%s\n",preMsg); + if (prefix!=NULL) + fprintf(errorFile,"%s",prefix); + fprintf(errorFile,"Internal error: "); + va_start(args, s); + vfprintf(errorFile,s,args); + va_end(args); + fflush(errorFile); + outCount++; +} + +void +uSetPreErrorMessage(char *msg) +{ + outCount= 0; + preMsg= msg; + return; +} + +void +uSetPostErrorMessage(char *msg) +{ + postMsg= msg; + return; +} + +void +uSetErrorPrefix(char *pre) +{ + prefix= pre; + return; +} + +void +uFinishUp(void) +{ + if ((outCount>0)&&(postMsg!=NULL)) + fprintf(errorFile,"%s\n",postMsg); + return; +} + +/***====================================================================***/ + +#ifndef HAVE_STRDUP +char * +uStringDup(char *str) +{ +char *rtrn; + + if (str==NULL) + return NULL; + rtrn= (char *)uAlloc(strlen(str)+1); + strcpy(rtrn,str); + return rtrn; +} +#endif + +#ifndef HAVE_STRCASECMP +int +uStrCaseCmp(char *str1,char *str2) +{ + char buf1[512],buf2[512]; + char c, *s; + register int n; + + for (n=0, s = buf1; (c = *str1++); n++) { + if (isupper(c)) + c = tolower(c); + if (n>510) + break; + *s++ = c; + } + *s = '\0'; + for (n=0, s = buf2; (c = *str2++); n++) { + if (isupper(c)) + c = tolower(c); + if (n>510) + break; + *s++ = c; + } + *s = '\0'; + return (strcmp(buf1, buf2)); +} + +int +uStrCasePrefix(char *my_prefix,char *str) +{ + char c1; + char c2; + while (((c1=*my_prefix)!='\0')&&((c2=*str)!='\0')) { + if (isupper(c1)) c1= tolower(c1); + if (isupper(c2)) c2= tolower(c2); + if (c1!=c2) + return 0; + my_prefix++; str++; + } + if (c1!='\0') + return 0; + return 1; +} + +#endif diff --git a/xkbcomp/utils.h b/xkbcomp/utils.h new file mode 100644 index 0000000..d57e6da --- /dev/null +++ b/xkbcomp/utils.h @@ -0,0 +1,422 @@ +#ifndef UTILS_H +#define UTILS_H 1 + + /*\ + * $Xorg: utils.h,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ + * + * COPYRIGHT 1990 + * DIGITAL EQUIPMENT CORPORATION + * MAYNARD, MASSACHUSETTS + * ALL RIGHTS RESERVED. + * + * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND + * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. + * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE + * FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED + * WARRANTY. + * + * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT + * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN + * ADDITION TO THAT SET FORTH ABOVE. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Digital Equipment Corporation not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + \*/ +/* $XFree86: xc/programs/xkbcomp/utils.h,v 3.5 2002/06/05 00:00:37 dawes Exp $ */ + +/***====================================================================***/ + +#include +#include +#include +#include + +#include + +#ifndef NUL +#define NUL '\0' +#endif + +/***====================================================================***/ + +#ifndef OPAQUE_DEFINED +typedef void *Opaque; +#endif +#ifndef NullOpaque +#define NullOpaque ((Opaque)NULL) +#endif + +#ifndef BOOLEAN_DEFINED +typedef char Boolean; +#endif + +#ifndef True +#define True ((Boolean)1) +#define False ((Boolean)0) +#endif /* ndef True */ +#define booleanText(b) ((b)?"True":"False") + +#ifndef COMPARISON_DEFINED +typedef int Comparison; + +#define Greater ((Comparison)1) +#define Equal ((Comparison)0) +#define Less ((Comparison)-1) +#define CannotCompare ((Comparison)-37) +#define comparisonText(c) ((c)?((c)<0?"Less":"Greater"):"Equal") +#endif + +#if 0 +typedef union { + int i; + unsigned u; + void *p; + void *(*fp)(); +} Union; +#endif + +/***====================================================================***/ + +extern Opaque uAlloc( + unsigned /* size */ +); +extern Opaque uCalloc( + unsigned /* n */, + unsigned /* size */ +); +extern Opaque uRealloc( + Opaque /* old */, + unsigned /* newSize */ +); +extern Opaque uRecalloc( + Opaque /* old */, + unsigned /* nOld */, + unsigned /* nNew */, + unsigned /* newSize */ +); +extern void uFree( + Opaque /* ptr */ +); + +#define uTypedAlloc(t) ((t *)uAlloc((unsigned)sizeof(t))) +#define uTypedCalloc(n,t) ((t *)uCalloc((unsigned)n,(unsigned)sizeof(t))) +#define uTypedRealloc(pO,n,t) ((t *)uRealloc((Opaque)pO,((unsigned)n)*sizeof(t))) +#define uTypedRecalloc(pO,o,n,t) ((t *)uRecalloc((Opaque)pO,((unsigned)o),((unsigned)n),sizeof(t))) +#if (defined mdHasAlloca) && (mdHasAlloca) +#define uTmpAlloc(n) ((Opaque)alloca((unsigned)n)) +#define uTmpFree(p) +#else +#define uTmpAlloc(n) uAlloc(n) +#define uTmpFree(p) uFree(p) +#endif + +/***====================================================================***/ + +extern Boolean uSetErrorFile( + char * /* name */ +); + +#define INFO6 uInformation +#define INFO5 uInformation +#define INFO4 uInformation +#define INFO3 uInformation +#define INFO2 uInformation +#define INFO1 uInformation +#define INFO uInformation + +extern void uInformation( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +#define ACTION6 uAction +#define ACTION5 uAction +#define ACTION4 uAction +#define ACTION3 uAction +#define ACTION2 uAction +#define ACTION1 uAction +#define ACTION uAction + +extern void uAction( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +#define WARN6 uWarning +#define WARN5 uWarning +#define WARN4 uWarning +#define WARN3 uWarning +#define WARN2 uWarning +#define WARN1 uWarning +#define WARN uWarning + +extern void uWarning( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +#define ERROR6 uError +#define ERROR5 uError +#define ERROR4 uError +#define ERROR3 uError +#define ERROR2 uError +#define ERROR1 uError +#define ERROR uError + +extern void uError( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +#define FATAL6 uFatalError +#define FATAL5 uFatalError +#define FATAL4 uFatalError +#define FATAL3 uFatalError +#define FATAL2 uFatalError +#define FATAL1 uFatalError +#define FATAL uFatalError + +extern void uFatalError( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +/* WSGO stands for "Weird Stuff Going On" */ +#define WSGO6 uInternalError +#define WSGO5 uInternalError +#define WSGO4 uInternalError +#define WSGO3 uInternalError +#define WSGO2 uInternalError +#define WSGO1 uInternalError +#define WSGO uInternalError + +extern void uInternalError( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +extern void uSetPreErrorMessage( + char * /* msg */ +); + +extern void uSetPostErrorMessage( + char * /* msg */ +); + +extern void uSetErrorPrefix( + char * /* void */ +); + +extern void uFinishUp( + void +); + + +/***====================================================================***/ + +#define NullString ((char *)NULL) + +#define uStringText(s) ((s)==NullString?"":(s)) +#define uStringEqual(s1,s2) (uStringCompare(s1,s2)==Equal) +#define uStringPrefix(p,s) (strncmp(p,s,strlen(p))==0) +#define uStringCompare(s1,s2) (((s1)==NullString||(s2)==NullString)?\ + (s1)!=(s2):strcmp(s1,s2)) +#define uStrCaseEqual(s1,s2) (uStrCaseCmp(s1,s2)==0) +#ifdef HAVE_STRCASECMP +#define uStrCaseCmp(s1,s2) (strcasecmp(s1,s2)) +#define uStrCasePrefix(p,s) (strncasecmp(p,s,strlen(p))==0) +#else +extern int uStrCaseCmp( + char * /* s1 */, + char * /* s2 */ +); +extern int uStrCasePrefix( + char * /* p */, + char * /* str */ +); +#endif +#ifdef HAVE_STRDUP +#define uStringDup(s1) (strdup(s1)) +#else +extern char *uStringDup( + char * /* s1 */ +); +#endif + +/***====================================================================***/ + +#ifdef ASSERTIONS_ON +#define uASSERT(where,why) \ + {if (!(why)) uFatalError("assertion botched in %s ( why )\n",where);} +#else +#define uASSERT(where,why) +#endif + +/***====================================================================***/ + +#ifndef DEBUG_VAR +#define DEBUG_VAR debugFlags +#endif + +#ifdef DEBUG_VAR_NOT_LOCAL +extern +#endif +unsigned int DEBUG_VAR; + +extern void uDebug( + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +extern void uDebugNOI( /* no indent */ + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 1, 2))) +#endif +; + +extern Boolean uSetDebugFile( + char *name +); + +extern FILE *uDebugFile; +extern int uDebugIndentLevel; +extern int uDebugIndentSize; +#define uDebugIndent(l) (uDebugIndentLevel+=(l)) +#define uDebugOutdent(l) (uDebugIndentLevel-=(l)) +#ifdef DEBUG_ON +#define uDEBUG(f,s) { if (DEBUG_VAR&(f)) uDebug(s);} +#define uDEBUG1(f,s,a) { if (DEBUG_VAR&(f)) uDebug(s,a);} +#define uDEBUG2(f,s,a,b) { if (DEBUG_VAR&(f)) uDebug(s,a,b);} +#define uDEBUG3(f,s,a,b,c) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c);} +#define uDEBUG4(f,s,a,b,c,d) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c,d);} +#define uDEBUG5(f,s,a,b,c,d,e) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c,d,e);} +#define uDEBUG_NOI(f,s) { if (DEBUG_VAR&(f)) uDebug(s);} +#define uDEBUG_NOI1(f,s,a) { if (DEBUG_VAR&(f)) uDebugNOI(s,a);} +#define uDEBUG_NOI2(f,s,a,b) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b);} +#define uDEBUG_NOI3(f,s,a,b,c) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c);} +#define uDEBUG_NOI4(f,s,a,b,c,d) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c,d);} +#define uDEBUG_NOI5(f,s,a,b,c,d,e) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c,d,e);} +#else +#define uDEBUG(f,s) +#define uDEBUG1(f,s,a) +#define uDEBUG2(f,s,a,b) +#define uDEBUG3(f,s,a,b,c) +#define uDEBUG4(f,s,a,b,c,d) +#define uDEBUG5(f,s,a,b,c,d,e) +#define uDEBUG_NOI(f,s) +#define uDEBUG_NOI1(f,s,a) +#define uDEBUG_NOI2(f,s,a,b) +#define uDEBUG_NOI3(f,s,a,b,c) +#define uDEBUG_NOI4(f,s,a,b,c,d) +#define uDEBUG_NOI5(f,s,a,b,c,d,e) +#endif + +extern Boolean uSetEntryFile( + char *name +); +extern void uEntry( + int /* l */, + char * /* s */, ... +) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 6))) +__attribute__((format(printf, 2, 3))) +#endif +; + +extern void uExit( + int l,char *rtVal +); +#ifdef ENTRY_TRACKING_ON +#define ENTRY_BIT 0x10 +#define LOW_ENTRY_BIT 0x1000 +#define ENTER (DEBUG_VAR&ENTRY_BIT) +#define FLAG(fLag) (DEBUG_VAR&(fLag)) + +extern int uEntryLevel; + +#define uENTRY(s) { if (ENTER) uEntry(1,s);} +#define uENTRY1(s,a) { if (ENTER) uEntry(1,s,a);} +#define uENTRY2(s,a,b) { if (ENTER) uEntry(1,s,a,b);} +#define uENTRY3(s,a,b,c) { if (ENTER) uEntry(1,s,a,b,c);} +#define uENTRY4(s,a,b,c,d) { if (ENTER) uEntry(1,s,a,b,c,d);} +#define uENTRY5(s,a,b,c,d,e) { if (ENTER) uEntry(1,s,a,b,c,d,e);} +#define uENTRY6(s,a,b,c,d,e,f) { if (ENTER) uEntry(1,s,a,b,c,d,e,f);} +#define uENTRY7(s,a,b,c,d,e,f,g) { if (ENTER) uEntry(1,s,a,b,c,d,e,f,g);} +#define uRETURN(v) { if (ENTER) uEntryLevel--; return(v); } +#define uVOIDRETURN { if (ENTER) uEntryLevel--; return; } + +#define uFLAG_ENTRY(w,s) { if (FLAG(w)) uEntry(0,s);} +#define uFLAG_ENTRY1(w,s,a) { if (FLAG(w)) uEntry(0,s,a);} +#define uFLAG_ENTRY2(w,s,a,b) { if (FLAG(w)) uEntry(0,s,a,b);} +#define uFLAG_ENTRY3(w,s,a,b,c) { if (FLAG(w)) uEntry(0,s,a,b,c);} +#define uFLAG_ENTRY4(w,s,a,b,c,d) { if (FLAG(w)) uEntry(0,s,a,b,c,d);} +#define uFLAG_ENTRY5(w,s,a,b,c,d,e) { if (FLAG(w)) uEntry(0,s,a,b,c,d,e);} +#define uFLAG_ENTRY6(w,s,a,b,c,d,e,f) { if (FLAG(w)) uEntry(0,s,a,b,c,d,e,f);} +#define uFLAG_ENTRY7(w,s,a,b,c,d,e,f,g) { if(FLAG(w))uEntry(0,s,a,b,c,d,e,f,g);} +#define uFLAG_RETURN(v) { return(v);} +#define uFLAG_VOIDRETURN { return; } +#else +#define uENTRY(s) +#define uENTRY1(s,a) +#define uENTRY2(s,a1,a2) +#define uENTRY3(s,a1,a2,a3) +#define uENTRY4(s,a1,a2,a3,a4) +#define uENTRY5(s,a1,a2,a3,a4,a5) +#define uENTRY6(s,a1,a2,a3,a4,a5,a6) +#define uENTRY7(s,a1,a2,a3,a4,a5,a6,a7) +#define uRETURN(v) { return(v); } +#define uVOIDRETURN { return; } + +#define uFLAG_ENTRY(f,s) +#define uFLAG_ENTRY1(f,s,a) +#define uFLAG_ENTRY2(f,s,a,b) +#define uFLAG_ENTRY3(f,s,a,b,c) +#define uFLAG_ENTRY4(f,s,a,b,c,d) +#define uFLAG_ENTRY5(f,s,a,b,c,d,e) +#define uFLAG_ENTRY6(f,s,a,b,c,d,e,g) +#define uFLAG_ENTRY7(f,s,a,b,c,d,e,g,h) +#define uFLAG_RETURN(v) { return(v);} +#define uFLAG_VOIDRETURN { return; } +#endif + + +#endif /* UTILS_H */ + + diff --git a/xkbcomp/vmod.c b/xkbcomp/vmod.c new file mode 100644 index 0000000..6d9628c --- /dev/null +++ b/xkbcomp/vmod.c @@ -0,0 +1,224 @@ +/* $Xorg: vmod.c,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/vmod.c,v 3.3 2001/01/17 23:45:45 dawes Exp $ */ + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR debugFlags +#include +#include "xkbcomp.h" +#include "tokens.h" +#include "expr.h" +#include "misc.h" + +#include +#include + +#include "vmod.h" + +void +InitVModInfo(VModInfo *info,XkbDescPtr xkb) +{ + ClearVModInfo(info,xkb); + info->errorCount= 0; + return; +} + +void +ClearVModInfo(VModInfo *info,XkbDescPtr xkb) +{ +register int i; + + if (XkbAllocNames(xkb,XkbVirtualModNamesMask,0,0)!=Success) + return; + if (XkbAllocServerMap(xkb,XkbVirtualModsMask,0)!=Success) + return; + info->xkb= xkb; + info->newlyDefined= info->defined= info->available= 0; + if (xkb && xkb->names) { + register int bit; + for (i=0,bit=1;inames->vmods[i]!=None) + info->defined|= bit; + } + } + return; +} + +/***====================================================================***/ + +Bool +HandleVModDef(VModDef *stmt,unsigned mergeMode,VModInfo *info) +{ +register int i,bit,nextFree; +ExprResult mod; +XkbServerMapPtr srv; +XkbNamesPtr names; +Atom stmtName; + + srv= info->xkb->server; + names= info->xkb->names; + stmtName= XkbInternAtom(info->xkb->dpy,XkbAtomGetString(NULL,stmt->name), + False); + for (i=0,bit=1,nextFree= -1;idefined&bit) { + if (names->vmods[i]==stmtName) { /* already defined */ + info->available|= bit; + if (stmt->value==NULL) + return True; + else { + char *str1,*str2 = ""; + if (!ExprResolveModMask(stmt->value,&mod,NULL,NULL)) { + str1= XkbAtomText(NULL,stmt->name,XkbMessage); + ACTION1("Declaration of %s ignored\n",str1); + return False; + } + if (mod.uval==srv->vmods[i]) + return True; + + str1= XkbAtomText(NULL,stmt->name,XkbMessage); + WARN1("Virtual modifier %s multiply defined\n",str1); + str1= XkbModMaskText(srv->vmods[i],XkbCFile); + if (mergeMode==MergeOverride) { + str2= str1; + str1= XkbModMaskText(mod.uval,XkbCFile); + } + ACTION2("Using %s, ignoring %s\n",str1,str2); + if (mergeMode==MergeOverride) + srv->vmods[i]= mod.uval; + return True; + } + } + } + else if (nextFree<0) + nextFree= i; + } + if (nextFree<0) { + ERROR1("Too many virtual modifiers defined (maximum %d)\n", + XkbNumVirtualMods); + ACTION("Exiting\n"); + return False; + } + info->defined|= (1<newlyDefined|= (1<available|= (1<vmods[nextFree]= stmtName; + if (stmt->value==NULL) + return True; + if (ExprResolveModMask(stmt->value,&mod,NULL,NULL)) { + srv->vmods[nextFree]= mod.uval; + return True; + } + ACTION1("Declaration of %s ignored\n", + XkbAtomText(NULL,stmt->name,XkbMessage)); + return False; +} + +int +LookupVModIndex( XPointer priv, + Atom elem, + Atom field, + unsigned type, + ExprResult * val_rtrn) +{ +register int i; +register char * fieldStr; +register char * modStr; +XkbDescPtr xkb; + + xkb= (XkbDescPtr)priv; + if ((xkb==NULL)||(xkb->names==NULL)||(elem!=None)||(type!=TypeInt)) { + return False; + } + fieldStr= XkbAtomGetString(xkb->dpy,field); + if (fieldStr==NULL) + return False; + for (i=0;idpy,xkb->names->vmods[i]); + if ((modStr!=NULL)&&(uStrCaseCmp(fieldStr,modStr)==0)) { + val_rtrn->uval= i; + return True; + } + } + return False; +} + +int +LookupVModMask( XPointer priv, + Atom elem, + Atom field, + unsigned type, + ExprResult * val_rtrn) +{ + if (LookupVModIndex(priv,elem,field,type,val_rtrn)) { + register unsigned ndx= val_rtrn->uval; + val_rtrn->uval= (1<<(XkbNumModifiers+ndx)); + return True; + } + return False; +} + +int +FindKeypadVMod(XkbDescPtr xkb) +{ +Atom name; +ExprResult rtrn; + + name= XkbInternAtom(xkb->dpy,"NumLock",False); + if ((xkb)&& + LookupVModIndex((XPointer)xkb,None,name,TypeInt,&rtrn)) { + return rtrn.ival; + } + return -1; +} + +Bool +ResolveVirtualModifier(ExprDef *def,ExprResult *val_rtrn,VModInfo *info) +{ +XkbNamesPtr names; + + names= info->xkb->names; + if (def->op==ExprIdent) { + register int i,bit; + for (i=0,bit=1;ixkb->dpy,names->vmods[i]); + str2= XkbAtomGetString(NULL,def->value.str); + if ((info->available&bit)&& + (uStrCaseCmp(str1,str2)==Equal)) { + val_rtrn->uval= i; + return True; + } + } + } + if (ExprResolveInteger(def,val_rtrn,NULL,NULL)) { + if (val_rtrn->uvaluval,XkbNumVirtualMods-1); + } + return False; +} diff --git a/xkbcomp/vmod.h b/xkbcomp/vmod.h new file mode 100644 index 0000000..231d2c8 --- /dev/null +++ b/xkbcomp/vmod.h @@ -0,0 +1,87 @@ +/* $Xorg: vmod.h,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86$ */ + +#ifndef VMOD_H +#define VMOD_H 1 + +typedef struct _VModInfo { + XkbDescPtr xkb; + unsigned defined; + unsigned available; + unsigned newlyDefined; + int errorCount; +} VModInfo; + +extern void InitVModInfo( + VModInfo * /* info */, + XkbDescPtr /* xkb */ +); + +extern void ClearVModInfo( + VModInfo * /* info */, + XkbDescPtr /* xkb */ +); + +extern Bool HandleVModDef( + VModDef * /* stmt */, + unsigned /* mergeMode */, + VModInfo * /* info */ +); + +extern Bool ApplyVModDefs( + VModInfo * /* info */, + XkbDescPtr /* xkb */ +); + +extern int LookupVModIndex( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int LookupVModMask( + XPointer /* priv */, + Atom /* elem */, + Atom /* field */, + unsigned /* type */, + ExprResult * /* val_rtrn */ +); + +extern int FindKeypadVMod( + XkbDescPtr /* xkb */ +); + +extern Bool ResolveVirtualModifier( + ExprDef * /* def */, + ExprResult * /* value_rtrn */, + VModInfo * /* info */ +); + +#endif /* VMOD_H */ diff --git a/xkbcomp/xkbcomp.c b/xkbcomp/xkbcomp.c new file mode 100644 index 0000000..f54f4f0 --- /dev/null +++ b/xkbcomp/xkbcomp.c @@ -0,0 +1,978 @@ +/* $Xorg: xkbcomp.c,v 1.4 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/xkbcomp.c,v 3.20 2003/09/24 02:43:38 dawes Exp $ */ + +#include +#include +#include + +/* for symlink attack security fix -- Branden Robinson */ +#include +#include +#include +/* end BR */ + +#if defined(sgi) +#include +#endif + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR debugFlags +#include "xkbcomp.h" +#include +#include "xkbpath.h" +#include "parseutils.h" +#include "misc.h" +#include "tokens.h" +#include + +#ifdef __UNIXOS2__ +#define chdir _chdir2 +#endif + +#ifdef WIN32 +#define S_IRGRP 0 +#define S_IWGRP 0 +#define S_IROTH 0 +#define S_IWOTH 0 +#endif + +#define lowbit(x) ((x) & (-(x))) + +/***====================================================================***/ + +#define WANT_DEFAULT 0 +#define WANT_XKM_FILE 1 +#define WANT_C_HDR 2 +#define WANT_XKB_FILE 3 +#define WANT_X_SERVER 4 +#define WANT_LISTING 5 + +#define INPUT_UNKNOWN 0 +#define INPUT_XKB 1 +#define INPUT_XKM 2 + +static char *fileTypeExt[] = { + "XXX", + "xkm", + "h", + "xkb", + "dir" +}; + +static unsigned inputFormat,outputFormat; + char * rootDir; +static char * inputFile; +static char * inputMap; +static char * outputFile; +static char * inDpyName; +static char * outDpyName; +static Display * inDpy; +static Display * outDpy; +static Bool showImplicit= False; +static Bool synch= False; +static Bool computeDflts= False; +static Bool xkblist= False; + unsigned warningLevel= 5; + unsigned verboseLevel= 0; + unsigned dirsToStrip= 0; + unsigned optionalParts= 0; +static char * preErrorMsg= NULL; +static char * postErrorMsg= NULL; +static char * errorPrefix= NULL; + +/***====================================================================***/ + +#define M(m) fprintf(stderr,(m)) +#define M1(m,a) fprintf(stderr,(m),(a)) + +static void +Usage(int argc,char *argv[]) +{ + if (!xkblist) + M1("Usage: %s [options] input-file [ output-file ]\n",argv[0]); + else M1("Usage: %s [options] file[(map)] ...\n",argv[0]); + M("Legal options:\n"); + M("-?,-help Print this message\n"); + if (!xkblist) { + M("-a Show all actions\n"); + M("-C Create a C header file\n"); + } +#ifdef DEBUG + M("-d [flags] Report debugging information\n"); +#endif + M("-em1 Print before printing first error message\n"); + M("-emp Print at the start of each message line\n"); + M("-eml If there were any errors, print before exiting\n"); + if (!xkblist) { + M("-dflts Compute defaults for missing parts\n"); + M("-I[] Specifies a top level directory for include\n"); + M(" directives. Multiple directories are legal.\n"); + M("-l [flags] List matching maps in the specified files\n"); + M(" f: list fully specified names\n"); + M(" h: also list hidden maps\n"); + M(" l: long listing (show flags)\n"); + M(" p: also list partial maps\n"); + M(" R: recursively list subdirectories\n"); + M(" default is all options off\n"); + } + M("-m[ap] Specifies map to compile\n"); + M("-o Specifies output file name\n"); + if (!xkblist) { + M("-opt[ional] Specifies optional components of keymap\n"); + M(" Errors in optional parts are not fatal\n"); + M(" can be any combination of:\n"); + M(" c: compat map g: geometry\n"); + M(" k: keycodes s: symbols\n"); + M(" t: types\n"); + } + if (xkblist) { + M("-p Specifies the number of slashes to be stripped\n"); + M(" from the front of the map name on output\n"); + } + M("-R[] Specifies the root directory for\n"); + M(" relative path names\n"); + M("-synch Force synchronization\n"); + if (xkblist) { + M("-v [] Set level of detail for listing.\n"); + M(" flags are as for the -l option\n"); + } + M("-w [] Set warning level (0=none, 10=all)\n"); + if (!xkblist) { + M("-xkb Create an XKB source (.xkb) file\n"); + M("-xkm Create a compiled key map (.xkm) file\n"); + } + return; +} + +/***====================================================================***/ + +static void +setVerboseFlags(char *str) +{ + for (;*str;str++) { + switch (*str) { + case 'f': verboseLevel|= WantFullNames; break; + case 'h': verboseLevel|= WantHiddenMaps; break; + case 'l': verboseLevel|= WantLongListing; break; + case 'p': verboseLevel|= WantPartialMaps; break; + case 'R': verboseLevel|= ListRecursive; break; + default: + if (warningLevel>4) { + WARN1("Unknown verbose option \"%c\"\n",(unsigned int)*str); + ACTION("Ignored\n"); + } + break; + } + } + return; +} + +static Bool +parseArgs(int argc,char *argv[]) +{ +register int i,tmp; + + i= strlen(argv[0]); + tmp= strlen("xkblist"); + if ((i>=tmp)&&(strcmp(&argv[0][i-tmp],"xkblist")==0)) { + xkblist= True; + } + for (i=1;i0) { + WARN("Too many file names on command line\n"); + ACTION3("Compiling %s, writing to %s, ignoring %s\n", + inputFile,outputFile,argv[i]); + } + } + else if (!AddMatchingFiles(argv[i])) + return False; + } + else if ((strcmp(argv[i],"-?")==0)||(strcmp(argv[i],"-help")==0)) { + Usage(argc,argv); + exit(0); + } + else if ((strcmp(argv[i],"-a")==0)&&(!xkblist)) { + showImplicit= True; + } + else if ((strcmp(argv[i],"-C")==0)&&(!xkblist)) { + if ((outputFormat!=WANT_DEFAULT)&&(outputFormat!=WANT_C_HDR)) { + if (warningLevel>0) { + WARN("Multiple output file formats specified\n"); + ACTION1("\"%s\" flag ignored\n",argv[i]); + } + } + else outputFormat= WANT_C_HDR; + } +#ifdef DEBUG + else if (strcmp(argv[i],"-d")==0) { + if ((i>=(argc-1))||(!isdigit(argv[i+1][0]))) { + debugFlags= 1; + } + else { + if (sscanf(argv[++i],"%i",&itmp) == 1) + debugFlags = itmp; + } + INFO1("Setting debug flags to %d\n",debugFlags); + } +#endif + else if ((strcmp(argv[i],"-dflts")==0)&&(!xkblist)) { + computeDflts= True; + } + else if (strcmp(argv[i],"-em1")==0) { + if (++i>=argc) { + if (warningLevel>0) { + WARN("No pre-error message specified\n"); + ACTION("Trailing \"-em1\" option ignored\n"); + } + } + else if (preErrorMsg!=NULL) { + if (warningLevel>0) { + WARN("Multiple pre-error messsages specified\n"); + ACTION2("Compiling %s, ignoring %s\n",preErrorMsg,argv[i]); + } + } + else preErrorMsg= argv[i]; + } + else if (strcmp(argv[i],"-emp")==0) { + if (++i>=argc) { + if (warningLevel>0) { + WARN("No error prefix specified\n"); + ACTION("Trailing \"-emp\" option ignored\n"); + } + } + else if (errorPrefix!=NULL) { + if (warningLevel>0) { + WARN("Multiple error prefixes specified\n"); + ACTION2("Compiling %s, ignoring %s\n",errorPrefix,argv[i]); + } + } + else errorPrefix= argv[i]; + } + else if (strcmp(argv[i],"-eml")==0) { + if (++i>=argc) { + if (warningLevel>0) { + WARN("No post-error message specified\n"); + ACTION("Trailing \"-eml\" option ignored\n"); + } + } + else if (postErrorMsg!=NULL) { + if (warningLevel>0) { + WARN("Multiple post-error messages specified\n"); + ACTION2("Compiling %s, ignoring %s\n",postErrorMsg,argv[i]); + } + } + else postErrorMsg= argv[i]; + } + else if ((strncmp(argv[i],"-I",2)==0)&&(!xkblist)) { + if (!XkbAddDirectoryToPath(&argv[i][2])) { + ACTION("Exiting\n"); + exit(1); + } + } + else if ((strncmp(argv[i],"-l",2)==0)&&(!xkblist)) { + if (outputFormat!=WANT_DEFAULT) { + if (warningLevel>0) { + WARN("Multiple output file formats specified\n"); + ACTION1("\"%s\" flag ignored\n",argv[i]); + } + } + else { + if (argv[i][2]!='\0') + setVerboseFlags(&argv[i][2]); + xkblist= True; + if ((inputFile)&&(!AddMatchingFiles(inputFile))) + return False; + else inputFile= NULL; + if ((outputFile)&&(!AddMatchingFiles(outputFile))) + return False; + else outputFile= NULL; + } + } + else if ((strcmp(argv[i],"-m")==0)||(strcmp(argv[i],"-map")==0)) { + if (++i>=argc) { + if (warningLevel>0) { + WARN("No map name specified\n"); + ACTION1("Trailing \"%s\" option ignored\n",argv[i-1]); + } + } + else if (xkblist) { + if (!AddMapOnly(argv[i])) + return False; + } + else if (inputMap!=NULL) { + if (warningLevel>0) { + WARN("Multiple map names specified\n"); + ACTION2("Compiling %s, ignoring %s\n",inputMap,argv[i]); + } + } + else inputMap= argv[i]; + } + else if ((strcmp(argv[i],"-merge")==0)&&(!xkblist)) { + /* Ignored */ + } + else if (strcmp(argv[i],"-o")==0) { + if (++i>=argc) { + if (warningLevel>0) { + WARN("No output file specified\n"); + ACTION("Trailing \"-o\" option ignored\n"); + } + } + else if (outputFile!=NULL) { + if (warningLevel>0) { + WARN("Multiple output files specified\n"); + ACTION2("Compiling %s, ignoring %s\n",outputFile,argv[i]); + } + } + else outputFile= argv[i]; + } + else if (((strcmp(argv[i],"-opt")==0)||(strcmp(argv[i],"optional")==0)) + &&(!xkblist)) { + if (++i>=argc) { + if (warningLevel>0) { + WARN("No optional components specified\n"); + ACTION1("Trailing \"%s\" option ignored\n",argv[i-1]); + } + } + else { + char *tmp2; + for (tmp2=argv[i];(*tmp2!='\0');tmp2++) { + switch (*tmp2) { + case 'c': case 'C': + optionalParts|= XkmCompatMapMask; + break; + case 'g': case 'G': + optionalParts|= XkmGeometryMask; + break; + case 'k': case 'K': + optionalParts|= XkmKeyNamesMask; + break; + case 's': case 'S': + optionalParts|= XkmSymbolsMask; + break; + case 't': case 'T': + optionalParts|= XkmTypesMask; + break; + default: + if (warningLevel>0) { + WARN1("Illegal component for %s option\n", + argv[i-1]); + ACTION1("Ignoring unknown specifier \"%c\"\n", + (unsigned int)*tmp2); + } + break; + } + } + } + } + else if (strncmp(argv[i],"-p",2)==0) { + if (isdigit(argv[i][2])) { + if (sscanf(&argv[i][2],"%i",&itmp) == 1) + dirsToStrip = itmp; + } + else if ((i<(argc-1))&&(isdigit(argv[i+1][0]))) { + if (sscanf(argv[++i],"%i",&itmp) == 1) + dirsToStrip = itmp; + } + else { + dirsToStrip= 0; + } + if (warningLevel>5) + INFO1("Setting path count to %d\n",dirsToStrip); + } + else if (strncmp(argv[i],"-R",2)==0) { + if (argv[i][2]=='\0') { + if (warningLevel>0) { + WARN("No root directory specified\n"); + ACTION("Ignoring -R option\n"); + } + } + else if (rootDir!=NULL) { + if (warningLevel>0) { + WARN("Multiple root directories specified\n"); + ACTION2("Using %s, ignoring %s\n",rootDir,argv[i]); + } + } + else { + rootDir= &argv[i][2]; + if (warningLevel>8) { + WARN1("Changing root directory to \"%s\"\n",rootDir); + } + if ((chdir(rootDir)<0) && (warningLevel>0)) { + WARN1("Couldn't change directory to \"%s\"\n",rootDir); + ACTION("Root directory (-R) option ignored\n"); + rootDir= NULL; + } + } + } + else if ((strcmp(argv[i],"-synch")==0)||(strcmp(argv[i],"-s")==0)) { + synch= True; + } + else if (strncmp(argv[i],"-v",2)==0) { + char *str; + if (argv[i][2]!='\0') + str= &argv[i][2]; + else if ((i<(argc-1))&&(argv[i+1][0]!='-')) + str= argv[++i]; + else str= NULL; + if (str) + setVerboseFlags(str); + } + else if (strncmp(argv[i],"-w",2)==0) { + if ((i>=(argc-1))||(!isdigit(argv[i+1][0]))) { + warningLevel = 0; + if (isdigit(argv[i][1])) + if (sscanf(&argv[i][1],"%i",&itmp) == 1) + warningLevel = itmp; + } + else { + if (sscanf(argv[++i],"%i",&itmp) == 1) + warningLevel = itmp; + } + } + else if ((strcmp(argv[i],"-xkb")==0)&&(!xkblist)) { + if ((outputFormat!=WANT_DEFAULT)&&(outputFormat!=WANT_XKB_FILE)) { + if (warningLevel>0) { + WARN("Multiple output file formats specified\n"); + ACTION1("\"%s\" flag ignored\n",argv[i]); + } + } + else outputFormat= WANT_XKB_FILE; + } + else if ((strcmp(argv[i],"-xkm")==0)&&(!xkblist)) { + if ((outputFormat!=WANT_DEFAULT)&&(outputFormat!=WANT_XKM_FILE)) { + if (warningLevel>0) { + WARN("Multiple output file formats specified\n"); + ACTION1("\"%s\" flag ignored\n",argv[i]); + } + } + else outputFormat= WANT_XKM_FILE; + } + else { + ERROR1("Unknown flag \"%s\" on command line\n",argv[i]); + Usage(argc,argv); + return False; + } + } + if (xkblist) + inputFormat= INPUT_XKB; + else if (inputFile==NULL) { + ERROR("No input file specified\n"); + return False; + } + else if (uStringEqual(inputFile,"-")) { + inputFormat= INPUT_XKB; + } +#ifndef WIN32 + else if (strchr(inputFile,':')==0) { +#else + else if ((strchr(inputFile,':')==0) || ( + strlen(inputFile) > 2 && + isalpha(inputFile[0]) && + inputFile[1] == ':' && strchr(inputFile + 2,':')==NULL)) { +#endif + int len; + len= strlen(inputFile); + if (inputFile[len-1]==')') { + char *tmp; + if ((tmp=strchr(inputFile,'('))!=0) { + *tmp= '\0'; inputFile[len-1]= '\0'; + tmp++; + if (*tmp=='\0') { + WARN("Empty map in filename\n"); + ACTION("Ignored\n"); + } + else if (inputMap==NULL) { + inputMap= uStringDup(tmp); + } + else { + WARN("Map specified in filename and with -m flag\n"); + ACTION1("map from name (\"%s\") ignored\n",tmp); + } + } + else { + ERROR1("Illegal name \"%s\" for input file\n",inputFile); + return False; + } + } + if ((len>4)&&(strcmp(&inputFile[len-4],".xkm")==0)) { + inputFormat= INPUT_XKM; + } + else { + FILE *file; + file= fopen(inputFile,"r"); + if (file) { + if (XkmProbe(file)) inputFormat= INPUT_XKM; + else inputFormat= INPUT_XKB; + fclose(file); + } + else { + fprintf(stderr,"Cannot open \"%s\" for reading\n",inputFile); + return False; + } + } + } + else { + inDpyName= inputFile; + inputFile= NULL; + inputFormat= INPUT_XKM; + } + + if (outputFormat==WANT_DEFAULT) { + if (xkblist) outputFormat= WANT_LISTING; + else if (inputFormat==INPUT_XKB) outputFormat= WANT_XKM_FILE; + else outputFormat= WANT_XKB_FILE; + } + if ((outputFormat==WANT_LISTING)&&(inputFormat!=INPUT_XKB)) { + if (inputFile) + ERROR("Cannot generate a listing from a .xkm file (yet)\n"); + else ERROR("Cannot generate a listing from an X connection (yet)\n"); + return False; + } + if (xkblist) { + if (outputFile==NULL) outputFile= uStringDup("-"); + else if (strchr(outputFile,':')!=NULL) { + ERROR("Cannot write a listing to an X connection\n"); + return False; + } + } + else if ((!outputFile) && (inputFile) && uStringEqual(inputFile,"-")) { + int len= strlen("stdin")+strlen(fileTypeExt[outputFormat])+2; + outputFile= uTypedCalloc(len,char); + if (outputFile==NULL) { + WSGO("Cannot allocate space for output file name\n"); + ACTION("Exiting\n"); + exit(1); + } + sprintf(outputFile,"stdin.%s",fileTypeExt[outputFormat]); + } + else if ((outputFile==NULL)&&(inputFile!=NULL)) { + int len; + char *base,*ext; + + if (inputMap==NULL) { + base= strrchr(inputFile,'/'); + if (base==NULL) base= inputFile; + else base++; + } + else base= inputMap; + + len= strlen(base)+strlen(fileTypeExt[outputFormat])+2; + outputFile= uTypedCalloc(len,char); + if (outputFile==NULL) { + WSGO("Cannot allocate space for output file name\n"); + ACTION("Exiting\n"); + exit(1); + } + ext= strrchr(base,'.'); + if (ext==NULL) + sprintf(outputFile,"%s.%s",base,fileTypeExt[outputFormat]); + else { + strcpy(outputFile,base); + strcpy(&outputFile[ext-base+1],fileTypeExt[outputFormat]); + } + } + else if (outputFile==NULL) { + int len; + char *ch,*name,buf[128]; + if (inDpyName[0]==':') + sprintf(name=buf,"server%s",inDpyName); + else name= inDpyName; + + len= strlen(name)+strlen(fileTypeExt[outputFormat])+2; + outputFile= uTypedCalloc(len,char); + if (outputFile==NULL) { + WSGO("Cannot allocate space for output file name\n"); + ACTION("Exiting\n"); + exit(1); + } + strcpy(outputFile,name); + for (ch=outputFile;(*ch)!='\0';ch++) { + if (*ch==':') *ch= '-'; + else if (*ch=='.') *ch= '_'; + } + *ch++= '.'; + strcpy(ch,fileTypeExt[outputFormat]); + } +#ifdef WIN32 + else if (strlen(outputFile) > 2 && + isalpha(outputFile[0]) && + outputFile[1] == ':' && strchr(outputFile + 2,':')==NULL) { + } +#endif + else if (strchr(outputFile,':')!=NULL) { + outDpyName= outputFile; + outputFile= NULL; + outputFormat= WANT_X_SERVER; + } + return True; +} + +static Display * +GetDisplay(char *program,char *dpyName) +{ +int mjr,mnr,error; +Display *dpy; + + mjr= XkbMajorVersion; + mnr= XkbMinorVersion; + dpy= XkbOpenDisplay(dpyName,NULL,NULL,&mjr,&mnr,&error); + if (dpy==NULL) { + switch (error) { + case XkbOD_BadLibraryVersion: + INFO3("%s was compiled with XKB version %d.%02d\n", + program,XkbMajorVersion,XkbMinorVersion); + ERROR2("X library supports incompatible version %d.%02d\n", + mjr,mnr); + break; + case XkbOD_ConnectionRefused: + ERROR1("Cannot open display \"%s\"\n",dpyName); + break; + case XkbOD_NonXkbServer: + ERROR1("XKB extension not present on %s\n",dpyName); + break; + case XkbOD_BadServerVersion: + INFO3("%s was compiled with XKB version %d.%02d\n", + program,XkbMajorVersion,XkbMinorVersion); + ERROR3("Server %s uses incompatible version %d.%02d\n", + dpyName,mjr,mnr); + break; + default: + WSGO1("Unknown error %d from XkbOpenDisplay\n",error); + } + } + else if (synch) + XSynchronize(dpy,True); + return dpy; +} + +/***====================================================================***/ + +extern int yydebug; + +int +main(int argc,char *argv[]) +{ +FILE * file; +XkbFile * rtrn; +XkbFile * mapToUse; +int ok; +XkbFileInfo result; +Status status; + + yyin = stdin; + uSetEntryFile(NullString); + uSetDebugFile(NullString); + uSetErrorFile(NullString); + + XkbInitIncludePath(); + if (!parseArgs(argc,argv)) + exit(1); +#ifdef DEBUG + if (debugFlags&0x2) + yydebug= 1; +#endif + if (preErrorMsg) + uSetPreErrorMessage(preErrorMsg); + if (errorPrefix) + uSetErrorPrefix(errorPrefix); + if (postErrorMsg) + uSetPostErrorMessage(postErrorMsg); + file= NULL; + XkbInitAtoms(NULL); + XkbAddDefaultDirectoriesToPath(); + if (xkblist) { + Bool gotSome; + gotSome= GenerateListing(outputFile); + if ((warningLevel>7)&&(!gotSome)) + return -1; + return 0; + } + if (inputFile!=NULL) { + if (uStringEqual(inputFile,"-")) { + static char *in= "stdin"; + file= stdin; + inputFile= in; + } + else { + file= fopen(inputFile,"r"); + } + } + else if (inDpyName!=NULL) { + inDpy= GetDisplay(argv[0],inDpyName); + if (!inDpy) { + ACTION("Exiting\n"); + exit(1); + } + } + if (outDpyName!=NULL) { + outDpy= GetDisplay(argv[0],outDpyName); + if (!outDpy) { + ACTION("Exiting\n"); + exit(1); + } + } + if ((inDpy==NULL) && (outDpy==NULL)) { + int mjr,mnr; + mjr= XkbMajorVersion; + mnr= XkbMinorVersion; + if (!XkbLibraryVersion(&mjr,&mnr)) { + INFO3("%s was compiled with XKB version %d.%02d\n", + argv[0],XkbMajorVersion,XkbMinorVersion); + ERROR2("X library supports incompatible version %d.%02d\n", + mjr,mnr); + ACTION("Exiting\n"); + exit(1); + } + } + if (file) { + ok= True; + setScanState(inputFile,1); + if ((inputFormat==INPUT_XKB)&&(XKBParseFile(file,&rtrn)&&(rtrn!=NULL))){ + fclose(file); + mapToUse= rtrn; + if (inputMap!=NULL) { + while ((mapToUse)&&(!uStringEqual(mapToUse->name,inputMap))) { + mapToUse= (XkbFile *)mapToUse->common.next; + } + if (!mapToUse) { + FATAL2("No map named \"%s\" in \"%s\"\n",inputMap, + inputFile); + /* NOTREACHED */ + } + } + else if (rtrn->common.next!=NULL) { + mapToUse= rtrn; + for (;mapToUse;mapToUse= (XkbFile*)mapToUse->common.next) { + if (mapToUse->flags&XkbLC_Default) + break; + } + if (!mapToUse) { + mapToUse= rtrn; + if (warningLevel>4) { + WARN1("No map specified, but \"%s\" has several\n", + inputFile); + ACTION1("Using the first defined map, \"%s\"\n", + mapToUse->name); + } + } + } + bzero((char *)&result,sizeof(result)); + result.type= mapToUse->type; + if ((result.xkb= XkbAllocKeyboard())==NULL) { + WSGO("Cannot allocate keyboard description\n"); + /* NOTREACHED */ + } + switch (mapToUse->type) { + case XkmSemanticsFile: + case XkmLayoutFile: + case XkmKeymapFile: + ok= CompileKeymap(mapToUse,&result,MergeReplace); + break; + case XkmKeyNamesIndex: + ok= CompileKeycodes(mapToUse,&result,MergeReplace); + break; + case XkmTypesIndex: + ok= CompileKeyTypes(mapToUse,&result,MergeReplace); + break; + case XkmSymbolsIndex: + /* if it's just symbols, invent key names */ + result.xkb->flags|= AutoKeyNames; + ok= False; + break; + case XkmCompatMapIndex: + ok= CompileCompatMap(mapToUse,&result,MergeReplace,NULL); + break; + case XkmGeometryFile: + case XkmGeometryIndex: + /* if it's just a geometry, invent key names */ + result.xkb->flags|= AutoKeyNames; + ok= CompileGeometry(mapToUse,&result,MergeReplace); + break; + default: + WSGO1("Unknown file type %d\n",mapToUse->type); + ok= False; + break; + } + } + else if (inputFormat==INPUT_XKM) { + unsigned tmp; + bzero((char *)&result,sizeof(result)); + if ((result.xkb= XkbAllocKeyboard())==NULL) { + WSGO("Cannot allocate keyboard description\n"); + /* NOTREACHED */ + } + tmp= XkmReadFile(file,0,XkmKeymapLegal,&result); + if (tmp==XkmKeymapLegal) { + ERROR1("Cannot read XKM file \"%s\"\n",inputFile); + ok= False; + } + } + else { + INFO1("Errors encountered in %s; not compiled.\n",inputFile); + ok= False; + } + } + else if (inDpy!=NULL) { + bzero((char *)&result,sizeof(result)); + result.type= XkmKeymapFile; + result.xkb= XkbGetMap(inDpy,XkbAllMapComponentsMask,XkbUseCoreKbd); + if (result.xkb==NULL) + WSGO("Cannot load keyboard description\n"); + if (XkbGetIndicatorMap(inDpy,~0,result.xkb)!=Success) + WSGO("Could not load indicator map\n"); + if (XkbGetControls(inDpy,XkbAllControlsMask,result.xkb)!=Success) + WSGO("Could not load keyboard controls\n"); + if (XkbGetCompatMap(inDpy,XkbAllCompatMask,result.xkb)!=Success) + WSGO("Could not load compatibility map\n"); + if (XkbGetNames(inDpy,XkbAllNamesMask,result.xkb)!=Success) + WSGO("Could not load names\n"); + if ((status=XkbGetGeometry(inDpy,result.xkb))!=Success) { + if (warningLevel>3) { + char buf[100]; + buf[0]= '\0'; + XGetErrorText(inDpy,status,buf,100); + WARN1("Could not load keyboard geometry for %s\n",inDpyName); + ACTION1("%s\n",buf); + ACTION("Resulting keymap file will not describe geometry\n"); + } + } + if (computeDflts) + ok= (ComputeKbdDefaults(result.xkb)==Success); + else ok= True; + } + else { + fprintf(stderr,"Cannot open \"%s\" to compile\n",inputFile); + ok= 0; + } + if (ok) { + FILE *out = stdout; + if ((inDpy!=outDpy)&& + (XkbChangeKbdDisplay(outDpy,&result)!=Success)) { + WSGO2("Error converting keyboard display from %s to %s\n", + inDpyName,outDpyName); + exit(1); + } + if (outputFile!=NULL) { + if (uStringEqual(outputFile,"-")) + outputFile= "stdout"; + else { + /* + * fix to prevent symlink attack (e.g., + * ln -s /etc/passwd /var/tmp/server-0.xkm) + */ + /* + * this patch may have POSIX, Linux, or GNU libc bias + * -- Branden Robinson + */ + int outputFileFd; + int binMode = 0; + const char *openMode = "w"; + unlink(outputFile); +#ifdef O_BINARY + switch (outputFormat) { + case WANT_XKM_FILE: + binMode = O_BINARY; + openMode = "wb"; + break; + default: + binMode = 0; + break; + } +#endif + outputFileFd= open(outputFile, O_WRONLY|O_CREAT|O_EXCL, + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH|binMode); + if (outputFileFd<0) { + ERROR1("Cannot open \"%s\" to write keyboard description\n", + outputFile); + ACTION("Exiting\n"); + exit(1); + } +#ifndef WIN32 + out= fdopen(outputFileFd, openMode); +#else + close(outputFileFd); + out= fopen(outputFile, "wb"); +#endif + /* end BR */ + if (out==NULL) { + ERROR1("Cannot open \"%s\" to write keyboard description\n", + outputFile); + ACTION("Exiting\n"); + exit(1); + } + } + } + switch (outputFormat) { + case WANT_XKM_FILE: + ok= XkbWriteXKMFile(out,&result); + break; + case WANT_XKB_FILE: + ok= XkbWriteXKBFile(out,&result,showImplicit,NULL,NULL); + break; + case WANT_C_HDR: + ok= XkbWriteCFile(out,outputFile,&result); + break; + case WANT_X_SERVER: + if (!(ok= XkbWriteToServer(&result))) { + ERROR2("%s in %s\n",_XkbErrMessages[_XkbErrCode], + _XkbErrLocation?_XkbErrLocation:"unknown"); + ACTION1("Couldn't write keyboard description to %s\n", + outDpyName); + } + break; + default: + WSGO1("Unknown output format %d\n",outputFormat); + ACTION("No output file created\n"); + ok= False; + break; + } + if (outputFormat!=WANT_X_SERVER) { + fclose(out); + if (!ok) { + ERROR2("%s in %s\n",_XkbErrMessages[_XkbErrCode], + _XkbErrLocation?_XkbErrLocation:"unknown"); + ACTION1("Output file \"%s\" removed\n",outputFile); + unlink(outputFile); + } + } + } + if (inDpy) + XCloseDisplay(inDpy); + inDpy= NULL; + if (outDpy) + XCloseDisplay(outDpy); + uFinishUp(); + return (ok==0); +} diff --git a/xkbcomp/xkbcomp.h b/xkbcomp/xkbcomp.h new file mode 100644 index 0000000..b9b9cae --- /dev/null +++ b/xkbcomp/xkbcomp.h @@ -0,0 +1,380 @@ +/* $Xorg: xkbcomp.h,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/xkbcomp.h,v 3.8 2001/12/19 21:30:30 dawes Exp $ */ + +#ifndef XKBCOMP_H +#define XKBCOMP_H 1 + +#ifndef DEBUG_VAR +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR debugFlags +#endif + +#include +#include + +#include "utils.h" + +#include +#include + +extern char *scanFile; + +#define TypeUnknown 0 +#define TypeBoolean 1 +#define TypeInt 2 +#define TypeFloat 3 +#define TypeString 4 +#define TypeAction 5 +#define TypeKeyName 6 +#define TypeSymbols 7 + +#define StmtUnknown 0 +#define StmtInclude 1 +#define StmtKeycodeDef 2 +#define StmtKeyAliasDef 3 +#define StmtExpr 4 +#define StmtVarDef 5 +#define StmtKeyTypeDef 6 +#define StmtInterpDef 7 +#define StmtVModDef 8 +#define StmtSymbolsDef 9 +#define StmtModMapDef 10 +#define StmtGroupCompatDef 11 +#define StmtIndicatorMapDef 12 +#define StmtIndicatorNameDef 13 +#define StmtOutlineDef 14 +#define StmtShapeDef 15 +#define StmtKeyDef 16 +#define StmtRowDef 17 +#define StmtSectionDef 18 +#define StmtOverlayKeyDef 19 +#define StmtOverlayDef 20 +#define StmtDoodadDef 21 + +#define FileSymInterp 100 + +typedef struct _ParseCommon { + unsigned stmtType; + struct _ParseCommon *next; +} ParseCommon; + +#define ExprValue 0 +#define ExprIdent 1 +#define ExprActionDecl 2 +#define ExprFieldRef 3 +#define ExprArrayRef 4 +#define ExprKeysymList 5 +#define ExprActionList 6 +#define ExprCoord 7 + +#define OpAdd 20 +#define OpSubtract 21 +#define OpMultiply 22 +#define OpDivide 23 +#define OpAssign 24 +#define OpNot 25 +#define OpNegate 26 +#define OpInvert 27 +#define OpUnaryPlus 28 + +#define MergeDefault 0 +#define MergeAugment 1 +#define MergeOverride 2 +#define MergeReplace 3 +#define MergeAltForm 4 + +#define AutoKeyNames (1L << 0) +#define CreateKeyNames(x) ((x)->flags&AutoKeyNames) + +extern unsigned warningLevel; +extern unsigned optionalParts; + +typedef struct _IncludeStmt { + ParseCommon common; + unsigned merge; + char *stmt; + char *file; + char *map; + char *modifier; + char *path; + struct _IncludeStmt *next; +} IncludeStmt; + +typedef struct _Expr { + ParseCommon common; + unsigned op; + unsigned type; + union { + struct { + struct _Expr *left; + struct _Expr *right; + } binary; + struct { + Atom element; + Atom field; + } field; + struct { + Atom element; + Atom field; + struct _Expr *entry; + } array; + struct { + Atom name; + struct _Expr *args; + } action; + struct { + int nSyms; + int szSyms; + KeySym * syms; + } list; + struct { + int x; + int y; + } coord; + struct _Expr *child; + Atom str; + unsigned uval; + int ival; + char keyName[5]; + Opaque ptr; + } value; +} ExprDef; + +typedef struct _VarDef { + ParseCommon common; + unsigned merge; + ExprDef *name; + ExprDef *value; +} VarDef; + +typedef struct _VModDef { + ParseCommon common; + unsigned merge; + Atom name; + ExprDef *value; +} VModDef; + +typedef struct _KeycodeDef { + ParseCommon common; + unsigned merge; + char name[5]; + ExprDef *value; +} KeycodeDef; + +typedef struct _KeyAliasDef { + ParseCommon common; + unsigned merge; + char alias[5]; + char real[5]; +} KeyAliasDef; + +typedef struct _KeyTypeDef { + ParseCommon common; + unsigned merge; + Atom name; + VarDef *body; +} KeyTypeDef; + +typedef struct _SymbolsDef { + ParseCommon common; + unsigned merge; + char keyName[5]; + ExprDef * symbols; +} SymbolsDef; + +typedef struct _ModMapDef { + ParseCommon common; + unsigned merge; + Atom modifier; + ExprDef * keys; +} ModMapDef; + +typedef struct _GroupCompatDef { + ParseCommon common; + unsigned merge; + int group; + ExprDef * def; +} GroupCompatDef; + +typedef struct _InterpDef { + ParseCommon common; + unsigned merge; + KeySym sym; + ExprDef *match; + VarDef *def; +} InterpDef; + +typedef struct _IndicatorNameDef { + ParseCommon common; + unsigned merge; + int ndx; + ExprDef * name; + Bool virtual; +} IndicatorNameDef; + +typedef struct _OutlineDef { + ParseCommon common; + Atom field; + int nPoints; + ExprDef * points; +} OutlineDef; + +typedef struct _ShapeDef { + ParseCommon common; + unsigned merge; + Atom name; + int nOutlines; + OutlineDef * outlines; +} ShapeDef; + +typedef struct _KeyDef { + ParseCommon common; + unsigned defined; + char * name; + ExprDef * expr; +} KeyDef; + +typedef struct _RowDef { + ParseCommon common; + int nKeys; + KeyDef * keys; +} RowDef; + +typedef struct _SectionDef { + ParseCommon common; + unsigned merge; + Atom name; + int nRows; + RowDef * rows; +} SectionDef; + +typedef struct _OverlayKeyDef { + ParseCommon common; + char over[5]; + char under[5]; +} OverlayKeyDef; + +typedef struct _OverlayDef { + ParseCommon common; + unsigned merge; + Atom name; + int nKeys; + OverlayKeyDef * keys; +} OverlayDef; + +typedef struct _DoodadDef { + ParseCommon common; + unsigned merge; + unsigned type; + Atom name; + VarDef * body; +} DoodadDef; + +/* IndicatorMapDef doesn't use the type field, but the rest of the fields + need to be at the same offsets as in DoodadDef. Use #define to avoid + any strict aliasing problems. */ +#define IndicatorMapDef DoodadDef + +typedef struct _XkbFile { + ParseCommon common; + int type; + char * topName; + char * name; + ParseCommon *defs; + int id; + unsigned flags; + Bool compiled; +} XkbFile; + +extern Bool CompileKeymap( + XkbFile * /* file */, + XkbFileInfo * /* result */, + unsigned /* merge */ +); + +extern Bool CompileKeycodes( + XkbFile * /* file */, + XkbFileInfo * /* result */, + unsigned /* merge */ +); + +extern Bool CompileGeometry( + XkbFile * /* file */, + XkbFileInfo * /* result */, + unsigned /* merge */ +); + +extern Bool CompileKeyTypes( + XkbFile * /* file */, + XkbFileInfo * /* result */, + unsigned /* merge */ +); + +typedef struct _LEDInfo *LEDInfoPtr; + +extern Bool CompileCompatMap( + XkbFile * /* file */, + XkbFileInfo * /* result */, + unsigned /* merge */, + LEDInfoPtr * /* unboundLEDs */ +); + +extern Bool CompileSymbols( + XkbFile * /* file */, + XkbFileInfo * /* result */, + unsigned /* merge */ +); + +#define WantLongListing (1<<0) +#define WantPartialMaps (1<<1) +#define WantHiddenMaps (1<<2) +#define WantFullNames (1<<3) +#define ListRecursive (1<<4) + +extern char * rootDir; +extern unsigned verboseLevel; +extern unsigned dirsToStrip; + +extern Bool AddListing( + char * /* file */, + char * /* map */ +); + +extern Bool AddMatchingFiles( + char * /* head_in */ +); + +extern int AddMapOnly( + char * /* map */ +); + +extern int GenerateListing( + char * /* filename */ +); + +#endif /* XKBCOMP_H */ diff --git a/xkbcomp/xkbcomp.man b/xkbcomp/xkbcomp.man new file mode 100644 index 0000000..aa18d3e --- /dev/null +++ b/xkbcomp/xkbcomp.man @@ -0,0 +1,109 @@ +.\" $Xorg: xkbcomp.man,v 1.3 2000/08/17 19:54:33 cpqbld Exp $ +.\" +.\" +.\" +.\" +.\" $XFree86: xc/programs/xkbcomp/xkbcomp.man,v 1.11 2003/07/28 21:57:02 herrb Exp $ +.\" +.TH XKBCOMP 1 __xorgversion__ +.SH NAME +xkbcomp \- compile XKB keyboard description +.SH SYNOPSIS +.B xkbcomp +[option] source [ destination ] +.SH DESCRIPTION +.PP +The +.I xkbcomp +keymap compiler converts a description of an XKB keymap into one of several +output formats. The most common use for xkbcomp is to create a compiled +keymap file (.xkm extension) which can be read directly by XKB-capable X +servers or utilities. The keymap compiler can also produce C header +files or XKB source files. The C header files produced by xkbcomp can be +included by X servers or utilities that need a built-in default keymap. +The XKB source files produced by \fIxkbcomp\fP are fully resolved and can be +used to verify that the files which typically make up an XKB keymap +are merged correctly or to create a single file which contains a complete +description of the keymap. +.PP +The \fIsource\fP may specify an X display, or an \fI.xkb\fP or \fI.xkm\fP +file; unless explicitly specified, the format of \fIdestination\fP +depends on the format of the source. Compiling a \fI.xkb\fP (keymap source) +file generates a \fI.xkm\fP (compiled keymap file) by default. If the +source is a \fI.xkm\fP file or an X display, \fIxkbcomp\fP generates a +keymap source file by default. +.PP +If the \fIdestination\fP is an X display, the keymap for the display +is updated with the compiled keymap. +.PP +The name of the \fIdestination\fP is usually computed from the name +of the source, with the extension replaced as appropriate. When compiling +a single map from a file which contains several maps, \fIxkbcomp\fP constructs +the destination file name by appending an appropriate extension to the +name of the map to be used. +.SH OPTIONS +.TP 8 +.B \-a +Show all keyboard information, reporting implicit or derived information +as a comment. Only affects \fI.xkb\fP format output. +.TP 8 +.B \-C +Produce a C header file as output (.h extension). +.TP 8 +.B \-dflts +Compute defaults for any missing components, such as key names. +.TP 8 +.B \-I\fIdir\fP +Specifies top-level directories to be searched for files included by the +keymap description. After all directories specified by \-I options +have been searched, the current directory and finally, the default +xkb directory (usually __projectroot__/lib/X11/xkb) will be searched. +.sp +To prevent the current and default directories from being searched, +use the \-I option alone (i.e. without a directory), before any \-I +options that specify the directories you do want searched. +.TP 8 +.B \-l +List maps that specify the \fImap\fP pattern in any files listed on the +command line (not implemented yet). +.TP 8 +.B \-m\ \fIname\fP +Specifies a map to be compiled from an file with multiple entries. +.TP 8 +.B \-merge +Merge the compiled information with the map from the server (not implemented +yet). +.TP 8 +.B \-o\ \fIname\fP +Specifies a name for the generated output file. The default is the name of +the source file with an appropriate extension for the output format. +.TP 8 +.B \-opt\ \fIparts\fP +Specifies a list of optional parts. Compilation errors in any optional parts +are not fatal. Parts may consist of any combination of the letters \fIc\fP, +\fIg\fP,\fIk\fP,\fIs\fP,\fIt\fP which specify the compatibility map, geometry, +keycodes, symbols and types, respectively. +.TP 8 +.B -R\fIdir\fP +Specifies the root directory for relative path names. +.TP 8 +.B -synch +Force synchronization for X requests. +.TP 8 +.B \-w\ \fIlvl\fP +Controls the reporting of warnings during compilation. A warning level +of 0 disables all warnings; a warning level of 10 enables them all. +.TP 8 +.B \-xkb +Generate a source description of the keyboard as output (.xkb extension). +.TP 8 +.B \-xkm +Generate a compiled keymap file as output (.xkm extension). +.SH "SEE ALSO" +X(__miscmansuffix__) +.SH COPYRIGHT +Copyright 1994, Silicon Graphics Computer Systems and X Consortium, Inc. +.br +See \fIX(__miscmansuffix__)\fP for a full statement of rights and permissions. +.SH AUTHOR +Erik Fortune, Silicon Graphics diff --git a/xkbcomp/xkbparse.y b/xkbcomp/xkbparse.y new file mode 100644 index 0000000..b50b9e8 --- /dev/null +++ b/xkbcomp/xkbparse.y @@ -0,0 +1,794 @@ +/* $Xorg: xkbparse.y,v 1.3 2000/08/17 19:54:34 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/xkbparse.y,v 3.11tsi Exp $ */ + +%token + END_OF_FILE 0 + ERROR_TOK 255 + XKB_KEYMAP 1 + XKB_KEYCODES 2 + XKB_TYPES 3 + XKB_SYMBOLS 4 + XKB_COMPATMAP 5 + XKB_GEOMETRY 6 + XKB_SEMANTICS 7 + XKB_LAYOUT 8 + INCLUDE 10 + OVERRIDE 11 + AUGMENT 12 + REPLACE 13 + ALTERNATE 14 + VIRTUAL_MODS 20 + TYPE 21 + INTERPRET 22 + ACTION_TOK 23 + KEY 24 + ALIAS 25 + GROUP 26 + MODIFIER_MAP 27 + INDICATOR 28 + SHAPE 29 + KEYS 30 + ROW 31 + SECTION 32 + OVERLAY 33 + TEXT 34 + OUTLINE 35 + SOLID 36 + LOGO 37 + VIRTUAL 38 + EQUALS 40 + PLUS 41 + MINUS 42 + DIVIDE 43 + TIMES 44 + OBRACE 45 + CBRACE 46 + OPAREN 47 + CPAREN 48 + OBRACKET 49 + CBRACKET 50 + DOT 51 + COMMA 52 + SEMI 53 + EXCLAM 54 + INVERT 55 + STRING 60 + INTEGER 61 + FLOAT 62 + IDENT 63 + KEYNAME 64 + PARTIAL 70 + DEFAULT 71 + HIDDEN 72 + ALPHANUMERIC_KEYS 73 + MODIFIER_KEYS 74 + KEYPAD_KEYS 75 + FUNCTION_KEYS 76 + ALTERNATE_GROUP 77 +%{ +#ifdef DEBUG +#define YYDEBUG 1 +#endif +#define DEBUG_VAR parseDebug +#include "parseutils.h" +#include +#include +#include + + +%} +%right EQUALS +%left PLUS MINUS +%left TIMES DIVIDE +%left EXCLAM INVERT +%left OPAREN +%start XkbFile +%union { + int ival; + unsigned uval; + char *str; + Atom sval; + ParseCommon *any; + ExprDef *expr; + VarDef *var; + VModDef *vmod; + InterpDef *interp; + KeyTypeDef *keyType; + SymbolsDef *syms; + ModMapDef *modMask; + GroupCompatDef *groupCompat; + IndicatorMapDef *ledMap; + IndicatorNameDef *ledName; + KeycodeDef *keyName; + KeyAliasDef *keyAlias; + ShapeDef *shape; + SectionDef *section; + RowDef *row; + KeyDef *key; + OverlayDef *overlay; + OverlayKeyDef *olKey; + OutlineDef *outline; + DoodadDef *doodad; + XkbFile *file; +} +%type Number Integer Float +%type XkbCompositeType FileType MergeMode OptMergeMode KeySym +%type DoodadType Flag Flags OptFlags +%type KeyName MapName OptMapName +%type FieldSpec Ident Element String +%type DeclList Decl +%type OptExprList ExprList Expr Term Lhs Terminal ArrayInit +%type OptKeySymList KeySymList Action ActionList Coord CoordList +%type VarDecl VarDeclList SymbolsBody SymbolsVarDecl +%type VModDecl VModDefList VModDef +%type InterpretDecl InterpretMatch +%type KeyTypeDecl +%type SymbolsDecl +%type ModMapDecl +%type GroupCompatDecl +%type IndicatorMapDecl +%type IndicatorNameDecl +%type KeyNameDecl +%type KeyAliasDecl +%type ShapeDecl +%type
SectionDecl +%type SectionBody SectionBodyItem +%type RowBody RowBodyItem Keys Key +%type OverlayDecl +%type OverlayKeyList OverlayKey +%type OutlineList OutlineInList +%type DoodadDecl +%type XkbFile XkbMapConfigList XkbMapConfig XkbConfig +%type XkbCompositeMap XkbCompMapList +%% +XkbFile : XkbCompMapList + { $$= rtrnValue= $1; } + | XkbMapConfigList + { $$= rtrnValue= $1; } + | XkbConfig + { $$= rtrnValue= $1; } + ; + +XkbCompMapList : XkbCompMapList XkbCompositeMap + { $$= (XkbFile *)AppendStmt(&$1->common,&$2->common); } + | XkbCompositeMap + { $$= $1; } + ; + +XkbCompositeMap : OptFlags XkbCompositeType OptMapName OBRACE + XkbMapConfigList + CBRACE SEMI + { $$= CreateXKBFile($2,$3,&$5->common,$1); } + ; + +XkbCompositeType: XKB_KEYMAP { $$= XkmKeymapFile; } + | XKB_SEMANTICS { $$= XkmSemanticsFile; } + | XKB_LAYOUT { $$= XkmLayoutFile; } + ; + +XkbMapConfigList : XkbMapConfigList XkbMapConfig + { $$= (XkbFile *)AppendStmt(&$1->common,&$2->common); } + | XkbMapConfig + { $$= $1; } + ; + +XkbMapConfig : OptFlags FileType OptMapName OBRACE + DeclList + CBRACE SEMI + { $$= CreateXKBFile($2,$3,$5,$1); } + ; + +XkbConfig : OptFlags FileType OptMapName DeclList + { $$= CreateXKBFile($2,$3,$4,$1); } + ; + + +FileType : XKB_KEYCODES { $$= XkmKeyNamesIndex; } + | XKB_TYPES { $$= XkmTypesIndex; } + | XKB_COMPATMAP { $$= XkmCompatMapIndex; } + | XKB_SYMBOLS { $$= XkmSymbolsIndex; } + | XKB_GEOMETRY { $$= XkmGeometryIndex; } + ; + +OptFlags : Flags { $$= $1; } + | { $$= 0; } + ; + +Flags : Flags Flag { $$= (($1)|($2)); } + | Flag { $$= $1; } + ; + +Flag : PARTIAL { $$= XkbLC_Partial; } + | DEFAULT { $$= XkbLC_Default; } + | HIDDEN { $$= XkbLC_Hidden; } + | ALPHANUMERIC_KEYS { $$= XkbLC_AlphanumericKeys; } + | MODIFIER_KEYS { $$= XkbLC_ModifierKeys; } + | KEYPAD_KEYS { $$= XkbLC_KeypadKeys; } + | FUNCTION_KEYS { $$= XkbLC_FunctionKeys; } + | ALTERNATE_GROUP { $$= XkbLC_AlternateGroup; } + ; + +DeclList : DeclList Decl + { $$= AppendStmt($1,$2); } + | { $$= NULL; } + ; + +Decl : OptMergeMode VarDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode VModDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode InterpretDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode KeyNameDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode KeyAliasDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode KeyTypeDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode SymbolsDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode ModMapDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode GroupCompatDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode IndicatorMapDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode IndicatorNameDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode ShapeDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode SectionDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | OptMergeMode DoodadDecl + { + $2->merge= StmtSetMerge(&$2->common,$1); + $$= &$2->common; + } + | MergeMode STRING + { + if ($1==MergeAltForm) { + yyerror("cannot use 'alternate' to include other maps"); + $$= &IncludeCreate(scanStr,MergeDefault)->common; + } + else { + $$= &IncludeCreate(scanStr,$1)->common; + } + } + ; + +VarDecl : Lhs EQUALS Expr SEMI + { $$= VarCreate($1,$3); } + | Ident SEMI + { $$= BoolVarCreate($1,1); } + | EXCLAM Ident SEMI + { $$= BoolVarCreate($2,0); } + ; + +KeyNameDecl : KeyName EQUALS Expr SEMI + { + KeycodeDef *def; + + def= KeycodeCreate($1,$3); + if ($1) + free($1); + $$= def; + } + ; + +KeyAliasDecl : ALIAS KeyName EQUALS KeyName SEMI + { + KeyAliasDef *def; + def= KeyAliasCreate($2,$4); + if ($2) free($2); + if ($4) free($4); + $$= def; + } + ; + +VModDecl : VIRTUAL_MODS VModDefList SEMI + { $$= $2; } + ; + +VModDefList : VModDefList COMMA VModDef + { $$= (VModDef *)AppendStmt(&$1->common,&$3->common); } + | VModDef + { $$= $1; } + ; + +VModDef : Ident + { $$= VModCreate($1,NULL); } + | Ident EQUALS Expr + { $$= VModCreate($1,$3); } + ; + +InterpretDecl : INTERPRET InterpretMatch OBRACE + VarDeclList + CBRACE SEMI + { + $2->def= $4; + $$= $2; + } + ; + +InterpretMatch : KeySym PLUS Expr + { $$= InterpCreate((KeySym)$1,$3); } + | KeySym + { $$= InterpCreate((KeySym)$1,NULL); } + ; + +VarDeclList : VarDeclList VarDecl + { $$= (VarDef *)AppendStmt(&$1->common,&$2->common); } + | VarDecl + { $$= $1; } + ; + +KeyTypeDecl : TYPE String OBRACE + VarDeclList + CBRACE SEMI + { $$= KeyTypeCreate($2,$4); } + ; + +SymbolsDecl : KEY KeyName OBRACE + SymbolsBody + CBRACE SEMI + { $$= SymbolsCreate($2,(ExprDef *)$4); } + ; + +SymbolsBody : SymbolsBody COMMA SymbolsVarDecl + { $$= (VarDef *)AppendStmt(&$1->common,&$3->common); } + | SymbolsVarDecl + { $$= $1; } + | { $$= NULL; } + ; + +SymbolsVarDecl : Lhs EQUALS Expr + { $$= VarCreate($1,$3); } + | Lhs EQUALS ArrayInit + { $$= VarCreate($1,$3); } + | Ident + { $$= BoolVarCreate($1,1); } + | EXCLAM Ident + { $$= BoolVarCreate($2,0); } + | ArrayInit + { $$= VarCreate(NULL,$1); } + ; + +ArrayInit : OBRACKET OptKeySymList CBRACKET + { $$= $2; } + | OBRACKET ActionList CBRACKET + { $$= ExprCreateUnary(ExprActionList,TypeAction,$2); } + ; + +GroupCompatDecl : GROUP Integer EQUALS Expr SEMI + { $$= GroupCompatCreate($2,$4); } + ; + +ModMapDecl : MODIFIER_MAP Ident OBRACE ExprList CBRACE SEMI + { $$= ModMapCreate($2,$4); } + ; + +IndicatorMapDecl: INDICATOR String OBRACE VarDeclList CBRACE SEMI + { $$= IndicatorMapCreate($2,$4); } + ; + +IndicatorNameDecl: INDICATOR Integer EQUALS Expr SEMI + { $$= IndicatorNameCreate($2,$4,False); } + | VIRTUAL INDICATOR Integer EQUALS Expr SEMI + { $$= IndicatorNameCreate($3,$5,True); } + ; + +ShapeDecl : SHAPE String OBRACE OutlineList CBRACE SEMI + { $$= ShapeDeclCreate($2,(OutlineDef *)&$4->common); } + | SHAPE String OBRACE CoordList CBRACE SEMI + { + OutlineDef *outlines; + outlines= OutlineCreate(None,$4); + $$= ShapeDeclCreate($2,outlines); + } + ; + +SectionDecl : SECTION String OBRACE SectionBody CBRACE SEMI + { $$= SectionDeclCreate($2,$4); } + ; + +SectionBody : SectionBody SectionBodyItem + { $$=(RowDef *)AppendStmt(&$1->common,&$2->common);} + | SectionBodyItem + { $$= $1; } + ; + +SectionBodyItem : ROW OBRACE RowBody CBRACE SEMI + { $$= RowDeclCreate($3); } + | VarDecl + { $$= (RowDef *)$1; } + | DoodadDecl + { $$= (RowDef *)$1; } + | IndicatorMapDecl + { $$= (RowDef *)$1; } + | OverlayDecl + { $$= (RowDef *)$1; } + ; + +RowBody : RowBody RowBodyItem + { $$=(KeyDef *)AppendStmt(&$1->common,&$2->common);} + | RowBodyItem + { $$= $1; } + ; + +RowBodyItem : KEYS OBRACE Keys CBRACE SEMI + { $$= $3; } + | VarDecl + { $$= (KeyDef *)$1; } + ; + +Keys : Keys COMMA Key + { $$=(KeyDef *)AppendStmt(&$1->common,&$3->common);} + | Key + { $$= $1; } + ; + +Key : KeyName + { $$= KeyDeclCreate($1,NULL); } + | OBRACE ExprList CBRACE + { $$= KeyDeclCreate(NULL,$2); } + ; + +OverlayDecl : OVERLAY String OBRACE OverlayKeyList CBRACE SEMI + { $$= OverlayDeclCreate($2,$4); } + ; + +OverlayKeyList : OverlayKeyList COMMA OverlayKey + { + $$= (OverlayKeyDef *) + AppendStmt(&$1->common,&$3->common); + } + | OverlayKey + { $$= $1; } + ; + +OverlayKey : KeyName EQUALS KeyName + { $$= OverlayKeyCreate($1,$3); } + ; + +OutlineList : OutlineList COMMA OutlineInList + { $$=(OutlineDef *)AppendStmt(&$1->common,&$3->common);} + | OutlineInList + { $$= $1; } + ; + +OutlineInList : OBRACE CoordList CBRACE + { $$= OutlineCreate(None,$2); } + | Ident EQUALS OBRACE CoordList CBRACE + { $$= OutlineCreate($1,$4); } + | Ident EQUALS Expr + { $$= OutlineCreate($1,$3); } + ; + +CoordList : CoordList COMMA Coord + { $$= (ExprDef *)AppendStmt(&$1->common,&$3->common); } + | Coord + { $$= $1; } + ; + +Coord : OBRACKET Number COMMA Number CBRACKET + { + ExprDef *expr; + expr= ExprCreate(ExprCoord,TypeUnknown); + expr->value.coord.x= $2; + expr->value.coord.y= $4; + $$= expr; + } + ; + +DoodadDecl : DoodadType String OBRACE VarDeclList CBRACE SEMI + { $$= DoodadCreate($1,$2,$4); } + ; + +DoodadType : TEXT { $$= XkbTextDoodad; } + | OUTLINE { $$= XkbOutlineDoodad; } + | SOLID { $$= XkbSolidDoodad; } + | LOGO { $$= XkbLogoDoodad; } + ; + +FieldSpec : Ident { $$= $1; } + | Element { $$= $1; } + ; + +Element : ACTION_TOK + { $$= XkbInternAtom(NULL,"action",False); } + | INTERPRET + { $$= XkbInternAtom(NULL,"interpret",False); } + | TYPE + { $$= XkbInternAtom(NULL,"type",False); } + | KEY + { $$= XkbInternAtom(NULL,"key",False); } + | GROUP + { $$= XkbInternAtom(NULL,"group",False); } + | MODIFIER_MAP + {$$=XkbInternAtom(NULL,"modifier_map",False);} + | INDICATOR + { $$= XkbInternAtom(NULL,"indicator",False); } + | SHAPE + { $$= XkbInternAtom(NULL,"shape",False); } + | ROW + { $$= XkbInternAtom(NULL,"row",False); } + | SECTION + { $$= XkbInternAtom(NULL,"section",False); } + | TEXT + { $$= XkbInternAtom(NULL,"text",False); } + ; + +OptMergeMode : MergeMode { $$= $1; } + | { $$= MergeDefault; } + ; + +MergeMode : INCLUDE { $$= MergeDefault; } + | AUGMENT { $$= MergeAugment; } + | OVERRIDE { $$= MergeOverride; } + | REPLACE { $$= MergeReplace; } + | ALTERNATE { $$= MergeAltForm; } + ; + +OptExprList : ExprList { $$= $1; } + | { $$= NULL; } + ; + +ExprList : ExprList COMMA Expr + { $$= (ExprDef *)AppendStmt(&$1->common,&$3->common); } + | Expr + { $$= $1; } + ; + +Expr : Expr DIVIDE Expr + { $$= ExprCreateBinary(OpDivide,$1,$3); } + | Expr PLUS Expr + { $$= ExprCreateBinary(OpAdd,$1,$3); } + | Expr MINUS Expr + { $$= ExprCreateBinary(OpSubtract,$1,$3); } + | Expr TIMES Expr + { $$= ExprCreateBinary(OpMultiply,$1,$3); } + | Lhs EQUALS Expr + { $$= ExprCreateBinary(OpAssign,$1,$3); } + | Term + { $$= $1; } + ; + +Term : MINUS Term + { $$= ExprCreateUnary(OpNegate,$2->type,$2); } + | PLUS Term + { $$= ExprCreateUnary(OpUnaryPlus,$2->type,$2); } + | EXCLAM Term + { $$= ExprCreateUnary(OpNot,TypeBoolean,$2); } + | INVERT Term + { $$= ExprCreateUnary(OpInvert,$2->type,$2); } + | Lhs + { $$= $1; } + | FieldSpec OPAREN OptExprList CPAREN %prec OPAREN + { $$= ActionCreate($1,$3); } + | Terminal + { $$= $1; } + | OPAREN Expr CPAREN + { $$= $2; } + ; + +ActionList : ActionList COMMA Action + { $$= (ExprDef *)AppendStmt(&$1->common,&$3->common); } + | Action + { $$= $1; } + ; + +Action : FieldSpec OPAREN OptExprList CPAREN + { $$= ActionCreate($1,$3); } + ; + +Lhs : FieldSpec + { + ExprDef *expr; + expr= ExprCreate(ExprIdent,TypeUnknown); + expr->value.str= $1; + $$= expr; + } + | FieldSpec DOT FieldSpec + { + ExprDef *expr; + expr= ExprCreate(ExprFieldRef,TypeUnknown); + expr->value.field.element= $1; + expr->value.field.field= $3; + $$= expr; + } + | FieldSpec OBRACKET Expr CBRACKET + { + ExprDef *expr; + expr= ExprCreate(ExprArrayRef,TypeUnknown); + expr->value.array.element= None; + expr->value.array.field= $1; + expr->value.array.entry= $3; + $$= expr; + } + | FieldSpec DOT FieldSpec OBRACKET Expr CBRACKET + { + ExprDef *expr; + expr= ExprCreate(ExprArrayRef,TypeUnknown); + expr->value.array.element= $1; + expr->value.array.field= $3; + expr->value.array.entry= $5; + $$= expr; + } + ; + +Terminal : String + { + ExprDef *expr; + expr= ExprCreate(ExprValue,TypeString); + expr->value.str= $1; + $$= expr; + } + | Integer + { + ExprDef *expr; + expr= ExprCreate(ExprValue,TypeInt); + expr->value.ival= $1; + $$= expr; + } + | Float + { + ExprDef *expr; + expr= ExprCreate(ExprValue,TypeFloat); + expr->value.ival= $1; + $$= expr; + } + | KeyName + { + ExprDef *expr; + expr= ExprCreate(ExprValue,TypeKeyName); + memcpy(expr->value.keyName,$1,4); + free($1); + $$= expr; + } + ; + +OptKeySymList : KeySymList { $$= $1; } + | { $$= NULL; } + ; + +KeySymList : KeySymList COMMA KeySym + { $$= AppendKeysymList($1,(KeySym)$3); } + | KeySym + { $$= CreateKeysymList((KeySym)$1); } + ; + +KeySym : IDENT + { + KeySym sym; + if (LookupKeysym(scanStr,&sym)) + $$= sym; + else { + char buf[120]; + sprintf(buf,"expected keysym, got %s", + uStringText(scanStr)); + yyerror(buf); + yynerrs++; + $$= NoSymbol; + } + } + | SECTION + { + $$= XK_section; + } + | Integer + { + if ($1<10) $$= $1+'0'; /* XK_0 .. XK_9 */ + else $$= $1; + } + ; + +Number : FLOAT { $$= scanInt; } + | INTEGER { $$= scanInt*XkbGeomPtsPerMM; } + ; + +Float : FLOAT { $$= scanInt; } + ; + +Integer : INTEGER { $$= scanInt; } + ; + +KeyName : KEYNAME { $$= scanStr; scanStr= NULL; } + ; + +Ident : IDENT { $$= XkbInternAtom(NULL,scanStr,False); } + | DEFAULT { $$= XkbInternAtom(NULL,"default",False); } + ; + +String : STRING { $$= XkbInternAtom(NULL,scanStr,False); } + ; + +OptMapName : MapName { $$= $1; } + | { $$= NULL; } + ; + +MapName : STRING { $$= scanStr; scanStr= NULL; } + ; +%% +void +yyerror(char *s) +{ + if (warningLevel>0) { + (void)fprintf(stderr,"%s: line %d of %s\n",s,lineNum, + (scanFile?scanFile:"(unknown)")); + if ((scanStr)&&(warningLevel>3)) + (void)fprintf(stderr,"last scanned symbol is: %s\n",scanStr); + } + return; +} + + +int +yywrap(void) +{ + return 1; +} + diff --git a/xkbcomp/xkbpath.c b/xkbcomp/xkbpath.c new file mode 100644 index 0000000..ffedd5a --- /dev/null +++ b/xkbcomp/xkbpath.c @@ -0,0 +1,332 @@ +/* $Xorg: xkbpath.c,v 1.3 2000/08/17 19:54:34 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/xkbpath.c,v 3.7 2002/06/05 00:00:38 dawes Exp $ */ + +#include +#include + +#define DEBUG_VAR_NOT_LOCAL +#define DEBUG_VAR debugFlags +#include "utils.h" +#include +#include +#include "xkbpath.h" + +#ifndef DFLT_XKB_CONFIG_ROOT +#define DFLT_XKB_CONFIG_ROOT "/usr/lib/X11/xkb" +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#define PATH_CHUNK 8 + +static Bool noDefaultPath = False; +static int longestPath; +static int szPath; +static int nPathEntries; +static char ** includePath; + +Bool +XkbParseIncludeMap(char **str_inout,char **file_rtrn,char **map_rtrn, + char *nextop_rtrn, char **extra_data) +{ +char *tmp,*str,*next; + + str= *str_inout; + if ((*str=='+')||(*str=='|')) { + *file_rtrn= *map_rtrn= NULL; + *nextop_rtrn= *str; + next= str+1; + } + else if (*str=='%') { + *file_rtrn= *map_rtrn= NULL; + *nextop_rtrn= str[1]; + next= str+2; + } + else { + next= strpbrk(str,"|+"); + if (next) { + *nextop_rtrn= *next; + *next++= '\0'; + } + else { + *nextop_rtrn= '\0'; + next= NULL; + } + tmp= strchr(str,':'); + if (tmp != NULL) { + *tmp++ = '\0'; + *extra_data = uStringDup(tmp); + } + else { + *extra_data = NULL; + } + tmp= strchr(str,'('); + if (tmp==NULL) { + *file_rtrn= uStringDup(str); + *map_rtrn= NULL; + } + else if (str[0]=='(') { + uFree(*extra_data); + return False; + } + else { + *tmp++= '\0'; + *file_rtrn= uStringDup(str); + str= tmp; + tmp= strchr(str,')'); + if ((tmp==NULL)||(tmp[1]!='\0')) { + uFree(*file_rtrn); + uFree(*extra_data); + return False; + } + *tmp++= '\0'; + *map_rtrn= uStringDup(str); + } + } + if (*nextop_rtrn=='\0') + *str_inout= NULL; + else if ((*nextop_rtrn=='|')||(*nextop_rtrn=='+')) + *str_inout= next; + else return False; + return True; +} + +Bool +XkbInitIncludePath(void) +{ + szPath= PATH_CHUNK; + includePath= (char **)calloc(szPath,sizeof(char *)); + if (includePath==NULL) + return False; + return True; +} + +void +XkbAddDefaultDirectoriesToPath(void) +{ + if (noDefaultPath) + return; + XkbAddDirectoryToPath("."); + XkbAddDirectoryToPath(DFLT_XKB_CONFIG_ROOT); +} + +void +XkbClearIncludePath(void) +{ +register int i; + + if (szPath>0) { + for (i=0;i=PATH_MAX) { /* allow for '/' and at least one character */ + ERROR2("Path entry (%s) too long (maxiumum length is %d)\n", + dir,PATH_MAX-3); + return False; + } + if (len>longestPath) + longestPath= len; + if (nPathEntries>=szPath) { + szPath+= PATH_CHUNK; + includePath= (char **)realloc(includePath,szPath*sizeof(char *)); + if (includePath==NULL) { + WSGO("Allocation failed (includePath)\n"); + return False; + } + } + includePath[nPathEntries]= (char *)calloc(strlen(dir)+1,sizeof(char)); + if (includePath[nPathEntries]==NULL) { + WSGO1("Allocation failed (includePath[%d])\n",nPathEntries); + return False; + } + strcpy(includePath[nPathEntries++],dir); + return True; +} + +/***====================================================================***/ + +char * +XkbDirectoryForInclude(unsigned type) +{ +static char buf[32]; + + switch (type) { + case XkmSemanticsFile: + strcpy(buf,"semantics"); + break; + case XkmLayoutFile: + strcpy(buf,"layout"); + break; + case XkmKeymapFile: + strcpy(buf,"keymap"); + break; + case XkmKeyNamesIndex: + strcpy(buf,"keycodes"); + break; + case XkmTypesIndex: + strcpy(buf,"types"); + break; + case XkmSymbolsIndex: + strcpy(buf,"symbols"); + break; + case XkmCompatMapIndex: + strcpy(buf,"compat"); + break; + case XkmGeometryFile: + case XkmGeometryIndex: + strcpy(buf,"geometry"); + break; + default: + strcpy(buf,""); + break; + } + return buf; +} + +/***====================================================================***/ + +typedef struct _FileCacheEntry { + char * name; + unsigned type; + char * path; + void * data; + struct _FileCacheEntry * next; +} FileCacheEntry; +static FileCacheEntry *fileCache; + +void * +XkbAddFileToCache(char *name,unsigned type,char *path,void *data) +{ +FileCacheEntry *entry; + + for (entry=fileCache;entry!=NULL;entry=entry->next) { + if ((type==entry->type)&&(uStringEqual(name,entry->name))) { + void *old= entry->data; + WSGO2("Replacing file cache entry (%s/%d)\n",name,type); + entry->path= path; + entry->data= data; + return old; + } + } + entry= uTypedAlloc(FileCacheEntry); + if (entry!=NULL) { + entry->name= name; + entry->type= type; + entry->path= path; + entry->data= data; + entry->next= fileCache; + fileCache= entry; + } + return NULL; +} + +void * +XkbFindFileInCache(char *name,unsigned type,char **pathRtrn) +{ +FileCacheEntry *entry; + + for (entry=fileCache;entry!=NULL;entry=entry->next) { + if ((type==entry->type)&&(uStringEqual(name,entry->name))) { + *pathRtrn= entry->path; + return entry->data; + } + } + return NULL; +} + +/***====================================================================***/ + +FILE * +XkbFindFileInPath(char *name,unsigned type,char **pathRtrn) +{ +register int i; +FILE *file= NULL; +int nameLen,typeLen,pathLen; +char buf[PATH_MAX],*typeDir; + + typeDir= XkbDirectoryForInclude(type); + nameLen= strlen(name); + typeLen= strlen(typeDir); + for (i=0;i=PATH_MAX) { + ERROR2("File name (%s/%s) too long\n",includePath[i],name); + ACTION("Ignored\n"); + continue; + } + sprintf(buf,"%s/%s",includePath[i],name); + file= fopen(buf,"r"); + if (file!=NULL) + break; + else if (typeLen<1) + continue; + + if ((nameLen+typeLen+pathLen+2)>=PATH_MAX) { + ERROR3("File name (%s/%s/%s) too long\n",includePath[i],typeDir, + name); + ACTION("Ignored\n"); + continue; + } + sprintf(buf,"%s/%s/%s",includePath[i],typeDir,name); + file= fopen(buf,"r"); + if (file!=NULL) + break; + } + + if ((file!=NULL)&&(pathRtrn!=NULL)) { + *pathRtrn= (char *)calloc(strlen(buf)+1,sizeof(char)); + if (*pathRtrn!=NULL) + strcpy(*pathRtrn,buf); + } + return file; +} + diff --git a/xkbcomp/xkbpath.h b/xkbcomp/xkbpath.h new file mode 100644 index 0000000..64f07c9 --- /dev/null +++ b/xkbcomp/xkbpath.h @@ -0,0 +1,79 @@ +/* $XConsortium $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/xkbpath.h,v 1.3 2002/07/01 02:26:01 tsi Exp $ */ + +#ifndef _XKBPATH_H_ +#define _XKBPATH_H_ 1 + +extern Bool XkbInitIncludePath( + void +); + +extern void XkbClearIncludePath( + void +); + +extern void XkbAddDefaultDirectoriesToPath( + void +); + +extern Bool XkbAddDirectoryToPath( + char * /* dir */ +); + +extern char * XkbDirectoryForInclude( + unsigned /* type */ +); + +extern FILE *XkbFindFileInPath( + char * /* name */, + unsigned /* type */, + char ** /* pathRtrn */ +); + +extern void * XkbAddFileToCache( + char * /* name */, + unsigned /* type */, + char * /* path */, + void * /* data */ +); + +extern void * XkbFindFileInCache( + char * /* name */, + unsigned /* type */, + char ** /* pathRtrn */ +); + +extern Bool XkbParseIncludeMap( + char ** /* str_inout */, + char ** /* file_rtrn */, + char ** /* map_rtrn */, + char * /* nextop_rtrn */, + char ** /* extra_data */ +); + +#endif /* _XKBPATH_H_ */ diff --git a/xkbcomp/xkbscan.c b/xkbcomp/xkbscan.c new file mode 100644 index 0000000..8d70220 --- /dev/null +++ b/xkbcomp/xkbscan.c @@ -0,0 +1,468 @@ +/* $Xorg: xkbscan.c,v 1.3 2000/08/17 19:54:34 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbcomp/xkbscan.c,v 3.10 2001/01/17 23:45:45 dawes Exp $ */ + +#include +#include +#include +#include +#include + +#include "tokens.h" +#define DEBUG_VAR scanDebug +#include "utils.h" +#include "parseutils.h" + +FILE *yyin = NULL; + +static char scanFileBuf[1024]; +char * scanFile= scanFileBuf; +int lineNum= 0; + +int scanInt; +char *scanIntStr; +int scanIntClass; + +char *scanStr = NULL; +int scanStrLine= 0; + +#define BUFSIZE 512 +static int nInBuf = 0; +static char buf[BUFSIZE]; + +#ifdef DEBUG + +extern unsigned debugFlags; + +static char * +tokText(int tok) +{ +static char buf[32]; + + switch (tok) { + case END_OF_FILE: sprintf(buf, "END_OF_FILE");break; + case ERROR_TOK: sprintf(buf, "ERROR"); break; + + case XKB_KEYMAP: sprintf(buf, "XKB_KEYMAP"); break; + case XKB_KEYCODES: sprintf(buf, "XKB_KEYCODES"); break; + case XKB_TYPES: sprintf(buf, "XKB_TYPES"); break; + case XKB_SYMBOLS: sprintf(buf, "XKB_SYMBOLS"); break; + case XKB_COMPATMAP: sprintf(buf, "XKB_COMPATMAP"); break; + case XKB_GEOMETRY: sprintf(buf, "XKB_GEOMETRY"); break; + case XKB_SEMANTICS: sprintf(buf, "XKB_SEMANTICS"); break; + case XKB_LAYOUT: sprintf(buf, "XKB_LAYOUT"); break; + + case INCLUDE: sprintf(buf, "INCLUDE"); break; + case OVERRIDE: sprintf(buf, "OVERRIDE"); break; + case AUGMENT: sprintf(buf, "AUGMENT"); break; + case REPLACE: sprintf(buf, "REPLACE"); break; + case ALTERNATE: sprintf(buf, "ALTERNATE"); break; + + case VIRTUAL_MODS: sprintf(buf, "VIRTUAL_MODS"); break; + case TYPE: sprintf(buf, "TYPE"); break; + case INTERPRET: sprintf(buf, "INTERPRET"); break; + case ACTION_TOK: sprintf(buf, "ACTION"); break; + case KEY: sprintf(buf, "KEY"); break; + case ALIAS: sprintf(buf, "ALIAS"); break; + case GROUP: sprintf(buf, "GROUP"); break; + case MODIFIER_MAP: sprintf(buf, "MODIFIER_MAP"); break; + case INDICATOR: sprintf(buf, "INDICATOR"); break; + case SHAPE: sprintf(buf, "SHAPE"); break; + case KEYS: sprintf(buf, "KEYS"); break; + case ROW: sprintf(buf, "ROW"); break; + case SECTION: sprintf(buf, "SECTION"); break; + case OVERLAY: sprintf(buf, "OVERLAY"); break; + case TEXT: sprintf(buf, "TEXT"); break; + case OUTLINE: sprintf(buf, "OUTLINE"); break; + case SOLID: sprintf(buf, "SOLID"); break; + case LOGO: sprintf(buf, "LOGO"); break; + case VIRTUAL: sprintf(buf, "VIRTUAL"); break; + + case EQUALS: sprintf(buf, "EQUALS"); break; + case PLUS: sprintf(buf, "PLUS"); break; + case MINUS: sprintf(buf, "MINUS"); break; + case DIVIDE: sprintf(buf, "DIVIDE"); break; + case TIMES: sprintf(buf, "TIMES"); break; + case OBRACE: sprintf(buf, "OBRACE"); break; + case CBRACE: sprintf(buf, "CBRACE"); break; + case OPAREN: sprintf(buf, "OPAREN"); break; + case CPAREN: sprintf(buf, "CPAREN"); break; + case OBRACKET: sprintf(buf, "OBRACKET");break; + case CBRACKET: sprintf(buf, "CBRACKET");break; + case DOT: sprintf(buf, "DOT"); break; + case COMMA: sprintf(buf, "COMMA"); break; + case SEMI: sprintf(buf, "SEMI"); break; + case EXCLAM: sprintf(buf, "EXCLAM"); break; + case INVERT: sprintf(buf, "INVERT"); break; + + case STRING: sprintf(buf, "STRING (%s)",scanStr); break; + case INTEGER: sprintf(buf, "INTEGER (0x%x)",scanInt); break; + case FLOAT: sprintf(buf, "FLOAT (%d.%d)", + scanInt/XkbGeomPtsPerMM, + scanInt%XkbGeomPtsPerMM);break; + case IDENT: sprintf(buf, "IDENT (%s)",scanStr); break; + case KEYNAME: sprintf(buf, "KEYNAME (%s)",scanStr); break; + + case PARTIAL: sprintf(buf, "PARTIAL"); break; + case DEFAULT: sprintf(buf, "DEFAULT"); break; + case HIDDEN: sprintf(buf, "HIDDEN"); break; + + case ALPHANUMERIC_KEYS: sprintf(buf, "ALPHANUMERIC_KEYS"); break; + case MODIFIER_KEYS: sprintf(buf, "MODIFIER_KEYS"); break; + case KEYPAD_KEYS: sprintf(buf, "KEYPAD_KEYS"); break; + case FUNCTION_KEYS: sprintf(buf, "FUNCTION_KEYS"); break; + case ALTERNATE_GROUP: sprintf(buf, "ALTERNATE_GROUP"); break; + + default: sprintf(buf, "UNKNOWN"); break; + } + return buf; +} +#endif + +int +setScanState(char *file,int line) +{ + if (file!=NULL) + strncpy(scanFile,file,1024); + if (line>=0) + lineNum= line; + return 1; +} + +static int +yyGetString(void) +{ +int ch; + + nInBuf = 0; + while ( ((ch=getc(yyin))!=EOF) && (ch!='"') ) { + if ( ch == '\\' ) { + if ((ch = getc(yyin))!=EOF) { + if ( ch=='n' ) ch = '\n'; + else if ( ch == 't' ) ch = '\t'; + else if ( ch == 'v' ) ch = '\v'; + else if ( ch == 'b' ) ch = '\b'; + else if ( ch == 'r' ) ch = '\r'; + else if ( ch == 'f' ) ch = '\f'; + else if ( ch == 'e' ) ch = '\033'; + else if ( ch == '0' ) { + int tmp,stop; + ch = stop = 0; + if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if (!stop) { + if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + } + if (!stop) { + if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + } + } + } + else return ERROR_TOK; + } + if ( nInBuf < BUFSIZE-1 ) + buf[nInBuf++] = ch; + } + if ( ch == '"' ) { + buf[nInBuf++] = '\0'; + if ( scanStr ) + uFree( scanStr ); + scanStr = (char *)uStringDup(buf); + scanStrLine = lineNum; + return STRING; + } + return ERROR_TOK; +} + +static int +yyGetKeyName(void) +{ +int ch; + + nInBuf = 0; + while ( ((ch=getc(yyin))!=EOF) && (ch!='>') ) { + if ( ch == '\\' ) { + if ((ch = getc(yyin))!=EOF) { + if ( ch=='n' ) ch = '\n'; + else if ( ch == 't' ) ch = '\t'; + else if ( ch == 'v' ) ch = '\v'; + else if ( ch == 'b' ) ch = '\b'; + else if ( ch == 'r' ) ch = '\r'; + else if ( ch == 'f' ) ch = '\f'; + else if ( ch == 'e' ) ch = '\033'; + else if ( ch == '0' ) { + int tmp,stop; + ch = stop = 0; + if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + } + } + else return ERROR_TOK; + } + + if ( nInBuf < BUFSIZE-1 ) + buf[nInBuf++] = ch; + } + if (( ch == '>' )&&(nInBuf<5)) { + buf[nInBuf++] = '\0'; + if ( scanStr ) + uFree( scanStr ); + scanStr = (char *)uStringDup(buf); + scanStrLine = lineNum; + return KEYNAME; + } + return ERROR_TOK; +} + +struct _Keyword { + char *keyword; + int token; +} keywords[] = { + { "xkb_keymap", XKB_KEYMAP }, + { "xkb_keycodes", XKB_KEYCODES }, + { "xkb_types", XKB_TYPES }, + { "xkb_symbols", XKB_SYMBOLS }, + { "xkb_compat", XKB_COMPATMAP }, + { "xkb_compat_map", XKB_COMPATMAP }, + { "xkb_compatibility", XKB_COMPATMAP }, + { "xkb_compatibility_map", XKB_COMPATMAP }, + { "xkb_geometry", XKB_GEOMETRY }, + { "xkb_semantics", XKB_SEMANTICS }, + { "xkb_layout", XKB_LAYOUT }, + { "include", INCLUDE }, + { "override", OVERRIDE }, + { "augment", AUGMENT }, + { "replace", REPLACE }, + { "alternate", ALTERNATE }, + { "partial", PARTIAL }, + { "default", DEFAULT }, + { "hidden", HIDDEN }, + { "virtual_modifiers", VIRTUAL_MODS }, + { "type", TYPE }, + { "interpret", INTERPRET }, + { "action", ACTION_TOK }, + { "key", KEY }, + { "alias", ALIAS }, + { "group", GROUP }, + { "modmap", MODIFIER_MAP }, + { "mod_map", MODIFIER_MAP }, + { "modifier_map", MODIFIER_MAP }, + { "indicator", INDICATOR }, + { "shape", SHAPE }, + { "row", ROW }, + { "keys", KEYS }, + { "section", SECTION }, + { "overlay", OVERLAY }, + { "text", TEXT }, + { "outline", OUTLINE }, + { "solid", SOLID }, + { "logo", LOGO }, + { "virtual", VIRTUAL }, + { "alphanumeric_keys", ALPHANUMERIC_KEYS }, + { "modifier_keys", MODIFIER_KEYS }, + { "keypad_keys", KEYPAD_KEYS }, + { "function_keys", FUNCTION_KEYS }, + { "alternate_group", ALTERNATE_GROUP } +}; +int numKeywords = sizeof(keywords)/sizeof(struct _Keyword); + +static int +yyGetIdent(int first) +{ +int ch,i,found; +int rtrn = IDENT; + + buf[0] = first; nInBuf = 1; + while ( ((ch=getc(yyin))!=EOF) && (isalnum(ch)||(ch=='_')) ) { + if ( nInBuf < BUFSIZE - 1 ) + buf[nInBuf++] = ch; + } + buf[nInBuf++] = '\0'; + found= 0; + + for (i=0;(!found)&&(i $@ diff --git a/xkbevd/NEWS b/xkbevd/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xkbevd/README b/xkbevd/README new file mode 100644 index 0000000..e69de29 diff --git a/xkbevd/cfgparse.y b/xkbevd/cfgparse.y new file mode 100644 index 0000000..05632df --- /dev/null +++ b/xkbevd/cfgparse.y @@ -0,0 +1,224 @@ +/* $Xorg: cfgparse.y,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbevd/cfgparse.y,v 1.4tsi Exp $ */ + +%token + END_OF_FILE 0 + ERROR 255 + BELL 1 + ACCESSX 2 + MESSAGE 3 + + NONE 20 + IGNORE 21 + ECHO 22 + PRINT_EV 23 + SHELL 24 + SOUND 25 + + EQUALS 40 + PLUS 41 + MINUS 42 + DIVIDE 43 + TIMES 44 + OBRACE 45 + CBRACE 46 + OPAREN 47 + CPAREN 48 + OBRACKET 49 + CBRACKET 50 + DOT 51 + COMMA 52 + SEMI 53 + EXCLAM 54 + INVERT 55 + STRING 60 + INTEGER 61 + FLOAT 62 + IDENT 63 + KEYNAME 64 +%{ +#ifdef DEBUG +#define YYDEBUG 1 +#endif +#define DEBUG_VAR parseDebug +#include "xkbevd.h" +%} +%right EQUALS +%left PLUS MINUS +%left TIMES DIVIDE +%left EXCLAM INVERT +%left OPAREN +%start CfgFile +%union { + char * str; + int ival; + CfgEntryPtr entry; + ActDefPtr act; +} +%type Ident String OptString NameSpec OptNameSpec +%type ActionType EventType +%type ActionDef +%type CfgFile CfgEntryList CfgEntry EventDef VarDef +%% +CfgFile : CfgEntryList + { InterpretConfigs($1); } + ; + +CfgEntryList : CfgEntryList CfgEntry + { + CfgEntryPtr tmp; + if ($1!=NULL) { + for (tmp=$1;tmp->next!=NULL;tmp=tmp->next) { + /* conditional does the work */ + } + tmp->next= $2; + $$= $1; + } + else $$= $2; + } + | CfgEntry { $$= $1; } + ; + +CfgEntry : EventDef ActionDef + { + if (($1)&&($2)) + $1->action= *($2); + if ($2) + uFree($2); + $$= $1; + } + | VarDef { $$= $1; } + ; + +VarDef : Ident EQUALS NameSpec + { + CfgEntryPtr cfg; + cfg= uTypedCalloc(1,CfgEntryRec); + if (cfg) { + cfg->entry_type= VariableDef; + cfg->event_type= 0; + cfg->name.str= $1; + cfg->action.type= UnknownAction; + cfg->action.text= $3; + cfg->action.priv= 0; + cfg->next= NULL; + } + $$= cfg; + } + ; + +EventDef : EventType OPAREN OptNameSpec CPAREN + { + CfgEntryPtr cfg; + cfg= uTypedCalloc(1,CfgEntryRec); + if (cfg) { + cfg->entry_type= EventDef; + cfg->event_type= $1; + cfg->name.str= $3; + cfg->action.type= UnknownAction; + cfg->action.text= NULL; + cfg->action.priv= 0; + cfg->next= NULL; + } + $$= cfg; + } + ; + +EventType : BELL { $$= XkbBellNotify; } + | ACCESSX { $$= XkbAccessXNotify; } + | MESSAGE { $$= XkbActionMessage; } + ; + +ActionDef : ActionType OptString + { + ActDefPtr act; + act= uTypedCalloc(1,ActDefRec); + if (act) { + act->type= $1; + act->text= $2; + } + $$= act; + } + ; + +ActionType : NONE { $$ = NoAction; } + | IGNORE { $$ = NoAction; } + | ECHO { $$ = EchoAction; } + | PRINT_EV { $$ = PrintEvAction; } + | SHELL { $$ = ShellAction; } + | SOUND { $$ = SoundAction; } + | { $$ = UnknownAction; } + ; + +OptNameSpec : NameSpec { $$= $1; } + | { $$= NULL; } + ; + +NameSpec : Ident { $$= $1; } + | String { $$= $1; } + ; + +Ident : IDENT { $$= scanStr; scanStr= NULL; } + ; + +OptString : String { $$= $1; } + | { $$= NULL; } + ; + +String : STRING { $$= scanStr; scanStr= NULL; } + ; +%% +int +yyerror(char *s) +{ + (void)fprintf(stderr,"%s: line %d of %s\n",s,lineNum, + (scanFile?scanFile:"(unknown)")); + if (scanStr) + (void)fprintf(stderr,"last scanned symbol is: %s\n",scanStr); + return 1; +} + + +int +yywrap(void) +{ + return 1; +} + +int +CFGParseFile(FILE *file) +{ + if (file) { + yyin= file; + if (yyparse()==0) { + return 1; + } + return 0; + } + return 1; +} diff --git a/xkbevd/cfgscan.c b/xkbevd/cfgscan.c new file mode 100644 index 0000000..6eaef0c --- /dev/null +++ b/xkbevd/cfgscan.c @@ -0,0 +1,384 @@ +/* $Xorg: cfgscan.c,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbevd/cfgscan.c,v 3.6 2001/01/17 23:46:07 dawes Exp $ */ + +#include +#include +#include +#include +#include +#include + +#include "tokens.h" +#include "xkbevd.h" + +FILE *yyin = NULL; + +static char scanFileBuf[1024]; +char * scanFile= scanFileBuf; +int lineNum= 0; + +int scanInt; +char *scanIntStr; +int scanIntClass; + +char *scanStr = NULL; +int scanStrLine= 0; + +#define BUFSIZE 512 +static int nInBuf = 0; +static char buf[BUFSIZE]; + +#ifdef DEBUG + +extern unsigned debugFlags; + +static char * +tokText(int tok) +{ +static char buf[32]; + + switch (tok) { + case END_OF_FILE: sprintf(buf, "END_OF_FILE");break; + case ERROR: sprintf(buf, "ERROR"); break; + + case BELL: sprintf(buf, "BELL"); break; + case ACCESSX: sprintf(buf, "ACCESSX"); break; + case MESSAGE: sprintf(buf, "MESSAGE"); break; + + case NONE: sprintf(buf, "NONE"); break; + case IGNORE: sprintf(buf, "IGNORE"); break; + case ECHO: sprintf(buf, "ECHO"); break; + case PRINT_EV: sprintf(buf, "PRINT_EV"); break; + case SHELL: sprintf(buf, "SHELL"); break; + case SOUND: sprintf(buf, "SOUND"); break; + + case EQUALS: sprintf(buf, "EQUALS"); break; + case PLUS: sprintf(buf, "PLUS"); break; + case MINUS: sprintf(buf, "MINUS"); break; + case DIVIDE: sprintf(buf, "DIVIDE"); break; + case TIMES: sprintf(buf, "TIMES"); break; + case OBRACE: sprintf(buf, "OBRACE"); break; + case CBRACE: sprintf(buf, "CBRACE"); break; + case OPAREN: sprintf(buf, "OPAREN"); break; + case CPAREN: sprintf(buf, "CPAREN"); break; + case OBRACKET: sprintf(buf, "OBRACKET");break; + case CBRACKET: sprintf(buf, "CBRACKET");break; + case DOT: sprintf(buf, "DOT"); break; + case COMMA: sprintf(buf, "COMMA"); break; + case SEMI: sprintf(buf, "SEMI"); break; + case EXCLAM: sprintf(buf, "EXCLAM"); break; + case INVERT: sprintf(buf, "INVERT"); break; + + case STRING: sprintf(buf, "STRING (%s)",scanStr); break; + case INTEGER: sprintf(buf, "INTEGER (0x%x)",scanInt); break; + case FLOAT: sprintf(buf, "FLOAT (%d.%d)", + scanInt/XkbGeomPtsPerMM, + scanInt%XkbGeomPtsPerMM);break; + case IDENT: sprintf(buf, "IDENT (%s)",scanStr); break; + case KEYNAME: sprintf(buf, "KEYNAME (%s)",scanStr); break; + default: sprintf(buf, "UNKNOWN"); break; + } + return buf; +} +#endif + +int +setScanState(char *file, int line) +{ + if (file!=NULL) + strncpy(scanFile,file,1024); + if (line>=0) + lineNum= line; + return 1; +} + +static int +yyGetString(void) +{ +int ch; + + nInBuf = 0; + while ( ((ch=getc(yyin))!=EOF) && (ch!='"') ) { + if ( ch == '\\' ) { + if ((ch = getc(yyin))!=EOF) { + if ( ch=='n' ) ch = '\n'; + else if ( ch == 't' ) ch = '\t'; + else if ( ch == 'v' ) ch = '\v'; + else if ( ch == 'b' ) ch = '\b'; + else if ( ch == 'r' ) ch = '\r'; + else if ( ch == 'f' ) ch = '\f'; + else if ( ch == 'e' ) ch = '\033'; + else if ( ch == '0' ) { + int tmp,stop; + ch = stop = 0; + if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + } + } + else return ERROR; + } + + if ( nInBuf < BUFSIZE-1 ) + buf[nInBuf++] = ch; + } + if ( ch == '"' ) { + buf[nInBuf++] = '\0'; + if ( scanStr ) + free( scanStr ); + scanStr = uStringDup(buf); + scanStrLine = lineNum; + return STRING; + } + return ERROR; +} + +static int +yyGetKeyName(void) +{ +int ch; + + nInBuf = 0; + while ( ((ch=getc(yyin))!=EOF) && (ch!='>') ) { + if ( ch == '\\' ) { + if ((ch = getc(yyin))!=EOF) { + if ( ch=='n' ) ch = '\n'; + else if ( ch == 't' ) ch = '\t'; + else if ( ch == 'v' ) ch = '\v'; + else if ( ch == 'b' ) ch = '\b'; + else if ( ch == 'r' ) ch = '\r'; + else if ( ch == 'f' ) ch = '\f'; + else if ( ch == 'e' ) ch = '\033'; + else if ( ch == '0' ) { + int tmp,stop; + ch = stop = 0; + if (((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + if ((!stop) && ((tmp=getc(yyin))!=EOF) && (isdigit(tmp)) && + (tmp!='8') && (tmp!='9')) { + ch= (ch*8)+(tmp-'0'); + } + else { + stop= 1; + ungetc(tmp,yyin); + } + } + } + else return ERROR; + } + + if ( nInBuf < BUFSIZE-1 ) + buf[nInBuf++] = ch; + } + if (( ch == '>' )&&(nInBuf<5)) { + buf[nInBuf++] = '\0'; + if ( scanStr ) + free( scanStr ); + scanStr = uStringDup(buf); + scanStrLine = lineNum; + return KEYNAME; + } + return ERROR; +} + +struct _Keyword { + char *keyword; + int token; +} keywords[] = { + { "bell", BELL }, + { "accessx", ACCESSX }, + { "message", MESSAGE }, + { "none", NONE }, + { "ignore", IGNORE }, + { "echo", ECHO }, + { "printevent", PRINT_EV }, + { "shell", SHELL }, + { "sound", SOUND } +}; +int numKeywords = sizeof(keywords)/sizeof(struct _Keyword); + +static int +yyGetIdent(int first) +{ +int ch,i,found; +int rtrn = -1; + + buf[0] = first; nInBuf = 1; + while ( ((ch=getc(yyin))!=EOF) && (isalnum(ch)||(ch=='_')) ) { + if ( nInBuf < BUFSIZE - 1 ) + buf[nInBuf++] = ch; + } + buf[nInBuf++] = '\0'; + found= 0; + + for (i=0;(!found)&&(ibell.device); + else if (uStringEqual(arg,"volume")||uStringEqual(arg,"v")) + sprintf(sink,"%d",ev->bell.percent); + else if (uStringEqual(arg,"pitch")||uStringEqual(arg,"p")) + sprintf(sink,"%d",ev->bell.pitch); + else if (uStringEqual(arg,"duration")||uStringEqual(arg,"d")) + sprintf(sink,"%d",ev->bell.duration); + else if (uStringEqual(arg,"class")||uStringEqual(arg,"c")) + sprintf(sink,"%d",ev->bell.bell_class); + else if (uStringEqual(arg,"id")||uStringEqual(arg,"i")) + sprintf(sink,"%d",ev->bell.bell_id); + else if (uStringEqual(arg,"window")||uStringEqual(arg,"w")) + sprintf(sink,"0x%x",(unsigned int)ev->bell.window); + else if (uStringEqual(arg,"name")||uStringEqual(arg,"n")) + sprintf(sink,"%s",XkbAtomText(dpy,ev->bell.name,XkbMessage)); + return sink; +} + +static char * +AppendAccessXNotifyArg(char *sink, char *arg, XkbEvent *ev) +{ + if (uStringEqual(arg,"device")||uStringEqual(arg,"D")) + sprintf(sink,"%d",ev->accessx.device); + else if (uStringEqual(arg,"detail")||uStringEqual(arg,"d")) { + sprintf(sink,"%s",XkbAccessXDetailText(ev->accessx.detail,XkbMessage)); + } + else if (uStringEqual(arg,"keycode")||uStringEqual(arg,"key")|| + uStringEqual(arg,"k")) + sprintf(sink,"%d",ev->accessx.keycode); + else if (uStringEqual(arg,"skdelay")||uStringEqual(arg,"s")) + sprintf(sink,"%d",ev->accessx.sk_delay); + else if (uStringEqual(arg,"bkdelay")||uStringEqual(arg,"b")) + sprintf(sink,"%d",ev->accessx.debounce_delay); + return sink; +} + +static char * +AppendActionMessageArg(char *sink, char *arg, XkbEvent *ev) +{ + if (uStringEqual(arg,"device")||uStringEqual(arg,"D")) + sprintf(sink,"%d",ev->message.device); + else if (uStringEqual(arg,"message")||uStringEqual(arg,"m")) + sprintf(sink,"%s",ev->message.message); + else if (uStringEqual(arg,"keycode")||uStringEqual(arg,"key")|| + uStringEqual(arg,"k")) + sprintf(sink,"%d",ev->message.keycode); + else if (uStringEqual(arg,"press")||uStringEqual(arg,"p")) + sprintf(sink,"%s",(ev->message.press?"press":"release")); + else if (uStringEqual(arg,"event")||uStringEqual(arg,"e")) + sprintf(sink,"%s",(ev->message.key_event_follows?"event":"no_event")); + return sink; +} + +static char * +AppendEventArg(char *sink, char *arg, XkbEvent *ev) +{ + switch (ev->any.xkb_type) { + case XkbBellNotify: + sink= AppendBellNotifyArg(sink,arg,ev); + break; + case XkbAccessXNotify: + sink= AppendAccessXNotifyArg(sink,arg,ev); + break; + case XkbActionMessage: + sink= AppendActionMessageArg(sink,arg,ev); + break; + default: + return sink; + } + sink+= strlen(sink); + return sink; +} + +static void +CopyEventArg(char **sink_inout, char **source_inout, XkbEvent *ev) +{ +char buf[1024]; +char *source,*sink; +char *arg; + + arg= buf; + source= *source_inout; + sink= *sink_inout; + if (*source=='$') { + *sink++= '$'; + source++; + *sink++= '\0'; + *sink_inout= sink; + *source_inout= source; + return; + } + else if (*source=='(') { + source++; + while ((*source!=')')&&(*source!='\0')) { + *arg++= *source++; + } + if (*source=='\0') { + *sink++= '$'; + *sink++= '\0'; + *sink_inout= sink; + return; + } + source++; + *arg++= '\0'; + arg= buf; + } + else { + arg[0]= *source++; + arg[1]= '\0'; + } + sink= AppendEventArg(sink,arg,ev); + *sink_inout= sink; + *source_inout= source; + return; +} + +char * +SubstituteEventArgs(char *cmd, XkbEvent *ev) +{ +static char buf[1024]; +char *source,*sink; + + if (index(cmd,'$')==NULL) + return cmd; + buf[0]= '\0'; + sink= buf; + source= cmd; + while (*source!='\0') { + if (*source=='$') { + source++; + CopyEventArg(&sink,&source,ev); + } + *sink++= *source++; + } + return buf; +} + diff --git a/xkbevd/example.cf b/xkbevd/example.cf new file mode 100644 index 0000000..7e73f15 --- /dev/null +++ b/xkbevd/example.cf @@ -0,0 +1,53 @@ +//$Xorg: example.cf,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ +soundDirectory = "/space/erik/.xkb/sounds/" + +Bell() "ss/08.ting.aifc" + +Bell(Info) "sfx/cricket.aiff" +Bell(Warning) "ss/02.xylo.pong.aifc" // bogus +Bell(MinorError) "ss/02.xylo.pong.aifc" +Bell(MajorError) "instr/crash16_hrd.aiff" +Bell(Question) echo "xkbevd: ignoring $(name) bell\n" +Bell(Start) "ss/searchBegin.44.aifc" +Bell(End) "ss/searchEnd.44.aifc" +Bell(Success) "musictags/harp_glis.Cmj.aiff" +Bell(Failure) "sfx/cannon.aiff" +Bell(Wait) "ss/searchBegin.44.aifc" +Bell(Proceed) "ss/searchEnd.44.aifc" +Bell("Ignore") echo "xkbevd: ignoring $(name) bell\n" +Bell(Iconify) echo "xkbevd: ignoring $(name) bell\n" +Bell(Deiconify) echo "xkbevd: ignoring $(name) bell\n" +Bell(Open) echo "xkbevd: ignoring $(name) bell\n" +Bell(Close) echo "xkbevd: ignoring $(name) bell\n" +Bell(TerminalBell) "ss/ss2.aifc" +Bell(MarginBell) "sfx/bell.aiff" +Bell(CursorStuck) "ss/02.chick.aifc" +Bell(NewMail) "sfx/doorchime.aiff" +Bell(LaunchApp) "ss/05.kerchick.echo.aifc" +Bell(AppDeath) "ss/20.zikik.aifc" +Bell(ImAlive) "ss/ss6.aifc" +Bell(RepeatingLastBell) ignore +Bell(ClockChimeHour) "musictags/harp_glis.Cmj.aiff" +Bell(ClockChimeHalf) "musictags/belltree_up2.aiff" +Bell(ClockChimeQuarter) "ss/ss6.aifc" +Bell(AX_FeatureOn) "instr/drm_clave.aiff" +Bell(AX_FeatureOff) "instr/drm_cowbell.aiff" +Bell(AX_FeatureChange) "instr/warped_harm.aiff" + +Bell(AX_IndicatorOn) "ss/01.african.thumb.inst.aifc" +Bell(AX_IndicatorOff) "ss/07.bzz.organ.aifc" +Bell(AX_IndicatorChange) "ss/01.buzz.kerchick.aifc" + +Bell(AX_SlowKeysWarning) "sfx/alarm_clock.aiff" + +Bell(AX_SlowKeyPress) "instr/drm_stick_mid.aiff" +Bell(AX_SlowKeyAccept) "instr/drm_cowbell.aiff" +Bell(AX_SlowKeyReject) "instr/drm_snare.aiff" +Bell(AX_SlowKeyRelease) "instr/drm_cowbell.aiff" + +Bell(AX_BounceKeyReject) "instr/drm_snare.aiff" + +Bell(AX_StickyLatch) "sfx/click2.aiff" +Bell(AX_StickyLock) "sfx/click3.aiff" +Bell(AX_StickyUnlock) "ss/searchEnd.44.aifc" +SlowKey() printEvent diff --git a/xkbevd/mkinstalldirs b/xkbevd/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xkbevd/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xkbevd/printev.c b/xkbevd/printev.c new file mode 100644 index 0000000..1aec0aa --- /dev/null +++ b/xkbevd/printev.c @@ -0,0 +1,624 @@ +/* $Xorg: printev.c,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbevd/printev.c,v 3.3 1999/03/02 11:49:59 dawes Exp $ */ + +#define DEBUG_VAR printevDebug +#include "xkbevd.h" +#include + +#define Yes "yes" +#define No "no" +#define Unknown "unknown" +#define ynText(v) ((v)?Yes:No) + +static char * +eventTypeToString(int evType) +{ +static char name[20]; + switch (evType) { + case KeyPress: strcpy(name,"KeyPress"); break; + case KeyRelease:strcpy(name,"KeyRelease"); break; + default: strcpy(name,"unknown"); break; + } + return name; +} + +static void +xkb_prologue (FILE *file, XkbEvent *ev, char *name) +{ + XkbAnyEvent *e = &ev->any; + + fprintf(file,"\n%s event, serial %ld, synthetic %s, device %d, time %ld,\n", + name, e->serial, ynText(e->send_event), e->device,e->time); + return; +} + +static void +do_XkbStateNotify(FILE *file, XkbEvent *xkbev) +{ + XkbStateNotifyEvent *state= &xkbev->state; + + if (state->keycode!=0) + fprintf(file," keycode %d, eventType %s,\n", + state->keycode,eventTypeToString(state->event_type)); + else fprintf(file," request %d/%d,\n",state->req_minor,state->req_minor); + fprintf(file," group= %d%s, base= %d%s, latched= %d%s, locked= %d%s,\n", + state->group, (state->changed&XkbGroupStateMask?"*":""), + state->base_group,(state->changed&XkbGroupBaseMask?"*":""), + state->latched_group,(state->changed&XkbGroupLatchMask?"*":""), + state->locked_group,(state->changed&XkbGroupLockMask?"*":"")); + fprintf(file, + " mods= 0x%02x%s, base= 0x%02x%s, latched= 0x%02x%s, locked= 0x%02x%s\n", + state->mods, (state->changed&XkbModifierStateMask?"*":""), + state->base_mods,(state->changed&XkbModifierBaseMask?"*":""), + state->latched_mods,(state->changed&XkbModifierLatchMask?"*":""), + state->locked_mods,(state->changed&XkbModifierLockMask?"*":"")); + fprintf(file," grab mods= 0x%02x%s, compat grab mods= 0x%02x%s\n", + state->grab_mods, (state->changed&XkbGrabModsMask?"*":""), + state->compat_grab_mods, + (state->changed&XkbCompatGrabModsMask?"*":"")); + fprintf(file," lookup mods= 0x%02x%s, compat lookup mods= 0x%02x%s\n", + state->lookup_mods, (state->changed&XkbLookupModsMask?"*":""), + state->compat_lookup_mods, + (state->changed&XkbCompatLookupModsMask?"*":"")); + fprintf(file," compatState = 0x%02x%s, ", + state->compat_state,(state->changed&XkbCompatStateMask?"*":"")); + fprintf(file,"ptr_buttons= 0x%04x%s\n",state->ptr_buttons, + (state->changed&XkbPointerButtonMask?"*":"")); + return; +} + +static void +do_map_message(char *what, int first, int num, int eol) +{ + if (num>1) + printf("%ss %d..%d changed%s",what,first,first+num-1,(eol?"\n":"")); + else printf("%s %d changed%s",what,first,(eol?"\n":"")); +} + +static void +do_XkbMapNotify(FILE *file,XkbEvent *xkbev) +{ + XkbMapNotifyEvent *map = &xkbev->map; + if (map->changed&XkbKeyTypesMask) { + do_map_message("key type",map->first_type,map->num_types,0); + } + if (map->changed&XkbKeySymsMask) { + do_map_message("symbols for key",map->first_key_sym,map->num_key_syms, + 1); + } + if (map->changed&XkbKeyActionsMask) { + do_map_message("acts for key",map->first_key_act, + map->num_key_acts,1); + } + if (map->changed&XkbKeyBehaviorsMask) { + do_map_message("behavior for key",map->first_key_behavior, + map->num_key_behaviors,1); + } + if (map->changed&XkbVirtualModsMask) { + fprintf(file," virtual modifiers changed (0x%04x)\n",map->vmods); + } + if (map->changed&XkbExplicitComponentsMask) { + do_map_message("explicit components for key",map->first_key_explicit, + map->num_key_explicit,1); + } + if (map->changed&XkbModifierMapMask) { + do_map_message("modifier map for key",map->first_modmap_key, + map->num_modmap_keys,1); + } + return; +} + +static void +do_XkbControlsNotify(FILE *file, XkbEvent *xkbev) +{ + XkbControlsNotifyEvent *ctrls = &xkbev->ctrls; + fprintf(file," changed= 0x%x, enabled= 0x%x, enabledChanges= 0x%x\n", + ctrls->changed_ctrls,ctrls->enabled_ctrls, + ctrls->enabled_ctrl_changes); + fprintf(file," num_groups= %d\n",ctrls->num_groups); + if (ctrls->keycode!=0) + fprintf(file," keycode %d, eventType %s,", + ctrls->keycode,eventTypeToString(ctrls->event_type)); + else fprintf(file," request %d/%d%s\n",ctrls->req_major,ctrls->req_minor, + (ctrls->req_major!=xkbOpcode?" (NON-XKB)":"")); + return; +} + +static void +do_XkbIndicatorNotify(FILE *file, XkbEvent *xkbev) +{ + XkbIndicatorNotifyEvent *leds = &xkbev->indicators; + if (leds->xkb_type==XkbIndicatorStateNotify) + fprintf(file," state changes= 0x%08x, new state= 0x%08x\n", + leds->changed,leds->state); + else fprintf(file," map changes= 0x%08x, state= 0x%08x\n", + leds->changed,leds->state); + return; +} + +static void +do_XkbBellNotify(FILE *file, XkbEvent *xkbev) +{ + XkbBellNotifyEvent *bell = &xkbev->bell; + fprintf(file," bell class= %d, id= %d\n",bell->bell_class,bell->bell_id); + fprintf(file," percent= %d, pitch= %d, duration= %d", + bell->percent,bell->pitch,bell->duration); + if (bell->name!=None) { + char *name = XGetAtomName (dpy, bell->name); + fprintf(file,"\n name= \"%s\"\n",(name?name:"")); + if (name) + XFree(name); + } + else fprintf(file,", no name\n"); + fprintf(file," window= 0x%x, %sevent_only\n",(unsigned int)bell->window, + (bell->event_only?"":"!")); + return; +} + +static void +do_XkbAccessXNotify(FILE *file, XkbEvent *xkbev) +{ + XkbAccessXNotifyEvent *sk = &xkbev->accessx; + char *detail; + switch (sk->detail) { + case XkbAXN_SKPress: detail= "skpress"; break; + case XkbAXN_SKAccept: detail= "skaccept"; break; + case XkbAXN_SKReject: detail= "skreject"; break; + case XkbAXN_SKRelease: detail= "skrelease"; break; + case XkbAXN_BKAccept: detail= "bkaccept"; break; + case XkbAXN_BKReject: detail= "bkreject"; break; + case XkbAXN_AXKWarning: detail= "warning"; break; + default: { + static char buf[20]; + sprintf(buf,"unknown(%d)",sk->detail); + detail= buf; + break; + } + } + fprintf(file, + " keycode= %d,detail= %s,slow keys delay= %d,debounce delay= %d\n", + sk->keycode,detail,sk->sk_delay,sk->debounce_delay); + return; +} + +static void +do_XkbNamesNotify(FILE *file, XkbEvent *xkbev) +{ + XkbNamesNotifyEvent *names = &xkbev->names; + + if (names->changed& + (XkbKeycodesNameMask|XkbGeometryNameMask|XkbSymbolsNameMask)) { + int needComma= 0; + fprintf(file," "); + if (names->changed&XkbKeycodesNameMask) { + fprintf(file,"keycodes"); + needComma++; + } + if (names->changed&XkbGeometryNameMask) { + fprintf(file,"%sgeometry",(needComma?", ":"")); + needComma++; + } + if (names->changed&XkbSymbolsNameMask) { + fprintf(file,"%ssymbols",(needComma?", ":"")); + needComma++; + } + if (names->changed&XkbPhysSymbolsNameMask) { + fprintf(file,"%sphysical symbols",(needComma?", ":"")); + needComma++; + } + fprintf(file," name%s changed\n",(needComma>1?"s":"")); + } + if (names->changed&XkbKeyTypeNamesMask) { + do_map_message("key type name",names->first_type,names->num_types,1); + } + if (names->changed&XkbKTLevelNamesMask) { + do_map_message("level names for key type", + names->first_lvl,names->num_lvls,1); + } + if (names->changed&XkbIndicatorNamesMask) { + fprintf(file," names of indicators in 0x%08x changed\n", + names->changed_indicators); + } + if (names->changed&XkbVirtualModNamesMask) { + fprintf(file," names of virtual modifiers in 0x%04x changed\n", + names->changed_vmods); + } + if (names->changed&XkbGroupNamesMask) { + fprintf(file," names of groups in 0x%x changed\n", + names->changed_groups); + } + if (names->changed&XkbKeyNamesMask) { + do_map_message("names for key",names->first_key,names->num_keys,1); + } + if (names->changed&XkbKeyAliasesMask) { + fprintf(file,"key aliases changed (%d aliases total)\n", + names->num_aliases); + } + if (names->changed&XkbRGNamesMask) { + fprintf(file,"radio group names changed (%d radio groups total)\n", + names->num_radio_groups); + } + return; +} + +static void +do_XkbCompatMapNotify(FILE *file, XkbEvent *xkbev) +{ + XkbCompatMapNotifyEvent *map = &xkbev->compat; + + if (map->changed_groups) + fprintf(file," compat maps for groups in 0x%02x changed\n", + map->changed_groups); + if (map->num_si>0) { + fprintf(file," symbol interpretations %d..%d (of %d) changed\n", + map->first_si,map->first_si+map->num_si-1, + map->num_total_si); + } + else fprintf(file," keyboard has %d symbol interpretations\n", + map->num_total_si); + return; +} + +static void +do_XkbActionMessage(FILE *file, XkbEvent *xkbev) +{ + XkbActionMessageEvent *msg= &xkbev->message; + fprintf(file," message: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + msg->message[0],msg->message[1], + msg->message[2],msg->message[3], + msg->message[4],msg->message[5]); + fprintf(file," key %d, event: %s, follows: %s\n",msg->keycode, + (msg->press?"press":"release"), + (msg->key_event_follows?"yes":"no")); + return; +} + +static void +do_XkbNewKeyboardNotify(FILE *file, XkbEvent *xkbev) +{ + XkbNewKeyboardNotifyEvent *nk= &xkbev->new_kbd; + fprintf(file," new device: %d min_keycode: %d, max_keycode %d\n", + nk->device,nk->min_key_code,nk->max_key_code); + fprintf(file," old device: %d min_keycode: %d, max_keycode %d\n", + nk->old_device, + nk->old_min_key_code,nk->old_max_key_code); + return; +} + +static void +do_XkbExtensionDeviceNotify(FILE *file, XkbEvent *xkbev) +{ + XkbExtensionDeviceNotifyEvent *edn= &xkbev->device; + fprintf(file," device= %d, class= %d, id= %d\n",edn->device, + edn->led_class,edn->led_id); + fprintf(file," reason= 0x%0x\n",edn->reason); + fprintf(file," supported= 0x%0x, unsupported= 0x%0x\n",edn->supported, + edn->unsupported); + fprintf(file," first button= %d, num buttons= %d\n",edn->first_btn, + edn->num_btns); + fprintf(file," leds defined= 0x%08x, led state= 0x%08x\n", + edn->leds_defined,edn->led_state); + return; +} + +#ifdef notyet +static char keyState[XkbMaxLegalKeyCode]; + +static void +do_KeyEvent(XkbEvent *eventp, int compose, int repeat) +{ + XKeyEvent *e = &eventp->core.xkey; + KeySym ks; + char *ksname,*kname; + int nbytes; + char str[256+1]; + static XComposeStatus status; + + nbytes = XLookupString (e, str, 256, &ks, (compose?&status:NULL)); + if (ks == NoSymbol) + ksname = "NoSymbol"; + else if (!(ksname = XKeysymToString (ks))) + ksname = "(no name)"; + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + + if (xkb && xkb->names && xkb->names->keys) + kname= XkbKeyNameText(xkb->names->keys[e->keycode].name,XkbMessage); + else kname= ""; /* XXX break trigraph */ + + printf (" state 0x%x, group= %d, key %s (keycode %u, keysym 0x%x, %s)\n", + e->state&0x1FFF, (e->state>>13)&0x7, kname, + e->keycode, (unsigned int)ks, ksname); + printf (" same_screen %s, autorepeat %s,\n",ynText(e->same_screen), + (detectableRepeat ? ynText(repeat) : "UNKNOWN")); + if (nbytes < 0) nbytes = 0; + if (nbytes > 256) nbytes = 256; + str[nbytes] = '\0'; + printf (" XLookupString gives %d characters: \"%s\"\n", nbytes, str); + + return; +} + +static void +do_KeyPress(XkbEvent *eventp) +{ +int repeat; + + repeat= keyState[eventp->core.xkey.keycode]!=0; + keyState[eventp->core.xkey.keycode]= 1; + do_KeyEvent (eventp, 1,repeat); + return; +} + +static void +do_KeyRelease(XkbEvent *eventp) +{ + keyState[eventp->core.xkey.keycode]= 0; + do_KeyEvent (eventp,0,False); + return; +} + +static void +do_ButtonPress(XkbEvent *eventp) +{ + XButtonEvent *e = &eventp->core.xbutton; + + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" state 0x%x, group= %d, button %u, same_screen %s\n", + e->state&0x1FFF, (e->state>>13)&0x7, e->button, + ynText(e->same_screen)); + + return; +} + +static void +do_ButtonRelease(XkbEvent *eventp) +{ + do_ButtonPress (eventp); /* since it has the same info */ + return; +} + +static void +do_MotionNotify(XkbEvent *eventp) +{ + XMotionEvent *e = &eventp->core.xmotion; + + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" state 0x%x, group= %d, is_hint %u, same_screen %s\n", + e->state&0x1FFF, (e->state>>13)&0x7, e->is_hint, + ynText(e->same_screen)); + + return; +} + +static void +do_EnterNotify(XkbEvent *eventp) +{ + XCrossingEvent *e = &eventp->core.xcrossing; + char *mode, *detail; + char dmode[10], ddetail[10]; + + switch (e->mode) { + case NotifyNormal: mode = "NotifyNormal"; break; + case NotifyGrab: mode = "NotifyGrab"; break; + case NotifyUngrab: mode = "NotifyUngrab"; break; + case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; + default: mode = dmode, sprintf (dmode, "%u", e->mode); break; + } + + switch (e->detail) { + case NotifyAncestor: detail = "NotifyAncestor"; break; + case NotifyVirtual: detail = "NotifyVirtual"; break; + case NotifyInferior: detail = "NotifyInferior"; break; + case NotifyNonlinear: detail = "NotifyNonlinear"; break; + case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; + case NotifyPointer: detail = "NotifyPointer"; break; + case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; + case NotifyDetailNone: detail = "NotifyDetailNone"; break; + default: detail = ddetail; sprintf (ddetail, "%u", e->detail); break; + } + + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" mode %s, detail %s, same_screen %s,\n", + mode, detail, ynText(e->same_screen)); + printf (" focus %s, state %u, group= %d\n", ynText(e->focus), + e->state&0x1FFF, (e->state>>13)&7 ); + + return; +} + +static void +do_LeaveNotify(XkbEvent *eventp) +{ + do_EnterNotify (eventp); /* since it has same information */ + return; +} + +static void +do_KeymapNotify(XkbEvent *eventp) +{ + XKeymapEvent *e = &eventp->core.xkeymap; + int i; + + printf (" keys: "); + for (i = 0; i < 32; i++) { + if (i == 16) printf ("\n "); + printf ("%-3u ", (unsigned int) e->key_vector[i]); + } + printf ("\n"); + return; +} + +static void +do_ClientMessage(XkbEvent *eventp) +{ + XClientMessageEvent *e = &eventp->core.xclient; + char *mname = XGetAtomName (dpy, e->message_type); + + printf (" message_type 0x%lx (%s), format %d\n", + e->message_type, mname ? mname : Unknown, e->format); + + if (mname) XFree (mname); + return; +} + +static void +do_MappingNotify(XkbEvent *eventp) +{ + XMappingEvent *e = &eventp->core.xmapping; + char *r; + char rdummy[10]; + + switch (e->request) { + case MappingModifier: r = "MappingModifier"; break; + case MappingKeyboard: r = "MappingKeyboard"; break; + case MappingPointer: r = "MappingPointer"; break; + default: r = rdummy; sprintf (rdummy, "%d", e->request); break; + } + + printf (" request %s, first_keycode %d, count %d\n", + r, e->first_keycode, e->count); + XRefreshKeyboardMapping(e); + return; +} + + +static void +set_sizehints(XSizeHints *hintp, int min_width, int min_height, + int defwidth, int defheight, int defx, int defy, char *geom) +{ + int geom_result; + + /* set the size hints, algorithm from xlib xbiff */ + + hintp->width = hintp->min_width = min_width; + hintp->height = hintp->min_height = min_height; + hintp->flags = PMinSize; + hintp->x = hintp->y = 0; + geom_result = NoValue; + if (geom != NULL) { + geom_result = XParseGeometry (geom, &hintp->x, &hintp->y, + (unsigned int *)&hintp->width, + (unsigned int *)&hintp->height); + if ((geom_result & WidthValue) && (geom_result & HeightValue)) { +#define max(a,b) ((a) > (b) ? (a) : (b)) + hintp->width = max (hintp->width, hintp->min_width); + hintp->height = max (hintp->height, hintp->min_height); + hintp->flags |= USSize; + } + if ((geom_result & XValue) && (geom_result & YValue)) { + hintp->flags += USPosition; + } + } + if (!(hintp->flags & USSize)) { + hintp->width = defwidth; + hintp->height = defheight; + hintp->flags |= PSize; + } +/* + if (!(hintp->flags & USPosition)) { + hintp->x = defx; + hintp->y = defy; + hintp->flags |= PPosition; + } + */ + if (geom_result & XNegative) { + hintp->x = DisplayWidth (dpy, DefaultScreen (dpy)) + hintp->x - + hintp->width; + } + if (geom_result & YNegative) { + hintp->y = DisplayHeight (dpy, DefaultScreen (dpy)) + hintp->y - + hintp->height; + } + return; +} +#endif + +void +PrintXkbEvent(FILE *file, XkbEvent *ev) +{ + if (ev->type==xkbEventCode) { + switch (ev->any.xkb_type) { + case XkbStateNotify: + xkb_prologue(file, ev, "XkbStateNotify" ); + do_XkbStateNotify(file,ev); + break; + case XkbMapNotify: + xkb_prologue(file, ev, "XkbMapNotify" ); + do_XkbMapNotify(file,ev); + break; + case XkbControlsNotify: + xkb_prologue(file, ev, "XkbControlsNotify" ); + do_XkbControlsNotify(file,ev); + break; + case XkbIndicatorMapNotify: + xkb_prologue(file, ev, "XkbIndicatorMapNotify" ); + do_XkbIndicatorNotify(file,ev); + break; + case XkbIndicatorStateNotify: + xkb_prologue(file, ev, "XkbIndicatorStateNotify" ); + do_XkbIndicatorNotify(file,ev); + break; + case XkbBellNotify: + xkb_prologue(file, ev, "XkbBellNotify" ); + do_XkbBellNotify(file,ev); + break; + case XkbAccessXNotify: + xkb_prologue(file, ev, "XkbAccessXNotify" ); + do_XkbAccessXNotify(file,ev); + break; + case XkbNamesNotify: + xkb_prologue(file, ev, "XkbNamesNotify" ); + do_XkbNamesNotify(file,ev); + break; + case XkbCompatMapNotify: + xkb_prologue(file, ev, "XkbCompatMapNotify" ); + do_XkbCompatMapNotify(file,ev); + break; + case XkbActionMessage: + xkb_prologue(file, ev, "XkbActionMessage" ); + do_XkbActionMessage(file,ev); + break; + case XkbNewKeyboardNotify: + xkb_prologue(file, ev, "XkbNewKeyboard" ); + do_XkbNewKeyboardNotify(file,ev); + break; + case XkbExtensionDeviceNotify: + xkb_prologue(file, ev, "XkbExtensionDeviceNotify" ); + do_XkbExtensionDeviceNotify(file,ev); + break; + default: + xkb_prologue(file, ev, "XKB_UNKNOWN!!!" ); + break; + } + } + return; +} diff --git a/xkbevd/tokens.h b/xkbevd/tokens.h new file mode 100644 index 0000000..c0b9d97 --- /dev/null +++ b/xkbevd/tokens.h @@ -0,0 +1,67 @@ +/* $Xorg: tokens.h,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +#ifndef TOKENS_H +#define TOKENS_H 1 + +#define END_OF_FILE 0 +#define ERROR 255 + +#define BELL 1 +#define ACCESSX 2 +#define MESSAGE 3 + +#define NONE 20 +#define IGNORE 21 +#define ECHO 22 +#define PRINT_EV 23 +#define SHELL 24 +#define SOUND 25 + +#define EQUALS 40 +#define PLUS 41 +#define MINUS 42 +#define DIVIDE 43 +#define TIMES 44 +#define OBRACE 45 +#define CBRACE 46 +#define OPAREN 47 +#define CPAREN 48 +#define OBRACKET 49 +#define CBRACKET 50 +#define DOT 51 +#define COMMA 52 +#define SEMI 53 +#define EXCLAM 54 +#define INVERT 55 + +#define STRING 60 +#define INTEGER 61 +#define FLOAT 62 +#define IDENT 63 +#define KEYNAME 64 + +#endif diff --git a/xkbevd/utils.c b/xkbevd/utils.c new file mode 100644 index 0000000..4c81e3f --- /dev/null +++ b/xkbevd/utils.c @@ -0,0 +1,380 @@ + + /*\ + * $XFree86: xc/programs/xkbevd/utils.c,v 3.5 2001/07/25 15:05:25 dawes Exp $ + * + * COPYRIGHT 1990 + * DIGITAL EQUIPMENT CORPORATION + * MAYNARD, MASSACHUSETTS + * ALL RIGHTS RESERVED. + * + * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND + * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. + * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE + * FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED + * WARRANTY. + * + * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT + * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN + * ADDITION TO THAT SET FORTH ABOVE. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Digital Equipment Corporation not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + \*/ +/* $Xorg: utils.c,v 1.5 2000/08/17 19:54:49 cpqbld Exp $ */ + +#define DEBUG_VAR_LOCAL +#include "utils.h" +#include +#include + +/***====================================================================***/ + +Opaque +uAlloc(size) + unsigned size; +{ + return((Opaque)malloc(size)); +} + +/***====================================================================***/ + +Opaque +uCalloc(n,size) + unsigned n; + unsigned size; +{ + return((Opaque)calloc(n,size)); +} + +/***====================================================================***/ + +Opaque +uRealloc(old,newSize) + Opaque old; + unsigned newSize; +{ + if (old==NULL) + return((Opaque)malloc(newSize)); + else return((Opaque)realloc((char *)old,newSize)); +} + +/***====================================================================***/ + +Opaque +uRecalloc(old,nOld,nNew,itemSize) + Opaque old; + unsigned nOld; + unsigned nNew; + unsigned itemSize; +{ +char *rtrn; + + if (old==NULL) + rtrn= (char *)calloc(nNew,itemSize); + else { + rtrn= (char *)realloc((char *)old,nNew*itemSize); + if ((rtrn)&&(nNew>nOld)) { + bzero(&rtrn[nOld*itemSize],(nNew-nOld)*itemSize); + } + } + return (Opaque)rtrn; +} + +/***====================================================================***/ + +void +uFree(ptr) + Opaque ptr; +{ + if (ptr!=(Opaque)NULL) + free((char *)ptr); + return; +} + +/***====================================================================***/ +/*** FUNCTION ENTRY TRACKING ***/ +/***====================================================================***/ + +static FILE *entryFile= NULL; + int uEntryLevel; + +Boolean +uSetEntryFile(name) + char *name; +{ + if ((entryFile!=NULL)&&(entryFile!=stderr)) { + fprintf(entryFile,"switching to %s\n",name?name:"stderr"); + fclose(entryFile); + } + if (name!=NullString) entryFile= fopen(name,"w"); + else entryFile= stderr; + if (entryFile==NULL) { + entryFile= stderr; + return(False); + } + return(True); +} + +void +uEntry(int l, char *s,...) +{ +int i; +va_list ap; + + va_start(ap, s); + for (i=0;i 0x%p\n",rtVal); + return; +} + +/***====================================================================***/ +/*** PRINT FUNCTIONS ***/ +/***====================================================================***/ + + FILE *uDebugFile= NULL; + int uDebugIndentLevel= 0; + int uDebugIndentSize= 4; + +Boolean +uSetDebugFile(name) + char *name; +{ + if ((uDebugFile!=NULL)&&(uDebugFile!=stderr)) { + fprintf(uDebugFile,"switching to %s\n",name?name:"stderr"); + fclose(uDebugFile); + } + if (name!=NullString) uDebugFile= fopen(name,"w"); + else uDebugFile= stderr; + if (uDebugFile==NULL) { + uDebugFile= stderr; + return(False); + } + return(True); +} + +void +uDebug(char *s,...) +{ +int i; +va_list ap; + + va_start(ap, s); + for (i=(uDebugIndentLevel*uDebugIndentSize);i>0;i--) { + putc(' ',uDebugFile); + } + vfprintf(uDebugFile,s,ap); + fflush(uDebugFile); + va_end(ap); + return; +} + +void +uDebugNOI(char *s,...) +{ +va_list ap; + + va_start(ap, s); + vfprintf(uDebugFile,s,ap); + fflush(uDebugFile); + va_end(ap); + return; +} + +/***====================================================================***/ + +static FILE *errorFile= NULL; + +Boolean +uSetErrorFile(char *name) +{ + if ((errorFile!=NULL)&&(errorFile!=stderr)) { + fprintf(errorFile,"switching to %s\n",name?name:"stderr"); + fclose(errorFile); + } + if (name!=NullString) errorFile= fopen(name,"w"); + else errorFile= stderr; + if (errorFile==NULL) { + errorFile= stderr; + return(False); + } + return(True); +} + +void +uInformation(char *s,...) +{ + va_list ap; + + va_start(ap, s); + vfprintf(errorFile,s,ap); + fflush(errorFile); + va_end(ap); + return; +} + +/***====================================================================***/ + +void +uAction(char *s,...) +{ + va_list ap; + + va_start(ap, s); + fprintf(errorFile," "); + vfprintf(errorFile,s,ap); + fflush(errorFile); + va_end(ap); + return; +} + +/***====================================================================***/ + +void +uWarning(char *s,...) +{ + va_list ap; + + va_start(ap, s); + fprintf(errorFile,"Warning: "); + vfprintf(errorFile,s,ap); + fflush(errorFile); + va_end(ap); + return; +} + +/***====================================================================***/ + +void +uError(char *s,...) +{ + va_list ap; + + va_start(ap, s); + fprintf(errorFile,"Error: "); + vfprintf(errorFile,s,ap); + fflush(errorFile); + va_end(ap); + return; +} + +/***====================================================================***/ + +void +uFatalError(char *s,...) +{ + va_list ap; + + va_start(ap, s); + fprintf(errorFile,"Fatal Error: "); + vfprintf(errorFile,s,ap); + fprintf(errorFile," Exiting\n"); + fflush(errorFile); + va_end(ap); + exit(1); + /* NOTREACHED */ +} + +/***====================================================================***/ + +void +uInternalError(char *s,...) +{ + va_list ap; + + va_start(ap, s); + fprintf(errorFile,"Internal error: "); + vfprintf(errorFile,s,ap); + fflush(errorFile); + va_end(ap); + return; +} + +/***====================================================================***/ + +#ifndef HAVE_STRDUP +char * +uStringDup(str) + char *str; +{ +char *rtrn; + + if (str==NULL) + return NULL; + rtrn= (char *)uAlloc(strlen(str)+1); + strcpy(rtrn,str); + return rtrn; +} +#endif + +#ifndef HAVE_STRCASECMP +int +uStrCaseCmp(str1, str2) + char *str1, *str2; +{ + char buf1[512],buf2[512]; + char c, *s; + register int n; + + for (n=0, s = buf1; (c = *str1++); n++) { + if (isupper(c)) + c = tolower(c); + if (n>510) + break; + *s++ = c; + } + *s = '\0'; + for (n=0, s = buf2; (c = *str2++); n++) { + if (isupper(c)) + c = tolower(c); + if (n>510) + break; + *s++ = c; + } + *s = '\0'; + return (strcmp(buf1, buf2)); +} + +int +uStrCasePrefix(prefix, str) + char *prefix, *str; +{ + char c1; + char c2; + while (((c1=*prefix)!='\0')&&((c2=*str)!='\0')) { + if (isupper(c1)) c1= tolower(c1); + if (isupper(c2)) c2= tolower(c2); + if (c1!=c2) + return 0; + prefix++; str++; + } + if (c1!='\0') + return 0; + return 1; +} + +#endif diff --git a/xkbevd/utils.h b/xkbevd/utils.h new file mode 100644 index 0000000..70d3ca4 --- /dev/null +++ b/xkbevd/utils.h @@ -0,0 +1,283 @@ +#ifndef UTILS_H +#define UTILS_H 1 + + /*\ + * $Xorg: utils.h,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ + * + * COPYRIGHT 1990 + * DIGITAL EQUIPMENT CORPORATION + * MAYNARD, MASSACHUSETTS + * ALL RIGHTS RESERVED. + * + * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND + * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. + * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE + * FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED + * WARRANTY. + * + * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT + * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN + * ADDITION TO THAT SET FORTH ABOVE. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Digital Equipment Corporation not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + \*/ +/* $XFree86: xc/programs/xkbevd/utils.h,v 1.6 2002/01/14 18:30:11 dawes Exp $ */ + +/***====================================================================***/ + +#include +#include +#include +#include +#include +#include + +_XFUNCPROTOBEGIN + + +#ifndef NUL +#define NUL '\0' +#endif + +/***====================================================================***/ + +#ifndef OPAQUE_DEFINED +typedef void *Opaque; +#endif +#ifndef NullOpaque +#define NullOpaque ((Opaque)NULL) +#endif + +#ifndef BOOLEAN_DEFINED +typedef char Boolean; +#endif + +#ifndef True +#define True ((Boolean)1) +#define False ((Boolean)0) +#endif /* ndef True */ +#define booleanText(b) ((b)?"True":"False") + +#ifndef COMPARISON_DEFINED +typedef int Comparison; + +#define Greater ((Comparison)1) +#define Equal ((Comparison)0) +#define Less ((Comparison)-1) +#define CannotCompare ((Comparison)-37) +#define comparisonText(c) ((c)?((c)<0?"Less":"Greater"):"Equal") +#endif + +#ifdef notyet +typedef union { + int i; + unsigned u; + void *p; + void *(*fp)(); +} Union; +#endif + +/***====================================================================***/ + +extern Opaque uAlloc( + unsigned /* size */ +); +extern Opaque uCalloc( + unsigned /* n */, + unsigned /* size */ +); +extern Opaque uRealloc( + Opaque /* old */, + unsigned /* newSize */ +); +extern Opaque uRecalloc( + Opaque /* old */, + unsigned /* nOld */, + unsigned /* nNew */, + unsigned /* newSize */ +); +extern void uFree( + Opaque /* ptr */ +); + +#define uTypedAlloc(t) ((t *)uAlloc((unsigned)sizeof(t))) +#define uTypedCalloc(n,t) ((t *)uCalloc((unsigned)n,(unsigned)sizeof(t))) +#define uTypedRealloc(pO,n,t) ((t *)uRealloc((Opaque)pO,((unsigned)n)*sizeof(t))) +#define uTypedRecalloc(pO,o,n,t) ((t *)uRecalloc((Opaque)pO,((unsigned)o),((unsigned)n),sizeof(t))) +#if (defined mdHasAlloca) && (mdHasAlloca) +#define uTmpAlloc(n) ((Opaque)alloca((unsigned)n)) +#define uTmpFree(p) +#else +#define uTmpAlloc(n) uAlloc(n) +#define uTmpFree(p) uFree(p) +#endif + +/***====================================================================***/ + +extern Boolean uSetErrorFile ( char *name ); +extern void uInformation ( char *s, ...); +extern void uAction ( char *s, ... ); +extern void uWarning ( char *s, ... ); +extern void uError ( char *s, ... ); +extern void uFatalError(char *s,...); +extern void uInternalError ( char *s, ... ); + +/***====================================================================***/ + +#define NullString ((char *)NULL) + +#define uStringText(s) ((s)==NullString?"":(s)) +#define uStringEqual(s1,s2) (uStringCompare(s1,s2)==Equal) +#define uStringPrefix(p,s) (strncmp(p,s,strlen(p))==0) +#define uStringCompare(s1,s2) (strcmp(s1,s2)) +#define uStrCaseEqual(s1,s2) (uStrCaseCmp(s1,s2)==0) +#ifdef HAVE_STRCASECMP +#define uStrCaseCmp(s1,s2) (strcasecmp(s1,s2)) +#define uStrCasePrefix(p,s) (strncasecmp(p,s,strlen(p))==0) +#else +extern int uStrCaseCmp( + char * /* s1 */, + char * /* s2 */ +); +extern int uStrCasePrefix( + char * /* p */, + char * /* str */ +); +#endif +#ifdef HAVE_STRDUP +#define uStringDup(s1) (strdup(s1)) +#else +extern char *uStringDup( + char * /* s1 */ +); +#endif + +/***====================================================================***/ + +#ifdef ASSERTIONS_ON +#define uASSERT(where,why) \ + {if (!(why)) uFatalError("assertion botched in %s ( why )\n",where);} +#else +#define uASSERT(where,why) +#endif + +/***====================================================================***/ + +#ifndef DEBUG_VAR +#define DEBUG_VAR debugFlags +#endif + +#ifndef DEBUG_VAR_LOCAL +extern +#endif +unsigned int DEBUG_VAR; + +extern void uDebug( char *s, ... ); +extern void uDebugNOI( char *s, ... ); /* no indent */ +extern Boolean uSetDebugFile( + char *name +); +extern FILE *uDebugFile; +extern int uDebugIndentLevel; +extern int uDebugIndentSize; +#define uDebugIndent(l) (uDebugIndentLevel+=(l)) +#define uDebugOutdent(l) (uDebugIndentLevel-=(l)) +#ifdef DEBUG_ON +#define uDEBUG(f,s) { if (DEBUG_VAR&(f)) uDebug(s);} +#define uDEBUG1(f,s,a) { if (DEBUG_VAR&(f)) uDebug(s,a);} +#define uDEBUG2(f,s,a,b) { if (DEBUG_VAR&(f)) uDebug(s,a,b);} +#define uDEBUG3(f,s,a,b,c) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c);} +#define uDEBUG4(f,s,a,b,c,d) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c,d);} +#define uDEBUG5(f,s,a,b,c,d,e) { if (DEBUG_VAR&(f)) uDebug(s,a,b,c,d,e);} +#define uDEBUG_NOI(f,s) { if (DEBUG_VAR&(f)) uDebug(s);} +#define uDEBUG_NOI1(f,s,a) { if (DEBUG_VAR&(f)) uDebugNOI(s,a);} +#define uDEBUG_NOI2(f,s,a,b) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b);} +#define uDEBUG_NOI3(f,s,a,b,c) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c);} +#define uDEBUG_NOI4(f,s,a,b,c,d) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c,d);} +#define uDEBUG_NOI5(f,s,a,b,c,d,e) { if (DEBUG_VAR&(f)) uDebugNOI(s,a,b,c,d,e);} +#else +#define uDEBUG(f,s) +#define uDEBUG1(f,s,a) +#define uDEBUG2(f,s,a,b) +#define uDEBUG3(f,s,a,b,c) +#define uDEBUG4(f,s,a,b,c,d) +#define uDEBUG5(f,s,a,b,c,d,e) +#define uDEBUG_NOI(f,s) +#define uDEBUG_NOI1(f,s,a) +#define uDEBUG_NOI2(f,s,a,b) +#define uDEBUG_NOI3(f,s,a,b,c) +#define uDEBUG_NOI4(f,s,a,b,c,d) +#define uDEBUG_NOI5(f,s,a,b,c,d,e) +#endif + +extern Boolean uSetEntryFile( + char *name +); +extern void uEntry(int l, char *s, ... ); +extern void uExit( + int l,char *rtVal +); +#ifdef ENTRY_TRACKING_ON +#define ENTRY_BIT 0x10 +#define LOW_ENTRY_BIT 0x1000 +#define ENTER (DEBUG_VAR&ENTRY_BIT) +#define FLAG(fLag) (DEBUG_VAR&(fLag)) + +extern int uEntryLevel; + +#define uENTRY(s) { if (ENTER) uEntry(1,s);} +#define uENTRY1(s,a) { if (ENTER) uEntry(1,s,a);} +#define uENTRY2(s,a,b) { if (ENTER) uEntry(1,s,a,b);} +#define uENTRY3(s,a,b,c) { if (ENTER) uEntry(1,s,a,b,c);} +#define uENTRY4(s,a,b,c,d) { if (ENTER) uEntry(1,s,a,b,c,d);} +#define uENTRY5(s,a,b,c,d,e) { if (ENTER) uEntry(1,s,a,b,c,d,e);} +#define uENTRY6(s,a,b,c,d,e,f) { if (ENTER) uEntry(1,s,a,b,c,d,e,f);} +#define uENTRY7(s,a,b,c,d,e,f,g) { if (ENTER) uEntry(1,s,a,b,c,d,e,f,g);} +#define uRETURN(v) { if (ENTER) uEntryLevel--; return(v); } +#define uVOIDRETURN { if (ENTER) uEntryLevel--; return; } + +#define uFLAG_ENTRY(w,s) { if (FLAG(w)) uEntry(0,s);} +#define uFLAG_ENTRY1(w,s,a) { if (FLAG(w)) uEntry(0,s,a);} +#define uFLAG_ENTRY2(w,s,a,b) { if (FLAG(w)) uEntry(0,s,a,b);} +#define uFLAG_ENTRY3(w,s,a,b,c) { if (FLAG(w)) uEntry(0,s,a,b,c);} +#define uFLAG_ENTRY4(w,s,a,b,c,d) { if (FLAG(w)) uEntry(0,s,a,b,c,d);} +#define uFLAG_ENTRY5(w,s,a,b,c,d,e) { if (FLAG(w)) uEntry(0,s,a,b,c,d,e);} +#define uFLAG_ENTRY6(w,s,a,b,c,d,e,f) { if (FLAG(w)) uEntry(0,s,a,b,c,d,e,f);} +#define uFLAG_ENTRY7(w,s,a,b,c,d,e,f,g) { if(FLAG(w))uEntry(0,s,a,b,c,d,e,f,g);} +#define uFLAG_RETURN(v) { return(v);} +#define uFLAG_VOIDRETURN { return; } +#else +#define uENTRY(s) +#define uENTRY1(s,a) +#define uENTRY2(s,a1,a2) +#define uENTRY3(s,a1,a2,a3) +#define uENTRY4(s,a1,a2,a3,a4) +#define uENTRY5(s,a1,a2,a3,a4,a5) +#define uENTRY6(s,a1,a2,a3,a4,a5,a6) +#define uENTRY7(s,a1,a2,a3,a4,a5,a6,a7) +#define uRETURN(v) { return(v); } +#define uVOIDRETURN { return; } + +#define uFLAG_ENTRY(f,s) +#define uFLAG_ENTRY1(f,s,a) +#define uFLAG_ENTRY2(f,s,a,b) +#define uFLAG_ENTRY3(f,s,a,b,c) +#define uFLAG_ENTRY4(f,s,a,b,c,d) +#define uFLAG_ENTRY5(f,s,a,b,c,d,e) +#define uFLAG_ENTRY6(f,s,a,b,c,d,e,g) +#define uFLAG_ENTRY7(f,s,a,b,c,d,e,g,h) +#define uFLAG_RETURN(v) { return(v);} +#define uFLAG_VOIDRETURN { return; } +#endif + +_XFUNCPROTOEND + +#endif /* UTILS_H */ + + diff --git a/xkbevd/xkbevd.c b/xkbevd/xkbevd.c new file mode 100644 index 0000000..36fd809 --- /dev/null +++ b/xkbevd/xkbevd.c @@ -0,0 +1,552 @@ +/* $Xorg: xkbevd.c,v 1.4 2000/08/17 19:54:49 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbevd/xkbevd.c,v 3.8 2001/01/17 23:46:09 dawes Exp $ */ + +#define DEBUG_VAR xkbevdDebug +#include +#include +#include "xkbevd.h" + + +#define lowbit(x) ((x) & (-(x))) + +/***====================================================================***/ + +#ifndef DFLT_XKBEVD_CONFIG +#define DFLT_XKBEVD_CONFIG "%s/.xkb/xkbevd.cf" +#endif /* DFLT_XKBEVD_CONFIG */ + +#ifndef DFLT_XKB_CONFIG_ROOT +#define DFLT_XKB_CONFIG_ROOT "/usr/X11R6/lib/xkb" +#endif + +#ifndef DFLT_SYS_XKBEVD_CONFIG +#define DFLT_SYS_XKBEVD_CONFIG "%s/xkbevd.cf" +#endif /* DFLT_SYS_XKBEVD_CONFIG */ + +#ifndef DFLT_SOUND_CMD +#define DFLT_SOUND_CMD "/usr/sbin/sfplay -q" +#endif /* DFLT_SOUND_CMD */ + +#ifndef DFLT_SOUND_DIR +#define DFLT_SOUND_DIR "/usr/share/data/sounds/prosonus/" +#endif /* DFLT_SOUND_DIR */ + +/***====================================================================***/ + +char * dpyName= NULL; +Display * dpy= NULL; +char * cfgFileName= NULL; +int xkbOpcode= 0; +int xkbEventCode= 0; +Bool detectableRepeat= False; + +CfgEntryPtr config= NULL; +unsigned long eventMask= 0; + +Bool synch= False; +int verbose= 0; +Bool background= False; + +char * soundCmd= NULL; +char * soundDir= NULL; + +XkbDescPtr xkb= NULL; + +/***====================================================================***/ + +#define M(m) fprintf(stderr,(m)) +#define M1(m,a) fprintf(stderr,(m),(a)) + +static void +Usage(int argc, char *argv[]) +{ + M1("Usage: %s [options]...\n",argv[0]); + M("Legal options:\n"); + M("-?,-help Print this message\n"); + M("-cfg Specify a config file\n"); + M("-sc Specify the command to play sounds\n"); + M("-sd Specify the root directory for sound files\n"); + M("-d[isplay] Specify the display to watch\n"); + M("-bg Run in background\n"); + M("-synch Force synchronization\n"); + M("-v Print verbose messages\n"); + return; +} + +/***====================================================================***/ + +static Bool +parseArgs(int argc, char *argv[]) +{ +register int i; + + for (i=1;i=(argc-1)) { + uError("No configuration file specified on command line\n"); + uAction("Trailing %s argument ignored\n",argv[i]); + } + else { + char *name= argv[++i]; + if (cfgFileName!=NULL) { + if (uStringEqual(cfgFileName,name)) + uWarning("Config file \"%s\" specified twice!\n"); + else { + uWarning("Multiple config files on command line\n"); + uAction("Using \"%s\", ignoring \"%s\"\n",name, + cfgFileName); + } + } + cfgFileName= name; + } + } + else if ((strcmp(argv[i],"-d")==0)||(strcmp(argv[i],"-display")==0)) { + if (i>=(argc-1)) { + uError("No display specified on command line\n"); + uAction("Trailing %s argument ignored\n",argv[i]); + } + else { + char *name= argv[++i]; + if (dpyName!=NULL) { + if (uStringEqual(dpyName,name)) + uWarning("Display \"%s\" specified twice!\n"); + else { + uWarning("Multiple displays on command line\n"); + uAction("Using \"%s\", ignoring \"%s\"\n",name, + dpyName); + } + } + dpyName= name; + } + } + else if (strcmp(argv[i],"-sc")==0) { + if (i>=(argc-1)) { + uError("No sound command specified on command line\n"); + uAction("Trailing %s argument ignored\n",argv[i]); + } + else { + char *name= argv[++i]; + if (soundCmd!=NULL) { + if (uStringEqual(soundCmd,name)) + uWarning("Sound command \"%s\" specified twice!\n"); + else { + uWarning("Multiple sound commands on command line\n"); + uAction("Using \"%s\", ignoring \"%s\"\n",name, + soundCmd); + } + } + soundCmd= name; + } + } + else if (strcmp(argv[i],"-sd")==0) { + if (i>=(argc-1)) { + uError("No sound directory specified on command line\n"); + uAction("Trailing %s argument ignored\n",argv[i]); + } + else { + char *name= argv[++i]; + if (soundDir!=NULL) { + if (uStringEqual(soundDir,name)) + uWarning("Sound directory \"%s\" specified twice!\n"); + else { + uWarning("Multiple sound dirs on command line\n"); + uAction("Using \"%s\", ignoring \"%s\"\n",name, + soundDir); + } + } + soundDir= name; + } + } + else if ((strcmp(argv[i],"-synch")==0)||(strcmp(argv[i],"-s")==0)) { + synch= True; + } + else if (strcmp(argv[i],"-v")==0) { + verbose++; + } + else if ((strcmp(argv[i],"-?")==0)||(strcmp(argv[i],"-help")==0)) { + Usage(argc,argv); + exit(0); + } + else { + uError("Unknown flag \"%s\" on command line\n",argv[i]); + Usage(argc,argv); + return False; + } + } + return True; +} + +static Display * +GetDisplay(char *program, char *dpyName, int *opcodeRtrn, int *evBaseRtrn) +{ +int mjr,mnr,error; +Display *dpy; + + mjr= XkbMajorVersion; + mnr= XkbMinorVersion; + dpy= XkbOpenDisplay(dpyName,evBaseRtrn,NULL,&mjr,&mnr,&error); + if (dpy==NULL) { + switch (error) { + case XkbOD_BadLibraryVersion: + uInformation("%s was compiled with XKB version %d.%02d\n", + program,XkbMajorVersion,XkbMinorVersion); + uError("X library supports incompatible version %d.%02d\n", + mjr,mnr); + break; + case XkbOD_ConnectionRefused: + uError("Cannot open display \"%s\"\n",dpyName); + break; + case XkbOD_NonXkbServer: + uError("XKB extension not present on %s\n",dpyName); + break; + case XkbOD_BadServerVersion: + uInformation("%s was compiled with XKB version %d.%02d\n", + program,XkbMajorVersion,XkbMinorVersion); + uError("Server %s uses incompatible version %d.%02d\n", + dpyName,mjr,mnr); + break; + default: + uInternalError("Unknown error %d from XkbOpenDisplay\n",error); + } + } + else if (synch) + XSynchronize(dpy,True); + if (opcodeRtrn) + XkbQueryExtension(dpy,opcodeRtrn,evBaseRtrn,NULL,&mjr,&mnr); + return dpy; +} + +/***====================================================================***/ + +void +InterpretConfigs(CfgEntryPtr cfg) +{ +char * name; +unsigned priv= 0; + + config= cfg; + while (cfg!=NULL) { + name= cfg->name.str; + if (cfg->entry_type==VariableDef) { + if (uStrCaseEqual(name,"sounddirectory")|| + uStrCaseEqual(name,"sounddir")) { + if (soundDir==NULL) { + soundDir= cfg->action.text; + cfg->name.str= NULL; + cfg->action.text= NULL; + } + } + else if (uStrCaseEqual(name,"soundcommand")|| + uStrCaseEqual(name,"soundcmd")) { + if (soundCmd==NULL) { + soundCmd= cfg->action.text; + cfg->name.str= NULL; + cfg->action.text= NULL; + } + } + else { + uWarning("Assignment to unknown variable \"%s\"\n",cfg->name); + uAction("Ignored\n"); + } + } + else if (cfg->entry_type==EventDef) switch (cfg->event_type) { + case XkbBellNotify: + if (name!=NULL) cfg->name.atom= XInternAtom(dpy,name,False); + else cfg->name.atom= None; + if (name) uFree(name); + break; + case XkbAccessXNotify: + priv= 0; + if (name==NULL) + priv= XkbAllNewKeyboardEventsMask; + else if (uStrCaseEqual(name,"skpress")) + priv= XkbAXN_SKPressMask; + else if (uStrCaseEqual(name,"skaccept")) + priv= XkbAXN_SKAcceptMask; + else if (uStrCaseEqual(name,"skreject")) + priv= XkbAXN_SKRejectMask; + else if (uStrCaseEqual(name,"skrelease")) + priv= XkbAXN_SKReleaseMask; + else if (uStrCaseEqual(name,"bkaccept")) + priv= XkbAXN_BKAcceptMask; + else if (uStrCaseEqual(name,"bkreject")) + priv= XkbAXN_BKRejectMask; + else if (uStrCaseEqual(name,"warning")) + priv= XkbAXN_AXKWarningMask; + if (name) uFree(name); + cfg->name.priv= priv; + break; + case XkbActionMessage: + /* nothing to do */ + break; + } + eventMask|= (1L<event_type); + cfg= cfg->next; + } + while ((config)&&(config->entry_type!=EventDef)) { + CfgEntryPtr next; + if (config->name.str) uFree(config->name.str); + if (config->action.text) uFree(config->action.text); + config->name.str= NULL; + config->action.text= NULL; + next= config->next; + uFree(config); + config= next; + } + cfg= config; + while ((cfg!=NULL)&&(cfg->next!=NULL)) { + CfgEntryPtr next; + next= cfg->next; + if (next->entry_type!=EventDef) { + if (next->name.str) uFree(config->name.str); + if (next->action.text) uFree(config->action.text); + next->name.str= NULL; + next->action.text= NULL; + cfg->next= next->next; + next->next= NULL; + uFree(next); + } + else cfg= next; + } + return; +} + +static CfgEntryPtr +FindMatchingConfig(XkbEvent *ev) +{ +CfgEntryPtr cfg,dflt; + + dflt= NULL; + for (cfg= config;(cfg!=NULL);cfg=cfg->next) { + if ((ev->type!=xkbEventCode)||(cfg->event_type!=ev->any.xkb_type)) + continue; + switch (ev->any.xkb_type) { + case XkbBellNotify: + if (ev->bell.name==cfg->name.atom) + return cfg; + else if ((cfg->name.atom==None)&&(dflt==NULL)) + dflt= cfg; + break; + case XkbAccessXNotify: + if (cfg->name.priv&(1L<accessx.detail)) + return cfg; + break; + case XkbActionMessage: + if (cfg->name.str==NULL) + dflt= cfg; + else if (strncmp(cfg->name.str,ev->message.message, + XkbActionMessageLength)==0) + return cfg; + break; + default: + uInternalError("Can't handle type %d XKB events yet, Sorry.\n"); + break; + } + } + return dflt; +} + +static Bool +ProcessMatchingConfig(XkbEvent *ev) +{ +CfgEntryPtr cfg; +char buf[1024],*cmd; +int ok; + + cfg= FindMatchingConfig(ev); + if (!cfg) + return False; + if (cfg->action.type==UnknownAction) { + if (cfg->action.text==NULL) + cfg->action.type= NoAction; + else if (cfg->action.text[0]=='!') { + char *tmp; + cfg->action.type= ShellAction; + tmp= uStringDup(&cfg->action.text[1]); + uFree(cfg->action.text); + cfg->action.text= tmp; + } + else cfg->action.type= SoundAction; + } + switch (cfg->action.type) { + case NoAction: + return True; + case EchoAction: + if (cfg->action.text!=NULL) { + sprintf(buf,cfg->action.text); + cmd= SubstituteEventArgs(buf,ev); + printf("%s",cmd); + } + return True; + case PrintEvAction: + PrintXkbEvent(stdout,ev); + return True; + case ShellAction: + if (cfg->action.text==NULL) { + uWarning("Empty shell command!\n"); + uAction("Ignored\n"); + return True; + } + cmd= cfg->action.text; + break; + case SoundAction: + if (cfg->action.text==NULL) { + uWarning("Empty sound command!\n"); + uAction("Ignored\n"); + return True; + } + sprintf(buf,"%s %s%s",soundCmd,soundDir,cfg->action.text); + cmd= buf; + break; + default: + uInternalError("Unknown error action type %d\n",cfg->action.type); + return False; + } + cmd= SubstituteEventArgs(cmd,ev); + if (verbose) + uInformation("Executing shell command \"%s\"\n",cmd); + ok= (system(cmd)==0); + return ok; +} + +/***====================================================================***/ + +int +main(int argc, char *argv[]) +{ +FILE * file; +static char buf[1024]; +XkbEvent ev; +Bool ok; + + + yyin = stdin; + uSetEntryFile(NullString); + uSetDebugFile(NullString); + uSetErrorFile(NullString); + + if (!parseArgs(argc,argv)) + exit(1); + file= NULL; + XkbInitAtoms(NULL); + if (cfgFileName==NULL) { + char *home; + home= (char *)getenv("HOME"); + sprintf(buf,DFLT_XKBEVD_CONFIG,(home?home:"")); + cfgFileName= buf; + } + if (uStringEqual(cfgFileName,"-")) { + static char *in= "stdin"; + file= stdin; + cfgFileName= in; + } + else { + file= fopen(cfgFileName,"r"); + if (file==NULL) { /* no personal config, try for a system one */ + if (cfgFileName!=buf) { /* user specified a file. bail */ + uError("Can't open config file \"%s\n",cfgFileName); + uAction("Exiting\n"); + exit(1); + } + sprintf(buf,DFLT_SYS_XKBEVD_CONFIG,DFLT_XKB_CONFIG_ROOT); + file= fopen(cfgFileName,"r"); + if (file==NULL) { + if (verbose) { + uError("Couldn't find a config file anywhere\n"); + uAction("Exiting\n"); + exit(1); + } + exit(0); + } + } + } + + if (background) { + if (fork()!=0) { + if (verbose) + uInformation("Running in the background\n"); + exit(0); + } + } + dpy= GetDisplay(argv[0],dpyName,&xkbOpcode,&xkbEventCode); + if (!dpy) + goto BAILOUT; + ok= True; + setScanState(cfgFileName,1); + CFGParseFile(file); + if (!config) { + uError("No configuration specified in \"%s\"\n",cfgFileName); + goto BAILOUT; + } + if (eventMask==0) { + uError("No events to watch in \"%s\"\n",cfgFileName); + goto BAILOUT; + } + if (!XkbSelectEvents(dpy,XkbUseCoreKbd,eventMask,eventMask)) { + uError("Couldn't select desired XKB events\n"); + goto BAILOUT; + } + xkb= XkbGetKeyboard(dpy,XkbGBN_AllComponentsMask,XkbUseCoreKbd); + if (eventMask&XkbBellNotifyMask) { + unsigned ctrls,vals; + if (verbose) + uInformation("Temporarily disabling the audible bell\n"); + if (!XkbChangeEnabledControls(dpy,XkbUseCoreKbd,XkbAudibleBellMask,0)) { + uError("Couldn't disable audible bell\n"); + goto BAILOUT; + } + ctrls= vals= XkbAudibleBellMask; + if (!XkbSetAutoResetControls(dpy,XkbAudibleBellMask,&ctrls,&vals)) { + uWarning("Couldn't configure audible bell to reset on exit\n"); + uAction("Audible bell might remain off\n"); + } + } + if (soundCmd==NULL) soundCmd= DFLT_SOUND_CMD; + if (soundDir==NULL) soundDir= DFLT_SOUND_DIR; + XkbStdBellEvent(dpy,None,0,XkbBI_ImAlive); + while (1) { + XNextEvent(dpy,&ev.core); + if ((!ProcessMatchingConfig(&ev))&&(ev.type==xkbEventCode)&& + (ev.any.xkb_type==XkbBellNotify)) { + XkbForceDeviceBell(dpy,ev.bell.device, + ev.bell.bell_class,ev.bell.bell_id, + ev.bell.percent); + } + } + + XCloseDisplay(dpy); + return (ok==0); +BAILOUT: + uAction("Exiting\n"); + if (dpy!=NULL) + XCloseDisplay(dpy); + exit(1); +} diff --git a/xkbevd/xkbevd.h b/xkbevd/xkbevd.h new file mode 100644 index 0000000..f7e9241 --- /dev/null +++ b/xkbevd/xkbevd.h @@ -0,0 +1,105 @@ +/* $Xorg: xkbevd.h,v 1.3 2000/08/17 19:54:49 cpqbld Exp $ */ +/************************************************************ + Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. + + Permission to use, copy, modify, and distribute this + software and its documentation for any purpose and without + fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright + notice and this permission notice appear in supporting + documentation, and that the name of Silicon Graphics not be + used in advertising or publicity pertaining to distribution + of the software without specific prior written permission. + Silicon Graphics makes no representation about the suitability + of this software for any purpose. It is provided "as is" + without any express or implied warranty. + + SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + GRAPHICS 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. + + ********************************************************/ +/* $XFree86: xc/programs/xkbevd/xkbevd.h,v 3.4 2001/01/17 23:46:09 dawes Exp $ */ + +#ifndef XKBEVD_H +#define XKBEVD_H 1 + +#include +#include +#include +#include +#include + +#include "utils.h" + +extern FILE * yyin; +extern char * scanFile; +extern int lineNum; +extern int scanInt; +extern char * scanIntStr; +extern int scanIntClass; +extern char * scanStr; +extern int scanStrLine; + +extern Display * dpy; +extern int xkbOpcode; +extern int xkbEventCode; +extern Bool detectableRepeat; + +extern XkbDescPtr xkb; + +#define UnknownAction 0 +#define NoAction 1 +#define EchoAction 2 +#define PrintEvAction 3 +#define ShellAction 4 +#define SoundAction 5 + +typedef struct _ActDef { + int type; + char * text; + unsigned priv; +} ActDefRec,*ActDefPtr; + +#define EventDef 0 +#define VariableDef 1 + +typedef struct _CfgEntry { + unsigned char entry_type; + unsigned char event_type; + union { + char * str; + Atom atom; + unsigned priv; + } name; + ActDefRec action; + struct _CfgEntry * next; +} CfgEntryRec,*CfgEntryPtr; + +extern void InterpretConfigs( + CfgEntryPtr /* cfgs */ +); + +extern char *SubstituteEventArgs( + char * /* cmd */, + XkbEvent * /* ev */ +); + +extern void PrintXkbEvent( + FILE * /* file */, + XkbEvent * /* ev */ +); + +extern int setScanState ( char * file, int line ); +extern int CFGParseFile ( FILE *file ); + +extern int yylex(void); +extern int yyparse(void); +extern int yyerror(char *s); +extern int yywrap(void); +#endif /* XKBEVD_H */ diff --git a/xman/AUTHORS b/xman/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xman/COPYING b/xman/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xman/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xman/INSTALL b/xman/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xman/Makefile.am b/xman/Makefile.am new file mode 100644 index 0000000..1b4de74 --- /dev/null +++ b/xman/Makefile.am @@ -0,0 +1,109 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xman + +helpdir=@HELPDIR@ +dist_help_DATA = xman.help + +xman_CFLAGS = $(XMAN_CFLAGS) -D_BSD_SOURCE -DHELPFILE=\"$(helpdir)/xman.help\" +xman_LDADD = $(XMAN_LIBS) + +xman_SOURCES = \ + buttons.c \ + defs.h \ + globals.c \ + globals.h \ + handler.c \ + help.c \ + iconclosed.h \ + icon_help.h \ + icon_open.h \ + main.c \ + man.c \ + man.h \ + misc.c \ + ScrollByL.c \ + ScrollByL.h \ + ScrollByLP.h \ + search.c \ + tkfuncs.c \ + vendor.c \ + vendor.h \ + version.h + +if XAW_USE_XPRINT +xman_SOURCES += \ + print.c \ + print.h +endif + +appman_PRE = \ + xman.man + +# App default files (*.ad) + +appdefaultdir = @appdefaultdir@ + +if XAW_USE_XPRINT +Xman: Xman-xprint.ad + ln -s $(top_srcdir)/Xman-xprint.ad Xman +else +Xman: Xman-noxprint.ad + ln -s $(top_srcdir)/Xman-noxprint.ad Xman +endif + +appdefault_DATA = Xman + +EXTRA_DIST = Xman-xprint.ad Xman-noxprint.ad + +CLEANFILES = Xman + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST += $(appman_PRE) +CLEANFILES += $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xman/NEWS b/xman/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xman/README b/xman/README new file mode 100644 index 0000000..e69de29 diff --git a/xman/ScrollByL.c b/xman/ScrollByL.c new file mode 100644 index 0000000..c679145 --- /dev/null +++ b/xman/ScrollByL.c @@ -0,0 +1,1215 @@ +/* $XConsortium: ScrollByL.c,v 1.30 94/04/17 20:43:46 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xman/ScrollByL.c,v 1.6tsi Exp $ */ + +#if !defined(lint) && !defined(SABER) && 0 + static char rcs_version[] = "$Athena: ScrollByL.c,v 4.5 88/12/19 13:46:04 kit Exp $"; +#endif + +#include +#include +#include +#include + +#include +#include /* depends on IntrinsicP.h */ +#include + +#include +#include + +#include "ScrollByLP.h" + +/* Default Translation Table */ + +static char defaultTranslations[] = + "f: Page(Forward) \n\ + b: Page(Back) \n\ + 1: Page(Line, 1) \n\ + 2: Page(Line, 2) \n\ + 3: Page(Line, 3) \n\ + 4: Page(Line, 4) \n\ + \\ : Page(Forward)"; + + +/**************************************************************** + * + * ScrollByLine Resources + * + ****************************************************************/ + +#define Offset(field) XtOffset(ScrollByLineWidget, scroll.field) +#define CoreOffset(field) XtOffset(ScrollByLineWidget, core.field) + +static XtResource resources[] = { + {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension), + CoreOffset(width), XtRImmediate, (caddr_t) 500}, + {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension), + CoreOffset(height), XtRImmediate, (caddr_t) 700}, + + {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + Offset(foreground), XtRString, "XtDefaultForeground"}, + {XtNforceVert, XtCBoolean, XtRBoolean, sizeof(Boolean), + Offset(force_vert), XtRImmediate, (caddr_t) FALSE}, + {XtNindent, XtCIndent, XtRDimension, sizeof(Dimension), + Offset(indent), XtRImmediate, (caddr_t) 15}, + {XtNuseRight, XtCBoolean, XtRBoolean, sizeof(Boolean), + Offset(use_right), XtRImmediate, (caddr_t) FALSE}, + {XtNmanualFontNormal, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + Offset(normal_font), XtRString, MANPAGE_NORMAL}, + {XtNmanualFontBold, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + Offset(bold_font), XtRString, MANPAGE_BOLD}, + {XtNmanualFontItalic, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + Offset(italic_font), XtRString, MANPAGE_ITALIC}, + {XtNmanualFontSymbol, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + Offset(symbol_font), XtRString, MANPAGE_SYMBOL}, + {XtNfile, XtCFile, XtRFile, sizeof(FILE *), + Offset(file), XtRImmediate, (caddr_t) NULL}, + {XtNNumTotalLines, XtCNumTotalLines, XtRInt, sizeof(int), + Offset(lines), XtRImmediate, (caddr_t) 0}, + {XtNNumVisibleLines, XtCNumVisibleLines, XtRInt, sizeof(int), + Offset(num_visible_lines), XtRImmediate, (caddr_t) 0}, +}; + +#undef Offset +#undef CoreOffset + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +static void CreateScrollbar(Widget w); +static Boolean ScrollVerticalText(Widget w, int new_line, Boolean force_redisp); +static void Layout(Widget w); +static void LoadFile(Widget w); +static void MoveAndClearText(Widget w, int old_y, int height, int new_y); +static void PaintText(Widget w, int y_loc, int height); +static void PrintText(Widget w, int start_line, int num_lines, int location); +static void SetThumbHeight(Widget w); +static void VerticalJump(Widget w, XtPointer junk, XtPointer percent_ptr); +static void VerticalScroll(Widget w, XtPointer client_data, XtPointer call_data); + +/* semi - public functions. */ + +static void Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes); +static void Initialize(Widget req, Widget new, ArgList args, Cardinal *num_args); +static void Destroy(Widget w); +static void Redisplay(Widget w, XEvent *event, Region region); +static void Page(Widget w, XEvent * event, String * params, Cardinal *num_params); +static Boolean SetValuesHook(Widget w, ArgList args, Cardinal *num_args); + +static XtActionsRec actions[] = { + { "Page", Page}, +}; + +#define superclass (&simpleClassRec) +#define SuperClass simpleWidgetClass + +ScrollByLineClassRec scrollByLineClassRec = { + { +/* core_class fields */ + /* superclass */ (WidgetClass) superclass, + /* class_name */ "ScrollByLine", + /* widget_size */ sizeof(ScrollByLineRec), + /* class_initialize */ NULL, + /* class_part_init */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ actions, + /* num_actions */ XtNumber(actions), + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ FALSE, + /* compress_enterleave*/ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ Layout, + /* expose */ Redisplay, + /* set_values */ NULL, + /* set_values_hook */ SetValuesHook, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ defaultTranslations, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator*/ XtInheritDisplayAccelerator, + /* extension */ NULL, + }, + { /* simple fields */ + /* change_sensitive */ XtInheritChangeSensitive + } +}; + +WidgetClass scrollByLineWidgetClass = + (WidgetClass) &scrollByLineClassRec; + + +/**************************************************************** + * + * Private Routines + * + ****************************************************************/ + +/* Function Name: Layout + * Description: This function lays out the scroll widget. + * Arguments: w - the scroll widget. + * key - a boolean: if true then resize the widget to the child + * if false the resize children to fit widget. + * Returns: TRUE if successful. + */ + +static void +Layout(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + Dimension width, height; + Widget bar; + Position bar_bw; + + CreateScrollbar(w); + +/* + * For now always show the bar. + */ + + bar = sblw->scroll.bar; + height = sblw->core.height; + width = sblw->core.width; + bar_bw = bar->core.border_width; + + /* Move child and v_bar to correct location. */ + + if (sblw->scroll.use_right) { + XtMoveWidget(bar, width - (bar->core.width + bar_bw), - bar_bw); + sblw->scroll.offset = 0; + } + else { + XtMoveWidget(bar, - bar_bw, - bar_bw); + sblw->scroll.offset = bar->core.width + bar_bw; + } + + /* resize the scrollbar to be the correct height or width. */ + + XtResizeWidget(bar, bar->core.width, height, bar->core.border_width); + + SetThumbHeight(w); + + sblw->scroll.num_visible_lines = height / sblw->scroll.font_height + 1; +} + +/* ARGSUSED */ +static void +GExpose(Widget w, XtPointer junk, XEvent *event, Boolean *cont) +{ + +/* + * Graphics exposure events are not currently sent to exposure proc. + */ + + if (event->type == GraphicsExpose) + Redisplay(w, event, NULL); + +} /* ChildExpose */ + +/* + * Repaint the widget's child Window Widget. + */ + +/* ARGSUSED */ +static void +Redisplay(Widget w, XEvent *event, Region region) +{ + int top, height; /* the locations of the top and height + of the region that needs to be repainted. */ + +/* + * This routine tells the client which sections of the window to + * repaint in his callback function which does the actual repainting. + */ + + if (event->type == Expose) { + top = event->xexpose.y; + height = event->xexpose.height; + } + else { + top = event->xgraphicsexpose.y; + height = event->xgraphicsexpose.height; + } + + PaintText(w, top, height); +} /* redisplay (expose) */ + +/* Function Name: PaintText + * Description: paints the text at the give location for a given height. + * Arguments: w - the sbl widget. + * y_loc, height - location and size of area to paint. + * Returns: none + */ + +static void +PaintText(Widget w, int y_loc, int height) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + int start_line, location; + + start_line = y_loc / sblw->scroll.font_height + sblw->scroll.line_pointer; + + if (start_line >= sblw->scroll.lines) + return; + +/* + * Only integer arithmetic makes this possible. + */ + + location = y_loc / sblw->scroll.font_height * sblw->scroll.font_height; + + PrintText(w, start_line, sblw->scroll.num_visible_lines, location); +} + +/* Function Name: Page + * Description: This function pages the widget, by the amount it recieves + * from the translation Manager. + * Arguments: w - the ScrollByLineWidget. + * event - the event that caused this return. + * params - the parameters passed to it. + * num_params - the number of parameters. + * Returns: none. + */ + +/* ARGSUSED */ +static void +Page(Widget w, XEvent * event, String * params, Cardinal *num_params) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + Widget bar = sblw->scroll.bar; + + if (*num_params < 1) + return; +/* + * If no scroll bar is visible then do not page, as the entire window is shown, + * of scrolling has been turned off. + */ + + if (bar == (Widget) NULL) + return; + + switch ( params[0][0] ) { + case 'f': + case 'F': + /* move one page forward */ + VerticalScroll(bar, NULL, (XtPointer)((long) bar->core.height)); + break; + case 'b': + case 'B': + /* move one page backward */ + VerticalScroll(bar, NULL, (XtPointer)(- (long) bar->core.height)); + break; + case 'L': + case 'l': + /* move one line forward */ + VerticalScroll(bar, NULL, + (XtPointer)((long) atoi(params[1]) * sblw->scroll.font_height)); + break; + default: + return; + } +} + +/* Function Name: CreateScrollbar + * Description: createst the scrollbar for us. + * Arguments: w - sblw widget. + * Returns: none. + */ + +static void +CreateScrollbar(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + Arg args[5]; + Cardinal num_args = 0; + + if (sblw->scroll.bar != NULL) + return; + + XtSetArg(args[num_args], XtNorientation, XtorientVertical); num_args++; + + sblw->scroll.bar = XtCreateWidget("scrollbar", scrollbarWidgetClass, w, + args, num_args); + XtAddCallback(sblw->scroll.bar, XtNscrollProc, VerticalScroll, NULL); + XtAddCallback(sblw->scroll.bar, XtNjumpProc, VerticalJump, NULL); +} + +/* Function Name: ScrollVerticalText + * Description: This accomplished the actual movement of the text. + * Arguments: w - the ScrollByLine Widget. + * new_line - the new location for the line pointer + * force_redisplay - should we force this window to get + * redisplayed? + * Returns: True if the thumb needs to be moved. + */ + +static Boolean +ScrollVerticalText( +Widget w, +int new_line, +Boolean force_redisp) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + int num_lines = sblw->scroll.num_visible_lines; + int max_lines, old_line; + Boolean move_thumb = FALSE; + +/* + * Do not let the window extend out of bounds. + */ + + if ( new_line < 0) { + new_line = 0; + move_thumb = TRUE; + } + else { + max_lines = sblw->scroll.lines - (int)w->core.height / sblw->scroll.font_height; + AssignMax(max_lines, 0); + + if ( new_line > max_lines ) { + new_line = max_lines; + move_thumb = TRUE; + } + } + +/* + * If forced to redisplay then do a full redisplay and return. + */ + + old_line = sblw->scroll.line_pointer; + sblw->scroll.line_pointer = new_line; /* Set current top of page. */ + + if (force_redisp) + MoveAndClearText(w, 0, /* cause a full redisplay */ 0, 0); + + if (new_line == old_line) + return(move_thumb); + +/* + * Scroll forward. + */ + + else if (new_line < old_line) { + int lines_to_scroll = old_line - new_line; + MoveAndClearText(w, 0, num_lines - lines_to_scroll, lines_to_scroll); + } + +/* + * Scroll back. + */ + + else { + int lines_to_scroll = new_line - old_line; + MoveAndClearText(w, lines_to_scroll, num_lines - lines_to_scroll, 0); + } + + return(move_thumb); +} + +/* Function Name: MoveAndClearText + * Description: Blits as much text as it can and clear the + * remaining area with generate exposures TRUE. + * Arguments: w - the sbl widget. + * old_y - the old y position. + * height - height of area to move. + * new_y - new y position. + * Returns: none + */ + +static void +MoveAndClearText(Widget w, int old_y, int height, int new_y) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + int from_left = sblw->scroll.indent + sblw->scroll.offset - 1; + int y_clear; + + old_y *= sblw->scroll.font_height; + new_y *= sblw->scroll.font_height; + height *= sblw->scroll.font_height; + +/* + * If we are already at the right location then do nothing. + * (height == 0). + * + * If we have scrolled more than a screen height then just clear + * the window. + */ + + if (height <= sblw->scroll.font_height) { /* avoid rounding errors. */ + XClearArea( XtDisplay(w), XtWindow(w), from_left, 0, + (unsigned int) 0, (unsigned int) 0, FALSE); + PaintText(w, 0, (int) sblw->core.height); + return; + } + + if ((int)height + (int)old_y > (int)w->core.height) + height = w->core.height - old_y; + + XCopyArea(XtDisplay(w), XtWindow(w), XtWindow(w), sblw->scroll.move_gc, + from_left, old_y, + (unsigned int) w->core.width - from_left, (unsigned int) height, + from_left, new_y); + + if (old_y > new_y) + height -= sblw->scroll.font_height/2; /* clear 1/2 font of extra space, + to make sure we don't lose or + gain decenders. */ + else + height -= sblw->scroll.font_height; /* clear 1 font of extra space, + to make sure we don't overwrite + with a last line in buffer. */ + + if (old_y > new_y) + y_clear = height; + else + y_clear = 0; + +/* + * We cannot use generate exposures, since that may allow another move and + * clear before the area get repainted, this would be bad. + */ + + XClearArea( XtDisplay(w), XtWindow(w), from_left, y_clear, + (unsigned int) 0, (unsigned int) (w->core.height - height), + FALSE); + PaintText(w, (int) y_clear, (int) (w->core.height - height)); +} + +/* Function Name: SetThumbHeight + * Description: Set the height of the thumb. + * Arguments: w - the sblw widget. + * Returns: none + */ + +static void +SetThumbHeight(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + float shown; + + if (sblw->scroll.bar == NULL) + return; + + if (sblw->scroll.lines == 0) + shown = 1.0; + else + shown = (float) w->core.height / (float) (sblw->scroll.lines * + sblw->scroll.font_height); + if (shown > 1.0) + shown = 1.0; + + XawScrollbarSetThumb( sblw->scroll.bar, (float) -1, shown ); +} + +/* Function Name: SetThumb + * Description: Set the thumb location. + * Arguments: w - the sblw. + * Returns: none + */ + +static void +SetThumb(Widget w) +{ + float location; + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + + if ( (sblw->scroll.lines == 0) || (sblw->scroll.bar == NULL) ) + return; + + location = (float) sblw->scroll.line_pointer / (float) sblw->scroll.lines; + XawScrollbarSetThumb( sblw->scroll.bar, location , (float) -1 ); +} + +/* Function Name: VerticalJump. + * Description: This function moves the test + * as the vertical scroll bar is moved. + * Arguments: w - the scrollbar widget. + * junk - not used. + * percent - the position of the scrollbar. + * Returns: none. + */ + +/* ARGSUSED */ +static void +VerticalJump(Widget w, XtPointer junk, XtPointer percent_ptr) +{ + float percent = *((float *) percent_ptr); + int new_line; /* The new location for the line pointer. */ + ScrollByLineWidget sblw = (ScrollByLineWidget) XtParent(w); + + new_line = (int) ((float) sblw->scroll.lines * percent); + if (ScrollVerticalText( (Widget) sblw, new_line, FALSE)) + SetThumb((Widget) sblw); +} + +/* Function Name: VerticalScroll + * Description: This function moves the postition of the interior window + * as the vertical scroll bar is moved. + * Arguments: w - the scrollbar widget. + * junk - not used. + * pos - the position of the cursor. + * Returns: none. + */ + +/* ARGSUSED */ +static void +VerticalScroll(Widget w, XtPointer client_data, XtPointer call_data) +{ + int pos = (int)(long) call_data; + int new_line; /* The new location for the line pointer. */ + ScrollByLineWidget sblw = (ScrollByLineWidget) XtParent(w); + + new_line = sblw->scroll.line_pointer + (pos / sblw->scroll.font_height); + (void) ScrollVerticalText( (Widget) sblw, new_line, FALSE); + SetThumb( (Widget) sblw); +} + +/* ARGSUSED */ +static void +Initialize(Widget req, Widget new, ArgList args, Cardinal *num_args) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) new; + unsigned long figWidth; + Atom atomNum; + + sblw->scroll.top_line = NULL; + sblw->scroll.line_pointer = 0; + LoadFile(new); + sblw->scroll.bar = (Widget) NULL; + + sblw->scroll.font_height = (sblw->scroll.normal_font->max_bounds.ascent + + sblw->scroll.normal_font->max_bounds.descent); + + atomNum = XInternAtom(XtDisplay(req), "FIGURE_WIDTH", False); + + if (XGetFontProperty(sblw->scroll.normal_font, atomNum, &figWidth)) + sblw->scroll.h_width = figWidth; + else + sblw->scroll.h_width = XTextWidth(sblw->scroll.normal_font, "$", 1); +} /* Initialize. */ + +/* Function Name: CreateGCs + * Description: Creates the graphics contexts that we need. + * Arguments: w - the sblw. + * Returns: none + */ + +static void +CreateGCs(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + + XtGCMask mask; + XGCValues values; + + values.graphics_exposures = TRUE; + sblw->scroll.move_gc = XtGetGC(w, GCGraphicsExposures, &values); + + mask = GCForeground | GCFont; + values.foreground = sblw->scroll.foreground; + + values.font = sblw->scroll.normal_font->fid; + sblw->scroll.normal_gc = XtGetGC(w, mask, &values); + + values.font = sblw->scroll.italic_font->fid; + sblw->scroll.italic_gc = XtGetGC(w, mask, &values); + + values.font = sblw->scroll.bold_font->fid; + sblw->scroll.bold_gc = XtGetGC(w, mask, &values); + + values.font = sblw->scroll.symbol_font->fid; + sblw->scroll.symbol_gc = XtGetGC(w, mask, &values); +} + +/* Function Name: DestroyGCs + * Description: removes all gcs for this widget. + * Arguments: w - the widget. + * Returns: none + */ + +static void +DestroyGCs(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + + XtReleaseGC(w, sblw->scroll.normal_gc); + XtReleaseGC(w, sblw->scroll.bold_gc); + XtReleaseGC(w, sblw->scroll.italic_gc); + XtReleaseGC(w, sblw->scroll.move_gc); +} + +static void +Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + + CreateScrollbar(w); + CreateGCs(w); + Layout(w); + (*SuperClass->core_class.realize) (w, valueMask, attributes); + XtRealizeWidget(sblw->scroll.bar); /* realize scrollbar. */ + XtMapWidget(sblw->scroll.bar); /* map scrollbar. */ + + XtAddEventHandler(w, 0, TRUE, GExpose, NULL); /* Get Graphics Exposures */ +} /* Realize */ + +/* Function Name: Destroy + * Description: Cleans up when we are killed. + * Arguments: w - the widget. + * Returns: none + */ + +static void +Destroy(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + + if (sblw->scroll.bar != NULL) + XtDestroyWidget(sblw->scroll.bar); /* Destroy scrollbar. */ + if (sblw->scroll.file != NULL) + fclose(sblw->scroll.file); + DestroyGCs(w); +} + +/* + * + * Set Values + * + */ + +/* ARGSUSED */ +static Boolean +SetValuesHook(Widget w, ArgList args, Cardinal *num_args) +{ + Boolean ret = TRUE; + Cardinal i; + + for (i = 0; i < *num_args; i++) { + if (strcmp(XtNfile, args[i].name) == 0) { + LoadFile(w); + ret = TRUE; + } + } + +/* + * Changing anthing else will have strange effects, I don't need it so + * I didn't code it. + */ + + return(ret); + +} /* Set Values */ + +/* + * A little design philosophy is probabally wise to include at this point. + * + * One of the things that I has hoped to achieve with xman is to make the + * viewing of manpage not only easy for the nieve user, but also fast for + * the experienced user, I wanted to be able to use it too. To achieve this + * I end up sacrificing a bit of start up time for the manual data structure. + * As well as, the overhead of reading the entire file before putting it up + * on the display. This is actually hardly even noticeable since most manual + * pages are shots, one to two pages - the notable exception is of course csh, + * but then that should be broken up anyway. + * + * METHOD: + * + * I allocate a chunk of space that is the size of the file, plus a null for + * debugging. Then copiesthe file into this chunk of memory. I then allocate + * an array of char*'s that are assigned to the beginning of each line. Yes, + * this means that I have to read the file twice, and could probabally be more + * clever about it, but once it is in memory the second read is damn fast. + * There are a few obsucrities here about guessing the number of lines and + * reallocing if I guess wrong, but other than that it is pretty straight + * forward. + * + * Chris Peterson + * 1/27/88 + */ + +#define ADD_MORE_MEM 100 /* first guesses for allocations. */ +#define CHAR_PER_LINE 40 + +/* Function Name: LoadFile + * Description: Loads the current file into the internal memory. + * Arguments: w - the sblw. + * Returns: none + */ + +static void +LoadFile(Widget w) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + FILE * file = sblw->scroll.file; + + char *page; + char **line_pointer,**top_line; /* pointers to beginnings of the + lines of the file. */ + int nlines; /* the current number of allocated lines. */ + struct stat fileinfo; /* file information from fstat. */ + + if ( sblw->scroll.top_line != NULL) { + XtFree(*(sblw->scroll.top_line)); /* free characters. */ + XtFree((char *)(sblw->scroll.top_line)); /* free lines. */ + } + sblw->scroll.top_line = NULL; + + if (file == NULL) + return; + +/* + * Get file size and allocate a chunk of memory for the file to be + * copied into. + */ + + if (fstat(fileno(file), &fileinfo)) + XtAppError(XtWidgetToApplicationContext(w), + "SBLW LoadFile: Failure in fstat."); + +/* + * Allocate a space for a list of pointer to the beginning of each line. + */ + + if ( (nlines = fileinfo.st_size/CHAR_PER_LINE) == 0) + return; + + page = XtMalloc(fileinfo.st_size + 1); /* leave space for the NULL */ + top_line = line_pointer = (char**) XtMalloc( nlines * sizeof(char *) ); + +/* + * Copy the file into memory. + */ + + fseek(file, 0L, SEEK_SET); + if (fread(page, sizeof(char), fileinfo.st_size, file) == 0) + XtAppError(XtWidgetToApplicationContext(w), + "SBLW LoadFile: Failure in fread."); + + +/* put NULL at end of buffer. */ + + *(page + fileinfo.st_size) = '\0'; + +/* + * Go through the file setting a line pointer to the character after each + * new line. If we run out of line pointer space then realloc that space + * with space for more lines. + */ + + *line_pointer++ = page; /* first line points to first char in buffer.*/ + while (*page != '\0') { + + if ( *page == '\n' ) { + *line_pointer++ = page + 1; + + if (line_pointer >= top_line + nlines) { + top_line = (char **) XtRealloc( (char *)top_line, (nlines + + ADD_MORE_MEM) * sizeof(char *) ); + line_pointer = top_line + nlines; + nlines += ADD_MORE_MEM; + } + } + page++; + } + +/* + * Realloc the line pointer space to take only the minimum amount of memory + */ + + sblw->scroll.lines = nlines = line_pointer - top_line - 1; + top_line = (char **) XtRealloc((char *)top_line, nlines * sizeof(char *)); + +/* + * Store the memory pointers + */ + + sblw->scroll.top_line = top_line; + sblw->scroll.line_pointer = 0; + SetThumbHeight(w); + SetThumb(w); +} + +#define NLINES 66 /* This is the number of lines to wait until + we boldify the line again, this allows + me to bold the first line of each page.*/ +#define BACKSPACE 010 /* I doubt you would want to change this. */ + +#define NORMAL 0 +#define BOLD 1 +#define ITALIC 2 +#define SYMBOL 3 +#define WHICH(italic, bold) ((bold) ? BOLD : ((italic) ? ITALIC : NORMAL)) + /* Choose BOLD over ITALICS. If neither */ + /* is chosen, use NORMAL. */ + +static int DumpText(Widget w, int x_loc, int y_loc, char * buf, int len, int format); +static Boolean Boldify(char *); + +/* Function Name: PrintText + * Description: This function actually prints the text. + * Arguments: w - the ScrollByLine widget. + * start_line - line to start printing, + * num_lines - the number of lines to print. + * location - the location to print the text. + * Returns: none. + */ + +/* ARGSUSED */ + +static void +PrintText(Widget w, int start_line, int num_lines, int location) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + + register char *bufp, *c; /* Generic char pointers */ + int current_line; /* the number of the currrent line */ + char buf[BUFSIZ]; /* Misc. characters */ + Boolean italicflag = FALSE; /* Print text in italics?? */ + Boolean first = TRUE; /* First line of a manual page??? */ + int x_loc, y_loc; /* x and y location of text. */ + +/* + * For table hack + * To get columns to line up reasonably in most cases, make the + * assumption that they were lined up using lots of spaces, where + * lots is greater than two. Use a space width of 70% of the + * widest character in the font. + */ + int h_col, h_fix; + char * h_c; + +/* + * Nothing loaded, take no action. + */ + + if (sblw->scroll.top_line == NULL || num_lines == 0) + return; + + current_line = start_line; + +/* Set the first character to print at the first line. */ + + c = *(sblw->scroll.top_line + start_line); + +/* + * Because XDrawString uses the bottom of the text as a position + * reference, add the height from the top of the font to the baseline + * to the ScollByLine position reference. + */ + + y_loc = location + sblw->scroll.normal_font->max_bounds.ascent; + +/* + * Ok, here's the more than mildly heuristic man page formatter. + * We put chars into buf until either a font change or newline + * occurs (at which time we flush it to the screen.) + */ + + + bufp = buf; + x_loc = sblw->scroll.offset + sblw->scroll.indent; + h_col = 0; + +/* + * A fix: + * Assume that we are always starting to print on or before the + * first line of a page, and then prove it if we aren't. + */ + for (h_fix = 1; h_fix <= (start_line % NLINES); h_fix++) + if (**(sblw->scroll.top_line + start_line - h_fix) != '\n') + { + first = FALSE; + break; + } + + while(TRUE) { + if (current_line % NLINES == 0) + first = TRUE; + +/* + * Lets make sure that we do not run out of space in our buffer, making full + * use of it is not critical since no window will be wide enough to display + * nearly BUFSIZ characters. + */ + + if ( (bufp - buf) > (BUFSIZ - 10) ) + /* Toss everything until we find a or the end of the buffer. */ + while ( (*c != '\n') && (*c != '\0') ) c++; + + switch(*c) { + + case '\0': /* If we reach the end of the file then return */ + DumpText(w, x_loc, y_loc, buf, bufp - buf, WHICH(italicflag, first)); + return; + + case '\n': + if (bufp != buf) { + Boolean bold; + *bufp = '\0'; /* for Boldify. */ + bold = ( (first) || ((x_loc == (sblw->scroll.offset + + sblw->scroll.indent)) && Boldify(buf)) ); + + (void) DumpText(w, x_loc, y_loc, buf, bufp - buf, + WHICH(italicflag, bold)); + + if (bold) + first = FALSE; + } + +/* + * If we have painted the required number of lines then we should now return. + */ + if (++current_line == start_line + num_lines ) + return; + + bufp = buf; + italicflag = FALSE; + x_loc = sblw->scroll.offset + sblw->scroll.indent; + h_col = 0; + y_loc += sblw->scroll.font_height; + break; + +/* + * This tab handling code is not very clever it moves the cursor over + * to the next boundry of eight (8) spaces, as calculated in width just + * before the printing loop started. + */ + + case '\t': /* TAB */ + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, + WHICH(italicflag, first)); + h_col += bufp - buf; + bufp = buf; + italicflag = FALSE; + x_loc = sblw->scroll.offset + sblw->scroll.indent; + h_col = h_col + 8 - (h_col%8); + x_loc += sblw->scroll.h_width * h_col; + break; + + case ' ': + h_c = c + 1; + while (*h_c == ' ') h_c++; + + if (h_c - c < 4) + { + *bufp++ = *c; + break; + } + + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, + WHICH(italicflag, first)); + h_col += bufp - buf; + bufp = buf; + italicflag = FALSE; + + x_loc = sblw->scroll.offset + sblw->scroll.indent; + h_col += (h_c - c); + x_loc += sblw->scroll.h_width * h_col; + c = h_c - 1; + break; + + case '\033': /* ignore esc sequences for now */ + c++; /* should always be esc-x */ + break; + +/* + * Overstrike code supplied by: cs.utexas.edu!ut-emx!clyde@rutgers.edu + * Since my manual pages do not have overstrike I couldn't test this. + */ + + case BACKSPACE: /* Backspacing for nroff bolding */ + if (c[-1] == c[1] && c[1] != BACKSPACE) { /* overstriking one char */ + if (bufp > buf) { + bufp--; /* Zap 1st instance of char to bolden */ + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, + WHICH(italicflag, FALSE)); + h_col += bufp - buf; + } + bufp = buf; + *bufp++ = c[1]; + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, BOLD); + h_col += bufp - buf; + bufp = buf; + first = FALSE; + + /* + * Nroff bolding looks like: + * C\bC\bC\bCN... + * c points to ----^ ^ + * it needs to point to --^ + */ + while (*c == BACKSPACE && c[-1] == c[1]) + c += 2; + c--; /* Back up to previous char */ + } + else { + if ((c[-1] == 'o' && c[1] == '+') /* Nroff bullet */ + || (c[-1] == '+' && c[1] == 'o')) { /* Nroff bullet */ + /* If we run into a bullet, print out */ + /* everything that's accumulated to this */ + /* point, then the bullet, then resume. */ + if (bufp>buf) { + bufp--; + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, + WHICH(italicflag, FALSE)); + h_col += bufp - buf; + } + bufp = buf; + *bufp = (char)183; + x_loc = DumpText(w, x_loc, y_loc, buf, 1, SYMBOL); + h_col++; + c++; + } + else { /* 'real' backspace - back up output ptr */ + if (bufp>buf) + bufp--; + } + } + break; + +/* End of contributed overstrike code. */ + + case '_': /* look for underlining [italicize] */ + if(*(c + 1) == BACKSPACE) { + if(!italicflag) { /* font change? */ + if (bufp != buf) { + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, NORMAL); + h_col += bufp - buf; + bufp = buf; + } + italicflag = TRUE; + } + c += 2; + *bufp++ = *c; + break; + } + /* else fall through to default, because this was a real underscore. */ + + default: + if(italicflag) { /* font change? */ + if (bufp != buf) { + x_loc = DumpText(w, x_loc, y_loc, buf, bufp - buf, + WHICH(italicflag, FALSE)); + h_col += bufp - buf; + bufp = buf; + } + italicflag = FALSE; + } + *bufp++ = *c; + break; + } + c++; + } +} + +/* Function Name: DumpText + * Description: Dumps text to the screen. + * Arguments: w - the widget. + * x_loc - to dump text at. + * y_loc - the y_location to draw_text. + * buf - buffer to dump. + * italic, bold, boolean that tells us which gc to use. + * Returns: x_location of the end of the text. + */ + +static int +DumpText(Widget w, int x_loc, int y_loc, char * buf, int len, int format) +{ + ScrollByLineWidget sblw = (ScrollByLineWidget) w; + GC gc; + XFontStruct * font; + + switch(format) { + + case ITALIC: + gc = sblw->scroll.italic_gc; + font = sblw->scroll.italic_font; + break; + + case BOLD: + gc = sblw->scroll.bold_gc; + font = sblw->scroll.bold_font; + break; + + case SYMBOL: + gc = sblw->scroll.symbol_gc; + font = sblw->scroll.symbol_font; + break; + + default: + gc = sblw->scroll.normal_gc; + font = sblw->scroll.normal_font; + break; + } + + XDrawString(XtDisplay(w), XtWindow(w), gc, x_loc, y_loc, buf, len); + return(x_loc + XTextWidth(font, buf, len)); +} + +/* Function Name: Boldify + * Description: look for keyword. + * Arguments: sp - string pointer. + * Returns: 1 if keyword else 0. + */ + +static Boolean +Boldify(register char *sp) +{ + register char *sp_pointer; + int length,count; + +/* + * If there are not lower case letters in the line the assume it is a + * keyword and boldify it in PrintManpage. + */ + + length = strlen(sp); + for (sp_pointer = sp, count = 0; count < length; sp_pointer++,count++) + if ( !isupper(*sp_pointer) && !isspace(*sp_pointer) ) + return(0); + return(1); +} + +#undef superclass +#undef SuperClass diff --git a/xman/ScrollByL.h b/xman/ScrollByL.h new file mode 100644 index 0000000..0283893 --- /dev/null +++ b/xman/ScrollByL.h @@ -0,0 +1,77 @@ +/* $XConsortium: ScrollByL.h,v 1.7 94/04/17 20:43:48 dave Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +#ifndef _XtScrollByLine_h +#define _XtScrollByLine_h + +/*********************************************************************** + * + * ScrollByLine Widget (subclass of Simple) + * + ***********************************************************************/ + +/* + * The default fonts. + */ + +#ifdef ATHENA +#define MANPAGE_NORMAL "fixed" +#define MANPAGE_BOLD "helvetica-bold12" +#define MANPAGE_ITALIC "helvetica-boldoblique12" +#define MANPAGE_SYMBOL "symbol-medium12" +#else +#define MANPAGE_NORMAL "*-new century schoolbook-medium-r-normal--*-120-*" +#define MANPAGE_BOLD "*-new century schoolbook-bold-r-normal--*-120-*" +#define MANPAGE_ITALIC "*-new century schoolbook-bold-i-normal--*-120-*" +#define MANPAGE_SYMBOL "*-symbol-medium-r-normal--*-120-*" +#endif /* ATHENA */ + +#define XtNindent "indent" +#define XtNforceVert "forceVert" +#define XtNmanualFontNormal "manualFontNormal" +#define XtNmanualFontBold "manualFontBold" +#define XtNmanualFontItalic "manualFontItalic" +#define XtNmanualFontSymbol "manualFontSymbol" +#define XtNNumTotalLines "numTotalLines" +#define XtNNumVisibleLines "numVisibleLines" + +#define XtCIndent "Indent" +#define XtCNumTotalLines "NumTotalLines" +#define XtCNumVisibleLines "NumVisibleLines" + +/* Class record constants */ + +extern WidgetClass scrollByLineWidgetClass; + +typedef struct _ScrollByLineClassRec *ScrollByLineWidgetClass; +typedef struct _ScrollByLineRec *ScrollByLineWidget; + +#endif /* _XtScrollByLine_h --- DON'T ADD STUFF AFTER THIS LINE */ diff --git a/xman/ScrollByLP.h b/xman/ScrollByLP.h new file mode 100644 index 0000000..25402d7 --- /dev/null +++ b/xman/ScrollByLP.h @@ -0,0 +1,100 @@ +/* $XConsortium: ScrollByLP.h,v 1.9 94/04/17 20:43:49 keith Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + + +#ifndef _XtScrollByLinePrivate_h +#define _XtScrollByLinePrivate_h + +#include + +#include "ScrollByL.h" + +/*********************************************************************** + * + * ScrollByLine Widget Private Data + * + ***********************************************************************/ + +/* New fields for the ScrollByLine widget class record */ +typedef struct { + int mumble; /* No new procedures */ +} ScrollByLineClassPart; + +/* Full class record declaration */ +typedef struct _ScrollByLineClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + ScrollByLineClassPart scrolled_widget_class; +} ScrollByLineClassRec; + +extern ScrollByLineClassRec scrollByLineClassRec; + +/* New fields for the ScrollByLine widget record */ +typedef struct _ScrollByLinePart { + Pixel foreground; /* The color for the forground of the text. */ + Boolean force_vert, /* Must have scrollbar visable */ + use_right; /* put scroll bar on right side of window. */ + FILE * file; /* The file to display. */ + Dimension indent; /* amount to indent the file. */ + XFontStruct * bold_font, /* The four fonts. */ + * normal_font, + * italic_font, + * symbol_font; + int h_width; /* Main font width */ + +/* variables not in resource list. */ + + Widget bar; /* The scrollbar. */ + int font_height; /* the height of the font. */ + int line_pointer; /* The line that currently is at the top + of the window being displayed. */ + Dimension offset; /* Drawing offset because of scrollbar. */ + GC move_gc; /* GC to use when moving the text. */ + GC bold_gc, normal_gc, italic_gc, symbol_gc; /* gc for drawing. */ + + char ** top_line; /* The top line of the file. */ + int lines; /* Total number of line in the file. */ + int num_visible_lines; /* Number of lines visible */ +} ScrollByLinePart; + +/**************************************************************** + * + * Full instance record declaration + * + ****************************************************************/ + +typedef struct _ScrollByLineRec { + CorePart core; + SimplePart simple; + ScrollByLinePart scroll; +} ScrollByLineRec; + +#endif /* _XtScrollByLinePrivate_h --- DON'T ADD STUFF AFTER THIS LINE */ diff --git a/xman/Xman-noxprint.ad b/xman/Xman-noxprint.ad new file mode 100644 index 0000000..3f08b02 --- /dev/null +++ b/xman/Xman-noxprint.ad @@ -0,0 +1,195 @@ +*input: True + +*topBox: True +*topBox.Title: Xman +*topBox.IconName: Xman + +*manualBrowser.Title: Manual Page +*manualBrowser.IconName: Manual Page +*manualBrowser.geometry: 600x600 + +*manualFontBold: -*-courier-bold-r-*-*-*-120-*-*-*-*-*-* +*manualFontItalic: -*-courier-medium-o-*-*-*-120-*-*-*-*-*-* +*manualFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*manualFontSymbol: -*-symbol-*-*-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*directoryFontNormal: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-lucida-bold-r-*-*-*-120-*-*-*-*-*-* + +!*SimpleMenu.BackingStore: Always +!*SimpleMenu.SaveUnder: Off + +*horizPane.orientation: horizontal +*horizPane*showGrip: False +*horizPane.min: 22 +*horizPane.max: 22 +*topLabel.BorderWidth: 0 +*search*label.BorderWidth: 0 + +*search*dialog*value: Xman + +!*optionMenu.Label: Options +!*sectionMenu.Label: Sections + +*horizPane*options.Label: Options +*horizPane*sections.Label: Sections + +*helpButton.Label: Help +*helpButton.Tip: Open help browser + +*quitButton.Label: Quit +*quitButton.Tip: Quit Xman + +*manpageButton.Label: Manual Page +*manpageButton.Tip: Open new manpage browser + +*topLabel.Label: Manual Browser + +!*SimpleMenu*menuLabel*vertSpace: 100 +!*SimpleMenu*menuLabel*leftMargin: 20 + +*displayDirectory.Label: Display Directory +*displayManualPage.Label: Display Manual Page +*help.Label: Help +*help.geometry: 600x600 +*search.Label: Search +*removeThisManpage.Label: Remove This Manpage +*help*removeThisManpage.Label: Remove Help +*openNewManpage.Label: Open New Manpage +*showVersion.Label: Show Version +*quit.Label: Quit + +*pleaseStandBy*Label: Formatting Manual Page, Please Stand By... + +*search*dialog.Label: Type string to search for: +*search*apropos.Label: Apropos +*search*manualPage.Label: Manual Page +*search*cancel.Label: Cancel + +*likeToSave*dialog.Label: Would you like to save this formatted Manual Page? +*likeToSave*yes.Label: Yes +*likeToSave*no.Label: No + +*translations: #override \ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrls: PopupSearch() + +*help*Paned.manualPage.translations:#override \ + Ctrl: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrlr: RemoveThisManpage() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrld: GotoPage(Directory) \n\ + Ctrlm: GotoPage(ManualPage) \n\ + Ctrlv: ShowVersion() \n\ + Prior: Page(Back) \n\ + Next : Page(Forward) \n\ + Shift,: Page(Line,-1) \n\ + Shift,: Page(Line,1) \n\ + Ctrl,: Page(Back) \n\ + Ctrl,: Page(Forward) \n\ + None,: Page(Line,-5) \n\ + None,: Page(Line,5) + +*manualBrowser*manualPage.translations: #override \ + Ctrl: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift,:GotoPage(Directory)\n\ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrlr: RemoveThisManpage() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrld: GotoPage(Directory) \n\ + Ctrlm: GotoPage(ManualPage) \n\ + Ctrlv: ShowVersion() \n\ + Prior: Page(Back) \n\ + Next : Page(Forward) \n\ + Shift,: Page(Line,-1) \n\ + Shift,: Page(Line,1) \n\ + Ctrl,: Page(Back) \n\ + Ctrl,: Page(Forward) \n\ + None,: Page(Line,-5) \n\ + None,: Page(Line,5) \n\ + Ctrls: PopupSearch() + +!*manualBrowser*directory.background: Grey80 +*manualBrowser*directory.translations: #override \ + Ctrl: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift,: GotoPage(Manpage) \n\ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrlr: RemoveThisManpage() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrld: GotoPage(Directory) \n\ + Ctrlm: GotoPage(ManualPage) \n\ + Ctrlv: ShowVersion() \n\ + Ctrls: PopupSearch() + +*manualBrowser*search*manualPage.translations: #augment \ + ,: Search(Manpage) reset() + +*manualBrowser*search*apropos.translations: #augment \ + ,: Search(Apropos) reset() + +*manualBrowser*search*cancel*translations: #augment \ + ,: Search(Cancel) reset() + +*manualBrowser*search*value*translations: #override \ + Return: Search(Manpage) \n\ + Ctrlm: Search(Manpage) + +*topBox*search*manualPage.translations: #augment \ + ,: Search(Manpage, Open) reset() + +*topBox*search*apropos.translations: #augment \ + ,: Search(Apropos, Open) reset() + +*topBox*search*cancel*translations: #augment \ + ,: Search(Cancel, Open) reset() + +*topBox*search*value*translations: #override \ + Return: Search(Manpage, Open) \n\ + Ctrlm: Search(Manpage, Open) + +*manualBrowser*likeToSave*yes.translations: #override \ + ,: SaveFormattedPage(Save) reset() \n\ + y: SaveFormattedPage(Save) \n\ + n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*no.translations: #override \ + ,: SaveFormattedPage(Cancel) reset() \n\ + y: SaveFormattedPage(Save) \n\ + n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*translations: #override \ + y: SaveFormattedPage(Save) \n\ + n: SaveFormattedPage(Cancel) + +*helpButton.translations: #augment \ + ,: PopupHelp() reset() + +*quitButton.translations: #augment \ + ,: Quit() reset() + +*manpageButton.translations: #augment \ + ,: CreateNewManpage() reset() + +! EOF. diff --git a/xman/Xman-xprint.ad b/xman/Xman-xprint.ad new file mode 100644 index 0000000..2598a98 --- /dev/null +++ b/xman/Xman-xprint.ad @@ -0,0 +1,294 @@ +*input: True + +*topBox: True +*topBox.Title: Xman +*topBox.IconName: Xman + +*manualBrowser.Title: Manual Page +*manualBrowser.IconName: Manual Page +*manualBrowser.geometry: 600x600 + +*manualFontBold: -*-courier-bold-r-*-*-*-120-*-*-*-*-*-* +*manualFontItalic: -*-courier-medium-o-*-*-*-120-*-*-*-*-*-* +*manualFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*manualFontSymbol: -*-symbol-*-*-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*directoryFontNormal: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-lucida-bold-r-*-*-*-120-*-*-*-*-*-* + +!*SimpleMenu.BackingStore: Always +!*SimpleMenu.SaveUnder: Off + +*horizPane.orientation: horizontal +*horizPane*showGrip: False +*horizPane.min: 22 +*horizPane.max: 22 +*topLabel.BorderWidth: 0 +*search*label.BorderWidth: 0 + +*search*dialog*value: Xman + +!*optionMenu.Label: Options +!*sectionMenu.Label: Sections + +*horizPane*options.Label: Options +*horizPane*sections.Label: Sections + +*helpButton.Label: Help +*helpButton.Tip: Open help browser + +*quitButton.Label: Quit +*quitButton.Tip: Quit Xman + +*manpageButton.Label: Manual Page +*manpageButton.Tip: Open new manpage browser + +*topLabel.Label: Manual Browser + +!*SimpleMenu*menuLabel*vertSpace: 100 +!*SimpleMenu*menuLabel*leftMargin: 20 + +*displayDirectory.Label: Display Directory +*displayManualPage.Label: Display Manual Page +*help.Label: Help +*help.geometry: 600x600 +*search.Label: Search +*removeThisManpage.Label: Remove This Manpage +*help*removeThisManpage.Label: Remove Help +*openNewManpage.Label: Open New Manpage +*printManualPage.Label: Print This Manpage +*showVersion.Label: Show Version +*quit.Label: Quit + +*pleaseStandBy*Label: Formatting Manual Page, Please Stand By... + +*search*dialog.Label: Type string to search for: +*search*apropos.Label: Apropos +*search*manualPage.Label: Manual Page +*search*cancel.Label: Cancel + +*likeToSave*dialog.Label: Would you like to save this formatted Manual Page? +*likeToSave*yes.Label: Yes +*likeToSave*no.Label: No + +*translations: #override \ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrls: PopupSearch() + +*help*Paned.manualPage.translations:#override \ + Ctrl: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrlr: RemoveThisManpage() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrld: GotoPage(Directory) \n\ + Ctrlm: GotoPage(ManualPage) \n\ + Ctrlp: PrintThisManpage() \n\ + Ctrlv: ShowVersion() \n\ + Prior: Page(Back) \n\ + Next : Page(Forward) \n\ + Shift,: Page(Line,-1) \n\ + Shift,: Page(Line,1) \n\ + Ctrl,: Page(Back) \n\ + Ctrl,: Page(Forward) \n\ + None,: Page(Line,-5) \n\ + None,: Page(Line,5) + +*manualBrowser*manualPage.translations: #override \ + Ctrl: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift,:GotoPage(Directory)\n\ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrlr: RemoveThisManpage() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrld: GotoPage(Directory) \n\ + Ctrlm: GotoPage(ManualPage) \n\ + Ctrlp: PrintThisManpage() \n\ + Ctrlv: ShowVersion() \n\ + Prior: Page(Back) \n\ + Next : Page(Forward) \n\ + Shift,: Page(Line,-1) \n\ + Shift,: Page(Line,1) \n\ + Ctrl,: Page(Back) \n\ + Ctrl,: Page(Forward) \n\ + None,: Page(Line,-5) \n\ + None,: Page(Line,5) \n\ + Ctrls: PopupSearch() + +!*manualBrowser*directory.background: Grey80 +*manualBrowser*directory.translations: #override \ + Ctrl: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift,: GotoPage(Manpage) \n\ + Ctrlq: Quit() \n\ + Ctrlc: Quit() \n\ + Ctrlr: RemoveThisManpage() \n\ + Ctrln: CreateNewManpage() \n\ + Ctrlh: PopupHelp() \n\ + Ctrld: GotoPage(Directory) \n\ + Ctrlm: GotoPage(ManualPage) \n\ + Ctrlv: ShowVersion() \n\ + Ctrls: PopupSearch() + +*manualBrowser*search*manualPage.translations: #augment \ + ,: Search(Manpage) reset() + +*manualBrowser*search*apropos.translations: #augment \ + ,: Search(Apropos) reset() + +*manualBrowser*search*cancel*translations: #augment \ + ,: Search(Cancel) reset() + +*manualBrowser*search*value*translations: #override \ + Return: Search(Manpage) \n\ + Ctrlm: Search(Manpage) + +*topBox*search*manualPage.translations: #augment \ + ,: Search(Manpage, Open) reset() + +*topBox*search*apropos.translations: #augment \ + ,: Search(Apropos, Open) reset() + +*topBox*search*cancel*translations: #augment \ + ,: Search(Cancel, Open) reset() + +*topBox*search*value*translations: #override \ + Return: Search(Manpage, Open) \n\ + Ctrlm: Search(Manpage, Open) + +*manualBrowser*likeToSave*yes.translations: #override \ + ,: SaveFormattedPage(Save) reset() \n\ + y: SaveFormattedPage(Save) \n\ + n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*no.translations: #override \ + ,: SaveFormattedPage(Cancel) reset() \n\ + y: SaveFormattedPage(Save) \n\ + n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*translations: #override \ + y: SaveFormattedPage(Save) \n\ + n: SaveFormattedPage(Cancel) + +*helpButton.translations: #augment \ + ,: PopupHelp() reset() + +*quitButton.translations: #augment \ + ,: Quit() reset() + +*manpageButton.translations: #augment \ + ,: CreateNewManpage() reset() + +! Use "white" as background for printing +*printshell*background: white + +! Print dialog +*printdialogshell*geometry: 600x120 +*printdialogshell*title: Print +*printdialogshell*main*ok.fromVert: innerform +*printdialogshell*main*ok.label: Print +*printdialogshell*main*ok.tip: Print +*printdialogshell*main*setup.fromHoriz: ok +*printdialogshell*main*setup.fromVert: innerform +*printdialogshell*main*setup.label: Setup... +*printdialogshell*main*setup.tip: Configure print job options (page size, orientation, etc.) +*printdialogshell*main*cancel.fromHoriz: setup +*printdialogshell*main*cancel.fromVert: innerform +*printdialogshell*main*cancel.label: Cancel +*printdialogshell*main*cancel.tip: Cancel printing +*printdialogshell*main*desclabel.label: Printer Description: +*printdialogshell*main*desclabel.tip: Short description of printer +*printdialogshell*main*desc.fromHoriz: desclabel +*printdialogshell*main*desc.tip: Short description of printer +*printdialogshell*main*info.fromHoriz: desc +*printdialogshell*main*info.label: Printer info... +*printdialogshell*main*info.tip: Display additional information about this printer +*printdialogshell*main*namelabel.fromVert: desclabel +*printdialogshell*main*namelabel.label: Printer Name: +*printdialogshell*main*namelabel.tip: Name of selected printer +*printdialogshell*main*name.fromHoriz: namelabel +*printdialogshell*main*name.fromVert: desclabel +*printdialogshell*main*name.tip: Name of selected printer +*printdialogshell*main*selectprinter.fromHoriz: name +*printdialogshell*main*selectprinter.fromVert: desclabel +*printdialogshell*main*selectprinter.label: Select Printer... +*printdialogshell*main*selectprinter.label: Select Printer... +*printdialogshell*main*selectprinter.tip: Select a different printer +*printdialogshell*main*filenamelabel.fromVert: namelabel +*printdialogshell*main*filenamelabel.label: File Name: +*printdialogshell*main*filenamelabel.tip: File where the output should be stored +*printdialogshell*main*filename.fromHoriz: filenamelabel +*printdialogshell*main*filename.fromVert: namelabel +*printdialogshell*main*filename.tip: File where the output should be stored +*printdialogshell*main*selectfile.fromHoriz: filename +*printdialogshell*main*selectfile.fromVert: namelabel +*printdialogshell*main*selectfile.label: Select File... +*printdialogshell*main*selectfile.tip: Select file where the output should be stored +*printdialogshell*main*printtoprinter.fromVert: filenamelabel +*printdialogshell*main*printtoprinter.label: Print to Printer +*printdialogshell*main*printtoprinter.tip: Send print job to printer +*printdialogshell*main*printtofile.fromVert: filenamelabel +*printdialogshell*main*printtofile.fromHoriz: printtoprinter +*printdialogshell*main*printtofile.label: Print to File +*printdialogshell*main*printtofile.tip: Save print job in a file + +! Print job options dialog +*printdialogshell*setup*geometry: 600x400 +*printdialogshell*setup*title: Print: Print job options +*printdialogshell*setup*ok.fromVert: list +*printdialogshell*setup*ok.label: OK +*printdialogshell*setup*ok.tip: Commit changes +*printdialogshell*setup*cancel.fromHoriz: ok +*printdialogshell*setup*cancel.fromVert: list +*printdialogshell*setup*cancel.label: Cancel +*printdialogshell*setup*cancel.tip: Cancel and reset to defaults +*printdialogshell*setup*paperlist.tip: Select paper size +*printdialogshell*setup*resolutionlist.fromHoriz: paperlist +*printdialogshell*setup*resolutionlist.tip: Select page resolution +*printdialogshell*setup*orientationlist.fromHoriz: resolutionlist +*printdialogshell*setup*orientationlist.tip: Select page orientation +*printdialogshell*setup*plexlist.fromHoriz: orientationlist +*printdialogshell*setup*plexlist.tip: Select page plex mode (simplex, duplex, etc.) +*printdialogshell*setup*colorspacelist.fromHoriz: plexlist +*printdialogshell*setup*colorspacelist.tip: Select color space (color, grayscale, CYMK, etc.) +*printdialogshell*setup*jobcopieslabel.fromVert: paperlist +*printdialogshell*setup*jobcopieslabel.tip: Set number of job copies +*printdialogshell*setup*jobcopieslabel.label: Job Copies: +*printdialogshell*setup*jobcopies.fromHoriz: jobcopieslabel +*printdialogshell*setup*jobcopies.fromVert: paperlist +*printdialogshell*setup*jobcopies.tip: Set number of job copies + +! Printer selection +*printdialogshell*printerselection*geometry: 400x150 +*printdialogshell*printerselection*title: Print: Select printer +*printdialogshell*printerselection*ok.fromVert: list +*printdialogshell*printerselection*ok.label: OK +*printdialogshell*printerselection*ok.tip: Switch printer +*printdialogshell*printerselection*cancel.fromHoriz: ok +*printdialogshell*printerselection*cancel.fromVert: list +*printdialogshell*printerselection*cancel.label: Cancel +*printdialogshell*printerselection*cancel.tip: Cancel printer selection +*printdialogshell*printerselection*list.tip: Select printer name from list + +! Select job file +*printdialogshell*selectfile*geometry: 400x80 +*printdialogshell*selectfile*title: Print: Select job file +*printdialogshell*selectfile*dialog.label: Select Filename: + +! EOF. diff --git a/xman/buttons.c b/xman/buttons.c new file mode 100644 index 0000000..13b1e70 --- /dev/null +++ b/xman/buttons.c @@ -0,0 +1,759 @@ +/* $XConsortium: buttons.c,v 1.33 94/04/17 20:43:50 dave Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xman/buttons.c,v 1.3 2000/03/03 23:16:26 dawes Exp $ */ + +/* + * xman - X window system manual page display program. + * Author: Chris D. Peterson, MIT Project Athena + * Created: October 27, 1987 + */ + +#include "globals.h" +#include "vendor.h" + +/* The files with the icon bits in them. */ + +#include "icon_open.h" +#include "icon_help.h" +#include "iconclosed.h" + +static void CreateOptionMenu(ManpageGlobals * man_globals, Widget parent); +static void CreateSectionMenu(ManpageGlobals * man_globals, Widget parent); +static void StartManpage(ManpageGlobals * man_globals, Boolean help, Boolean page); +static Widget * ConvertNamesToWidgets(Widget parent, char ** names); + +/* Function Name: MakeTopBox + * Description: This funtion creates the top menu, in a shell widget. + * Arguments: none. + * Returns: the top level widget + */ + +#define TOPARGS 5 + +extern Atom wm_delete_window; /* in main.c */ + +Widget top; /* needed in PopupWarning, misc.c */ + +void +MakeTopBox(void) +{ + Widget form, command, label; /* widgets. */ + Arg arglist[TOPARGS]; /* An argument list */ + Cardinal num_args = 0; /* The number of arguments. */ + ManpageGlobals * man_globals; + static char * full_size[] = { + "topLabel", MANPAGE_BUTTON, NULL + }; + static char * half_size[] = { + HELP_BUTTON, QUIT_BUTTON, NULL + }; + +/* create the top icon. */ + + num_args = 0; + XtSetArg(arglist[num_args], XtNiconPixmap, + XCreateBitmapFromData( XtDisplay(initial_widget), + XtScreen(initial_widget)->root, + (char *)iconclosed_bits, iconclosed_width, + iconclosed_height)); + num_args++; + XtSetArg(arglist[num_args], XtNtitle, resources.title); + num_args++; + XtSetArg(arglist[num_args], XtNiconic, resources.iconic); + num_args++; + top = XtCreatePopupShell(TOPBOXNAME, topLevelShellWidgetClass, + initial_widget, arglist, num_args); + + form = XtCreateManagedWidget("form", formWidgetClass, top, + NULL, (Cardinal) 0); + + label = XtCreateManagedWidget("topLabel", labelWidgetClass, form, + NULL, (Cardinal) 0); + + num_args = 0; + XtSetArg(arglist[num_args], XtNfromVert, label); num_args++; + command = XtCreateManagedWidget(HELP_BUTTON, commandWidgetClass, form, + arglist, num_args); + + /* use same vertical as help widget. */ + XtSetArg(arglist[num_args], XtNfromHoriz, command); num_args++; + command = XtCreateManagedWidget(QUIT_BUTTON, commandWidgetClass, form, + arglist, num_args); + + num_args = 0; + XtSetArg(arglist[num_args], XtNfromVert, command); num_args++; + command = XtCreateManagedWidget(MANPAGE_BUTTON, commandWidgetClass, form, + arglist, num_args); + + help_widget = NULL; /* We have not seen the help yet. */ + + FormUpWidgets(form, full_size, half_size); + + XtRealizeWidget(top); + /* add WM_COMMAND property */ + XSetCommand(XtDisplay(top), XtWindow(top), saved_argv, saved_argc); + + man_globals = (ManpageGlobals*) XtCalloc(ONE, (Cardinal) sizeof(ManpageGlobals)); + MakeSearchWidget(man_globals, top); + MakeSaveWidgets(man_globals, top); + + SaveGlobals( (man_globals->This_Manpage = top), man_globals); + XtMapWidget(top); + AddCursor(top, resources.cursors.top); + +/* + * Set up ICCCM delete window. + */ + XtOverrideTranslations + (top, XtParseTranslationTable ("WM_PROTOCOLS: Quit()")); + (void) XSetWMProtocols (XtDisplay(top), XtWindow(top), + &wm_delete_window, 1); + + +} + +/* Function Name: CreateManpage + * Description: Creates a new manpage. + * Arguments: none. + * Returns: none. + */ + +Widget +CreateManpage(FILE * file) +{ + ManpageGlobals * man_globals; /* The psuedo global structure. */ + + man_globals = InitPsuedoGlobals(); + CreateManpageWidget(man_globals, MANNAME, TRUE); + + if (file == NULL) + StartManpage( man_globals, OpenHelpfile(man_globals), FALSE ); + else { + OpenFile(man_globals, file); + StartManpage( man_globals, FALSE, TRUE); + } + return(man_globals->This_Manpage); +} + +/* Function Name: InitPsuedoGlobals + * Description: Initializes the psuedo global variables. + * Arguments: none. + * Returns: a pointer to a new pseudo globals structure. + */ + +ManpageGlobals * +InitPsuedoGlobals(void) +{ + ManpageGlobals * man_globals; + + /* + * Allocate necessary memory. + */ + + man_globals = (ManpageGlobals *)XtCalloc(ONE, (Cardinal) sizeof(ManpageGlobals)); + if(!man_globals) + return NULL; + + man_globals->search_widget = NULL; + man_globals->section_name = (char **) XtMalloc( (Cardinal) (sections * + sizeof(char *))); + man_globals->manpagewidgets.box = (Widget *) XtCalloc( (Cardinal) sections, + (Cardinal) sizeof(Widget)); + + /* Initialize the number of screens that will be shown */ + + man_globals->both_shown = resources.both_shown_initial; + + return(man_globals); +} + +/* Function Name: CreateManpageWidget + * Description: Creates a new manual page widget. + * Arguments: man_globals - a new man_globals structure. + * name - name of this shell widget instance. + * full_instance - if true then create a full manpage, + * otherwise create stripped down version + * used for help. + * Returns: none + */ + +#define MANPAGEARGS 10 + +void +CreateManpageWidget( +ManpageGlobals * man_globals, +char * name, +Boolean full_instance) +{ + Arg arglist[MANPAGEARGS]; /* An argument list for widget creation */ + Cardinal num_args; /* The number of arguments in the list. */ + Widget mytop, pane, hpane, mysections; /* Widgets */ + ManPageWidgets * mpw = &(man_globals->manpagewidgets); + + num_args = (Cardinal) 0; + XtSetArg(arglist[num_args], XtNwidth, default_width); + num_args++; + XtSetArg(arglist[num_args], XtNheight, default_height); + num_args++; + + mytop = XtCreatePopupShell(name, topLevelShellWidgetClass, initial_widget, + arglist, num_args); + + man_globals->This_Manpage = mytop; /* pointer to root widget of Manualpage. */ + num_args = 0; + if (full_instance) + XtSetArg(arglist[num_args], XtNiconPixmap, + XCreateBitmapFromData( XtDisplay(mytop), XtScreen(mytop)->root, + (char *)icon_open_bits, icon_open_width, + icon_open_height)); + else + XtSetArg(arglist[num_args], XtNiconPixmap, + XCreateBitmapFromData( XtDisplay(mytop), XtScreen(mytop)->root, + (char *)icon_help_bits, icon_help_width, + icon_help_height)); + num_args++; + XtSetValues(mytop, arglist, num_args); + + pane = XtCreateManagedWidget("vertPane", panedWidgetClass, mytop, NULL, + (Cardinal) 0); + +/* Create menu bar. */ + + hpane = XtCreateManagedWidget("horizPane", panedWidgetClass, + pane, NULL, (Cardinal) 0); + num_args = 0; + XtSetArg(arglist[num_args], XtNmenuName, OPTION_MENU); num_args++; + (void) XtCreateManagedWidget("options", menuButtonWidgetClass, + hpane, arglist, num_args); + + CreateOptionMenu(man_globals, mytop); + + num_args = 0; + XtSetArg(arglist[num_args], XtNmenuName, SECTION_MENU); num_args++; + mysections = XtCreateManagedWidget("sections", menuButtonWidgetClass, + hpane, arglist, num_args); + + XtSetArg(arglist[0], XtNlabel, SHOW_BOTH); + XtSetValues(man_globals->both_screens_entry, arglist, (Cardinal) 1); + + if (full_instance) { + MakeSearchWidget(man_globals, mytop); + CreateSectionMenu(man_globals, mytop); + MakeSaveWidgets(man_globals, mytop); + } else { + XtSetSensitive(mysections, FALSE); + XtSetArg(arglist[0], XtNsensitive, FALSE); + XtSetValues(man_globals->dir_entry, arglist, ONE); + XtSetValues(man_globals->manpage_entry, arglist, ONE); + XtSetValues(man_globals->help_entry, arglist, ONE); + XtSetValues(man_globals->search_entry, arglist, ONE); + XtSetValues(man_globals->both_screens_entry, arglist, ONE); + } + +#ifdef INCLUDE_XPRINT_SUPPORT + XtSetArg(arglist[0], XtNsensitive, True); + XtSetValues(man_globals->print_entry, arglist, ONE); +#endif /* INCLUDE_XPRINT_SUPPORT */ + + man_globals->label = XtCreateManagedWidget("manualTitle", labelWidgetClass, + hpane, NULL, (Cardinal) 0); + +/* Create Directory */ + + if (full_instance) { + num_args = 0; + XtSetArg(arglist[num_args], XtNallowVert, TRUE); + num_args++; + + mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass, + pane, arglist, num_args); + + man_globals->current_directory = INITIAL_DIR; + MakeDirectoryBox(man_globals, mpw->directory, + mpw->box + man_globals->current_directory, + man_globals->current_directory ); + XtManageChild(mpw->box[man_globals->current_directory]); + } + +/* Create Manpage */ + + mpw->manpage = XtCreateWidget(MANUALPAGE, scrollByLineWidgetClass, + pane, NULL, (Cardinal) 0); + +} + +/* Function Name: StartManpage + * Description: Starts up a new manpage. + * Arguments: man_globals - the psuedo globals variable. + * help - is this a help file? + * page - Is there a page to display? + * Returns: none. + */ + +static void +StartManpage(ManpageGlobals * man_globals, Boolean help, Boolean page) +{ + Widget dir = man_globals->manpagewidgets.directory; + Widget manpage = man_globals->manpagewidgets.manpage; + Widget label = man_globals->label; + Arg arglist[1]; + +/* + * If there is a helpfile then put up both screens if both_show is set. + */ + + if (page || help) { + if (help) + strcpy(man_globals->manpage_title, "Xman Help"); + + if (man_globals->both_shown) { + XtManageChild(dir); + man_globals->dir_shown = TRUE; + + XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height); + XtSetValues(dir, arglist, (Cardinal) 1); + + XtSetArg(arglist[0], XtNsensitive, FALSE); + XtSetValues(man_globals->manpage_entry, arglist, ONE); + XtSetValues(man_globals->dir_entry, arglist, ONE); + + XtSetArg(arglist[0], XtNlabel, SHOW_ONE); + XtSetValues(man_globals->both_screens_entry, arglist, ONE); + ChangeLabel(label, + man_globals->section_name[man_globals->current_directory]); + } + else { + ChangeLabel(label,man_globals->manpage_title); + } + XtManageChild(manpage); + man_globals->dir_shown = FALSE; + } +/* + * Since There is file to display, put up directory and do not allow change + * to manpage, show both, or help. + */ + else { + XtManageChild(dir); + man_globals->dir_shown = TRUE; + XtSetArg(arglist[0], XtNsensitive, FALSE); + XtSetValues(man_globals->manpage_entry, arglist, ONE); + XtSetValues(man_globals->help_entry, arglist, ONE); + XtSetValues(man_globals->both_screens_entry, arglist, ONE); + man_globals->both_shown = FALSE; + ChangeLabel(label, + man_globals->section_name[man_globals->current_directory]); + } + +/* + * Start 'er up, and change the cursor. + */ + + XtRealizeWidget( man_globals->This_Manpage ); + SaveGlobals( man_globals->This_Manpage, man_globals); + XtMapWidget( man_globals->This_Manpage ); + AddCursor( man_globals->This_Manpage, resources.cursors.manpage); + XtSetArg(arglist[0], XtNtransientFor, man_globals->This_Manpage); + XtSetValues(XtParent(man_globals->standby), arglist, (Cardinal)1); + XtSetValues(XtParent(man_globals->save), arglist, (Cardinal) 1); + XtRealizeWidget(XtParent(man_globals->standby)); + XtRealizeWidget(XtParent(man_globals->save)); + AddCursor( XtParent(man_globals->standby), resources.cursors.top); + AddCursor( XtParent(man_globals->save), resources.cursors.top); + +/* + * Set up ICCCM delete window. + */ + XtOverrideTranslations + (man_globals->This_Manpage, + XtParseTranslationTable ("WM_PROTOCOLS: RemoveThisManpage()")); + (void) XSetWMProtocols (XtDisplay(man_globals->This_Manpage), + XtWindow(man_globals->This_Manpage), + &wm_delete_window, 1); + +} + +/* Function Name: MenuDestroy + * Description: free's data associated with menu when it is destroyed. + * Arguments: w - menu widget. + * free_me - data to free. + * junk - not used. + * Returns: none. + */ + +/* ARGSUSED */ +static void +MenuDestroy(Widget w, XtPointer free_me, XtPointer junk) +{ + XtFree( (char *) free_me); +} + +/* Function Name: CreateOptionMenu + * Description: Create the option menu. + * Arguments: man_globals - the manual page globals. + * parent - the button that activates the menu. + * Returns: none. + */ + +static void +CreateOptionMenu(ManpageGlobals * man_globals, Widget parent) +{ + Widget menu, entry; + int i; + static char * option_names[] = { /* Names of the buttons. */ + DIRECTORY, + MANPAGE, + HELP, + SEARCH, + BOTH_SCREENS, + REMOVE_MANPAGE, + OPEN_MANPAGE, +#ifdef INCLUDE_XPRINT_SUPPORT + PRINT_MANPAGE, +#endif /* INCLUDE_XPRINT_SUPPORT */ + SHOW_VERSION, + QUIT + }; + + menu = XtCreatePopupShell(OPTION_MENU, simpleMenuWidgetClass, parent, + NULL, (Cardinal) 0); + man_globals->option_menu = menu; + + for (i = 0 ; i < NUM_OPTIONS ; i++) { + entry = XtCreateManagedWidget(option_names[i], smeBSBObjectClass, + menu, NULL, ZERO); + XtAddCallback(entry, XtNcallback, OptionCallback, (caddr_t) man_globals); + switch (i) { + case 0: + man_globals->dir_entry = entry; + break; + case 1: + man_globals->manpage_entry = entry; + break; + case 2: + man_globals->help_entry = entry; + break; + case 3: + man_globals->search_entry = entry; + break; + case 4: + man_globals->both_screens_entry = entry; + break; + case 5: + man_globals->remove_entry = entry; + break; + case 6: + man_globals->open_entry = entry; + break; +#ifdef INCLUDE_XPRINT_SUPPORT + case 7: + man_globals->print_entry = entry; + break; + case 8: + man_globals->version_entry = entry; + break; + case 9: + man_globals->quit_entry = entry; + break; +#else /* !INCLUDE_XPRINT_SUPPORT */ + case 7: + man_globals->version_entry = entry; + break; + case 8: + man_globals->quit_entry = entry; + break; +#endif /* !INCLUDE_XPRINT_SUPPORT */ + default: + Error(("CreateOptionMenu: Unknown id=%d\n", i)); + break; + } + } + +#ifdef INCLUDE_XPRINT_SUPPORT + XtVaSetValues(man_globals->print_entry, XtNsensitive, FALSE, NULL); +#endif /* INCLUDE_XPRINT_SUPPORT */ +} + +/* Function Name: CreateSectionMenu + * Description: Create the Section menu. + * Arguments: man_globals - the manual page globals. + * parent - the button that activates the menu. + * Returns: none. + */ + +static void +CreateSectionMenu(ManpageGlobals * man_globals, Widget parent) +{ + Widget menu, entry; + int i; + MenuStruct * menu_struct; + Arg args[1]; + Cardinal num_args; + char entry_name[BUFSIZ]; + + menu = XtCreatePopupShell(SECTION_MENU, simpleMenuWidgetClass, parent, + NULL, (Cardinal) 0); + + for (i = 0 ; i < sections ; i ++) { + num_args = 0; + XtSetArg(args[num_args], XtNlabel, manual[i].blabel); num_args++; + sprintf(entry_name, "section%d", i); + + entry = XtCreateManagedWidget(entry_name, smeBSBObjectClass, + menu, args, num_args); + menu_struct = (MenuStruct *) XtMalloc(sizeof(MenuStruct)); + menu_struct->data = (caddr_t) man_globals; + menu_struct->number = i; + XtAddCallback(entry, XtNcallback, DirPopupCallback, (caddr_t) menu_struct); + XtAddCallback(entry, XtNdestroyCallback,MenuDestroy, (caddr_t)menu_struct); + + } +} + +/* Function Name: CreateList + * Description: this function prints a label in the directory list + * Arguments: section - the manual section. + * Returns: none + */ + +static char ** +CreateList(int section) +{ + char ** ret_list, **current; + int count; + + ret_list = (char **) XtMalloc( (manual[section].nentries + 1) * + sizeof (char *)); + + for (current = ret_list, count = 0 ; count < manual[section].nentries ; + count++, current++) + *current = CreateManpageName(manual[section].entries[count], section, + manual[section].flags); + + *current = NULL; /* NULL terminate the list. */ + return(ret_list); +} + +/* Function Name: MakeDirectoryBox + * Description: make a directory box. + * Arguments: man_globals - the psuedo global structure for each manpage. + * parent - this guys parent widget. + * dir_disp - the directory display widget. + * section - the section number. + * Returns: none. + */ + +void +MakeDirectoryBox(ManpageGlobals *man_globals, Widget parent, Widget *dir_disp, int section) +{ + Arg arglist[10]; + Cardinal num_args; + char * name, label_name[BUFSIZ]; + + if (*dir_disp != NULL) /* If we have one, don't make another. */ + return; + + name = manual[section].blabel; /* Set the section name */ + sprintf(label_name,"Directory of: %s",name); + man_globals->section_name[section] = StrAlloc(label_name); + + num_args = 0; + XtSetArg(arglist[num_args], XtNlist, CreateList(section)); + num_args++; + XtSetArg(arglist[num_args], XtNfont, resources.fonts.directory); + num_args++; + + *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent, + arglist, num_args); + + XtAddCallback(*dir_disp, XtNcallback, + DirectoryHandler, (caddr_t) man_globals); +} + +/* Function Name: MakeSaveWidgets. + * Description: This functions creates two popup widgets, the please + * standby widget and the would you like to save widget. + * Arguments: man_globals - the psuedo globals structure for each man page + * parent - the realized parent for both popups. + * Returns: none. + */ + +void +MakeSaveWidgets(ManpageGlobals *man_globals, Widget parent) +{ + Widget shell, dialog; /* misc. widgets. */ + Arg warg[1]; + Cardinal n = 0; + +/* make the please stand by popup widget. */ + if (XtIsRealized(parent)) { + XtSetArg(warg[0], XtNtransientFor, parent); n++; + } + shell = XtCreatePopupShell( "pleaseStandBy", transientShellWidgetClass, + parent, warg, (Cardinal) n); + + man_globals->standby = XtCreateManagedWidget("label", labelWidgetClass, + shell, NULL, (Cardinal) 0); + + man_globals->save = XtCreatePopupShell("likeToSave", + transientShellWidgetClass, + parent, warg, n); + + dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, + man_globals->save, NULL, (Cardinal) 0); + + XawDialogAddButton(dialog, FILE_SAVE, NULL, NULL); + XawDialogAddButton(dialog, CANCEL_FILE_SAVE, NULL, NULL); + + if (XtIsRealized(parent)) { + XtRealizeWidget(shell); + AddCursor(shell,resources.cursors.top); + XtRealizeWidget(man_globals->save); + AddCursor(man_globals->save, resources.cursors.top); + } +} + +/* Function Name: FormUpWidgets + * Description: Sizes widgets to look nice. + * Arguments: parent - the common parent of all the widgets. + * full_size - array of widget names that will he full size. + * half_size - array of widget names that will he half size. + * Returns: none + */ + +void +FormUpWidgets(Widget parent, char ** full_size, char ** half_size) +{ + Widget * full_widgets, * half_widgets, *temp, long_widget; + Dimension longest, length, b_width; + int interior_dist; + Arg arglist[2]; + + full_widgets = ConvertNamesToWidgets(parent, full_size); + half_widgets = ConvertNamesToWidgets(parent, half_size); + + long_widget = NULL; + longest = 0; + XtSetArg(arglist[0], XtNwidth, &length); + XtSetArg(arglist[1], XtNborderWidth, &b_width); + +/* + * Find Longest widget. + */ + + for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++) { + XtGetValues(*temp, arglist, (Cardinal) 2); + length += 2 * b_width; + if (length > longest) { + longest = length; + long_widget = *temp; + } + } + + if (long_widget == (Widget) NULL) { /* Make sure we found one. */ + PopupWarning(GetGlobals(parent), + "Could not find longest widget, aborting..."); + XtFree((char *)full_widgets); + XtFree((char *)half_widgets); + return; + } + +/* + * Set all other full_widgets to this length. + */ + + for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++ ) + if ( long_widget != *temp) { + Dimension width, border_width; + + XtSetArg(arglist[0], XtNborderWidth, &border_width); + XtGetValues(*temp, arglist, (Cardinal) 1); + + width = longest - 2 * border_width; + XtSetArg(arglist[0], XtNwidth, width); + XtSetValues(*temp, arglist, (Cardinal) 1); + } + +/* + * Set all the half widgets to the right length. + */ + + XtSetArg(arglist[0], XtNdefaultDistance, &interior_dist); + XtGetValues(parent, arglist, (Cardinal) 1); + + for ( temp = half_widgets ; *temp != (Widget) NULL ; temp++) { + Dimension width, border_width; + + XtSetArg(arglist[0], XtNborderWidth, &border_width); + XtGetValues(*temp, arglist, (Cardinal) 1); + + width = (int)(longest - interior_dist)/2 - 2 * border_width; + XtSetArg(arglist[0], XtNwidth, width); + XtSetValues(*temp, arglist, (Cardinal) 1); + } + + XtFree((char *)full_widgets); + XtFree((char *)half_widgets); +} + +/* Function Name: ConvertNamesToWidgets + * Description: Convers a list of names into a list of widgets. + * Arguments: parent - the common parent of these widgets. + * names - an array of widget names. + * Returns: an array of widget id's. + */ + +static Widget * +ConvertNamesToWidgets(Widget parent, char ** names) +{ + char ** temp; + Widget * ids, * temp_ids; + int count; + + for (count = 0, temp = names; *temp != NULL ; count++, temp++); + + ids = (Widget *) XtMalloc( (count + 1) * sizeof(Widget)); + + + for ( temp_ids = ids; *names != NULL ; names++, temp_ids++) { + *temp_ids = XtNameToWidget(parent, *names); + if (*temp_ids == NULL) { + char error_buf[BUFSIZ]; + + sprintf(error_buf, "Could not find widget named '%s'", *names); + PrintError(error_buf); + XtFree((char *)ids); + return(NULL); + } + } + + *temp_ids = (Widget) NULL; + return(ids); +} diff --git a/xman/config.h.in b/xman/config.h.in new file mode 100644 index 0000000..87ff05c --- /dev/null +++ b/xman/config.h.in @@ -0,0 +1,46 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAS_MKSTEMP + +/* Default local man page search path (default: none) */ +#undef LOCALMANPATH + +/* Define to path to man config file if you have one */ +#undef MANCONF + +/* Define to 1 if you have BSD format manpath.config */ +#undef MANCONFIGSTYLE_BSD + +/* Define to 1 if you have FreeBSD format manpath.config */ +#undef MANCONFIGSTYLE_FreeBSD + +/* Define to 1 if you have Linux format man.conf or man.config */ +#undef MANCONFIGSTYLE_Linux + +/* Define to 1 if you have OpenBSD format manpath.config */ +#undef MANCONFIGSTYLE_OpenBSD + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Default system man page search path (default: none) */ +#undef SYSMANPATH + +/* Version number of package */ +#undef VERSION diff --git a/xman/defs.h b/xman/defs.h new file mode 100644 index 0000000..ec4d068 --- /dev/null +++ b/xman/defs.h @@ -0,0 +1,146 @@ +/* $XConsortium: defs.h,v 1.25 94/04/17 20:43:50 converse Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xman/defs.h,v 1.2 2000/03/03 23:16:26 dawes Exp $ */ + +/* + * xman - X window system manual page display program. + * Author: Chris D. Peterson, MIT Project Athena + * Created: October 22, 1987 + */ + +#ifndef HELPFILE +#define HELPFILE "/usr/lib/X11/xman.help" /* name of the default helpfile. */ +#endif + +/* The default cursors */ + +#define XMAN_CURSOR "left_ptr" /* Top level cursor. */ +#define HELP_CURSOR "left_ptr" /* The help cursor. */ +#define MANPAGE_CURSOR "left_ptr" /* The manpage cursor. */ +#define SEARCH_ENTRY_CURSOR "question_arrow" /* The search text widget + cursor. */ +#define DIRECTORY_NORMAL "fixed" /* The default dir font */ + +#define OPTION_MENU "optionMenu" /* Name of the Option Menu. */ +#define SECTION_MENU "sectionMenu" /* Name of the Section Menu. */ + +#define HELP_BUTTON "helpButton" /* Name of top help button */ +#define QUIT_BUTTON "quitButton" /* Name of top quit button */ +#define MANPAGE_BUTTON "manpageButton" /* Name of top manpage button */ + +#define TOPBOXNAME "topBox" /* Name of the Top Box. */ +#define MANNAME "manualBrowser" /* name for each manual page widget. */ +#define SEARCHNAME "search" /* The name for the search widget. */ +#define HELPNAME "help" /* The name of the help widget. */ +#define DIRECTORY_NAME "directory" /* name of the directory widget. */ +#define MANUALPAGE "manualPage" /* name of the Scrollbyline widget that + contains the man page. */ +#define DIALOG "dialog" + +/* Names of the menu buttons */ + +#ifdef INCLUDE_XPRINT_SUPPORT +#define NUM_OPTIONS 10 /* Number of menu options. */ +#else /* !INCLUDE_XPRINT_SUPPORT */ +#define NUM_OPTIONS 9 /* Number of menu options. */ +#endif /* !INCLUDE_XPRINT_SUPPORT */ + +#define DIRECTORY "displayDirectory" +#define MANPAGE "displayManualPage" +#define HELP "help" +#define SEARCH "search" +#define BOTH_SCREENS "showBothScreens" +#define REMOVE_MANPAGE "removeThisManpage" +#define OPEN_MANPAGE "openNewManpage" +#ifdef INCLUDE_XPRINT_SUPPORT +#define PRINT_MANPAGE "printManualPage" +#endif /* INCLUDE_XPRINT_SUPPORT */ +#define SHOW_VERSION "showVersion" +#define QUIT "quit" + +/* definitions of string to use for show both and show one. */ + +#define SHOW_BOTH "Show Both Screens" +#define SHOW_ONE "Show One Screen" + +/* + * Things will not look right if you change these names to make + * MANUALSEARCH longer APROPOSSEARCH, see search.c for details. + */ + +#define MANUALSEARCH "manualPage" +#define APROPOSSEARCH "apropos" +#define CANCEL "cancel" + +#define MANUAL 0 +#define APROPOS 1 + +#define NO_SECTION_DEFAULTS ("no default sections") + +/* + * Define HANDLE_ROFFSEQ to enable parsing of '\" + * sequences in source files to set the format pipeline. + * This is necessary because the default pipeline causes incorrect + * display of ascii(7) on Linux. + * This depends on GNU roff. + */ +#ifdef HAS_GROFF +#define HANDLE_ROFFSEQ +#endif + +#define DEFAULT_WIDTH 500 /* The default width of xman. */ +#define SECTALLOC 8 /* The number of entries allocated + at a time for the manual structures. */ +#define ENTRYALLOC 100 /* The number of entries allocated + at a time for a section. */ + +#define INITIAL_DIR 0 /* The Initial Directory displayed. */ + +#define COPY "cp" /* copy command */ +#define CHMOD_MODE 00666 /* permissions set on saved formatted files */ +#define MANDESC "mandesc" /* name of the mandesc files */ + +#define INDENT 15 +#define TYP20STR "MMMMMMMMMMMMMMMMMMMM" + +#define FILE_SAVE "yes" +#define CANCEL_FILE_SAVE "no" +#define MANTEMP "/tmp/xmanXXXXXX" + +/* + * Macro Definitions. + */ + +#define streq(a, b) ( strcmp((a), (b)) == 0 ) + +/* + * Function definitions moved to man.h + */ diff --git a/xman/globals.c b/xman/globals.c new file mode 100644 index 0000000..e880953 --- /dev/null +++ b/xman/globals.c @@ -0,0 +1,54 @@ +/* $XConsortium: globals.c,v 1.9 94/04/17 20:43:51 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + + +#include "man.h" + +Xman_Resources resources; /* Resource manager sets these. */ + +/* bookkeeping global variables. */ + +Widget help_widget; /* The help widget. */ + +int default_height,default_width; /* Approximately the default with and + height, of the manpage when shown, + the the top level manual page + window */ + +Manual * manual; /* The manual structure. */ +int sections; /* The number of manual sections. */ + +int man_pages_shown; /* The current number of manual + pages being shown, if 0 we exit. */ + +Widget initial_widget; /* The initial widget, never realized. */ + +XContext manglobals_context; /* The context for man_globals. */ diff --git a/xman/globals.h b/xman/globals.h new file mode 100644 index 0000000..d629f51 --- /dev/null +++ b/xman/globals.h @@ -0,0 +1,56 @@ +/* $XConsortium: globals.h,v 1.9 94/04/17 20:43:51 dave Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86$ */ + +#include "man.h" + +extern Xman_Resources resources; /* Resource manager sets these. */ + +/* bookkeeping global variables. */ + +extern Widget help_widget; /* The help widget. */ + +extern int default_height,default_width; /* Approximately the default with and + height, of the manpage when shown, + the the top level manual page + window */ +extern int man_pages_shown; /* The current number of manual + pages being shown, if 0 we exit. */ + +extern Manual * manual; /* The manual structure. */ +extern int sections; /* The number of manual sections. */ + +extern XContext manglobals_context; /* The context for man_globals. */ + +extern Widget initial_widget; /* The initial widget, never realized. */ + +extern char **saved_argv; +extern int saved_argc; diff --git a/xman/handler.c b/xman/handler.c new file mode 100644 index 0000000..f89cdd6 --- /dev/null +++ b/xman/handler.c @@ -0,0 +1,724 @@ +/* $XConsortium: handler.c,v 1.22 94/12/16 21:36:53 gildea Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xman/handler.c,v 1.6 2003/01/19 04:44:45 paulo Exp $ */ + +/* + * xman - X window system manual page display program. + * Author: Chris D. Peterson, MIT Project Athena + * Created: October 29, 1987 + */ + +#include +#include +#include "globals.h" +#include "vendor.h" +#ifdef INCLUDE_XPRINT_SUPPORT +#include "printdialog.h" +#include "print.h" +#endif /* INCLUDE_XPRINT_SUPPORT */ + +static void PutUpManpage(ManpageGlobals * man_globals, FILE * file); +static void ToggleBothShownState(ManpageGlobals * man_globals); + +/* Function Name: OptionCallback + * Description: This is the callback function for the callback menu. + * Arguments: w - the widget we are calling back from. + * globals_pointer - a pointer to the psuedo globals structure + * for this manpage. + * junk - (call data) not used. + * Returns: none. + */ + +/*ARGSUSED*/ +void +OptionCallback(Widget w, XtPointer pointer, XtPointer junk) +{ + ManpageGlobals * man_globals = (ManpageGlobals *) pointer; + String params; + Cardinal num_params = 1; + + if ( w == man_globals->search_entry ) + PopupSearch(XtParent(w), NULL, NULL, NULL); + else if (w == man_globals->dir_entry) { /* Put Up Directory */ + params = "Directory"; + GotoPage(XtParent(w), NULL, ¶ms, &num_params); + } + else if (w == man_globals->manpage_entry ) { /* Put Up Man Page */ + params = "ManualPage"; + GotoPage(XtParent(w), NULL, ¶ms, &num_params); + } + else if ( w == man_globals->help_entry ) /* Help */ + PopupHelp(XtParent(w), NULL, NULL, NULL); + else if ( w == man_globals->both_screens_entry ) /*Toggle Both_Shown State.*/ + ToggleBothShownState(man_globals); + else if ( w == man_globals->remove_entry) /* Kill the manpage */ + RemoveThisManpage(XtParent(w), NULL, NULL, NULL); + else if ( w == man_globals->open_entry) /* Open new manpage */ + CreateNewManpage(XtParent(w), NULL, NULL, NULL); +#ifdef INCLUDE_XPRINT_SUPPORT + else if ( w == man_globals->print_entry) /* Print current manpage */ + PrintThisManpage(XtParent(w), NULL, NULL, NULL); +#endif /* INCLUDE_XPRINT_SUPPORT */ + else if ( w == man_globals->version_entry) /* Get version */ + ShowVersion(XtParent(w), NULL, NULL, NULL); + else if ( w == man_globals->quit_entry) /* Quit. */ + Quit(XtParent(w), NULL, NULL, NULL); +} + +/* Function Name: ToggleBothShownState; + * Description: toggles the state of the both shown feature. + * Arguments: man_globals - the man globals structure. + * Returns: none. + */ + +/* + * I did not have a two state widget, which is the way this + * should really be done. 1/22/88 - CDP. + */ + +static void +ToggleBothShownState(ManpageGlobals * man_globals) +{ + char * label_str; + Arg arglist[1]; + + if (man_globals->both_shown == TRUE) { + label_str = SHOW_BOTH; + if (man_globals->dir_shown) + XtUnmanageChild(man_globals->manpagewidgets.manpage); + else + XtUnmanageChild(man_globals->manpagewidgets.directory); + } + else { + Widget manpage = man_globals->manpagewidgets.manpage; + Widget dir = man_globals->manpagewidgets.directory; + + label_str = SHOW_ONE; + + XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height); + XtSetValues(dir, arglist, (Cardinal) 1); + + if (!man_globals->dir_shown) { + XtUnmanageChild(manpage); + XtManageChild(dir); + } + XtManageChild(manpage); + } + man_globals->both_shown = !man_globals->both_shown; + + if (man_globals->dir_shown) + ChangeLabel(man_globals->label, + man_globals->section_name[man_globals->current_directory]); + else + ChangeLabel(man_globals->label, man_globals->manpage_title); + + XtSetArg(arglist[0], XtNlabel, label_str); + XtSetValues(man_globals->both_screens_entry, arglist, ONE); + + /* if both are shown there is no need to switch between the two. */ + + XtSetArg(arglist[0], XtNsensitive, !man_globals->both_shown); + XtSetValues(man_globals->manpage_entry, arglist, ONE); + XtSetValues(man_globals->dir_entry, arglist, ONE); +} + +/* Function Name: Popup + * Description: This function pops up the given widget under the cursor. + * Arguments: w - the widget to popup. + * grab_kind - the kind of grab to register. + * Returns: none + */ + +/* How far off the top of the widget to have the initial cursor postion. */ + +#define OFF_OF_TOP 25 + +void +Popup(Widget w, XtGrabKind grab_kind) +{ + int x_root,y_root,y_pos,garbage; + unsigned int mask; + Window junk_window; + + XQueryPointer(XtDisplay(w), XtWindow(w), &junk_window, &junk_window, + &x_root, &y_root, &garbage, &garbage, &mask); + + y_pos = OFF_OF_TOP - Height(w)/2 - BorderWidth(w); + PositionCenter(w, x_root, y_root, y_pos, 0, 2, 2); + XtPopup(w, grab_kind); +} + +/* Function Name: PutUpManpage + * Description: Puts the manpage on the display. + * Arguments: man_globals - a pointer to the psuedo globals structure + * for this manpage. + * file - the file to display. + * Returns: none. + */ + +static void +PutUpManpage(ManpageGlobals * man_globals, FILE * file) +{ + String params = "ManualPage"; + Cardinal num_params = 1; + + if (file == NULL) + return; + + OpenFile(man_globals, file); + + if (!man_globals->both_shown) { + Arg arglist[1]; + XtSetArg(arglist[0], XtNsensitive, TRUE); + XtSetValues(man_globals->manpage_entry, arglist, ONE); + XtSetValues(man_globals->both_screens_entry, arglist, ONE); + } + GotoPage(man_globals->manpagewidgets.manpage, NULL, ¶ms, &num_params); +} + +/* Function Name: DirectoryHandler + * Description: This is the callback function for the directory listings. + * Arguments: w - the widget we are calling back from. + * global_pointer - the pointer to the psuedo global structure + * associated with this manpage. + * ret_val - return value from the list widget. + * Returns: none. + */ + +void +DirectoryHandler(Widget w, XtPointer global_pointer, XtPointer ret_val) +{ + FILE * file; /* The manpage file. */ + ManpageGlobals * man_globals = (ManpageGlobals *) global_pointer; + XawListReturnStruct * ret_struct = (XawListReturnStruct *) ret_val; + + file = FindManualFile(man_globals, man_globals->current_directory, + ret_struct->list_index); + PutUpManpage(man_globals, file); + if ((file != NULL) && (file != man_globals->curr_file)) { + fclose(file); + } +} + +/* Function Name: DirPopupCallback + * Description: This is the callback function for the callback menu. + * Arguments: w - the widget we are calling back from. + * pointer - a pointer to the psuedo globals structure + * for this manpage. + * junk - (call data) not used. + * Returns: none. + */ + +/*ARGSUSED*/ +void +DirPopupCallback(Widget w, XtPointer pointer, XtPointer junk) +{ + ManpageGlobals * man_globals; + MenuStruct * menu_struct; + Widget parent; + int number; + int current_box; + + menu_struct = (MenuStruct *) pointer; + man_globals = (ManpageGlobals *) menu_struct->data; + + number = menu_struct->number; + current_box = man_globals->current_directory; + + /* We have used this guy, pop down the menu. */ + + if (number != current_box) { + /* This is the only one that we know has a parent. */ + parent = XtParent(man_globals->manpagewidgets.box[INITIAL_DIR]); + + MakeDirectoryBox(man_globals, parent, + man_globals->manpagewidgets.box + number, number); + XtUnmanageChild(man_globals->manpagewidgets.box[current_box]); + XtManageChild(man_globals->manpagewidgets.box[number]); + + XawListUnhighlight(man_globals->manpagewidgets.box[current_box]); + ChangeLabel(man_globals->label, man_globals->section_name[number]); + man_globals->current_directory = number; + } + + /* put up directory. */ + if (!man_globals->both_shown) { + XtUnmanageChild(man_globals->manpagewidgets.manpage); + XtManageChild(man_globals->manpagewidgets.directory); + } +} + +/************************************************************ + * + * Action Routines. + * + ************************************************************/ + +/* Function Name: SaveFormattedPage + * Description: This is the action routine may save the manpage. + * Arguments: w - any widget in the widget tree. + * event - NOT USED. + * params, num_params - the parameters paseed to the action + * routine, can be either Manpage or + * Directory. + * Returns: none. + */ + +/*ARGSUSED*/ +void +SaveFormattedPage(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals * man_globals; + char cmdbuf[BUFSIZ], error_buf[BUFSIZ]; + + if (*num_params != 1) { + XtAppWarning(XtWidgetToApplicationContext(w), + "Xman - SaveFormattedPage: This action routine requires one argument."); + return; + } + + man_globals = GetGlobals(w); + +/* + * If we are not active then take no action. + */ + + if (man_globals->tempfile == '\0') return; + + switch (params[0][0]) { + case 'S': + case 's': + +#ifndef NO_COMPRESS + if (!man_globals->compress) +#endif + + sprintf(cmdbuf, "%s %s %s", COPY, man_globals->tempfile, + man_globals->save_file); + +#ifndef NO_COMPRESS + else + if (man_globals->gzip) + sprintf(cmdbuf, "%s < %s > %s", GZIP_COMPRESS, man_globals->tempfile, + man_globals->save_file); + else + sprintf(cmdbuf, "%s < %s > %s", COMPRESS, man_globals->tempfile, + man_globals->save_file); +#endif + + if(! system(cmdbuf)) { + /* make sure the formatted man page is fully accessible by the world */ + if (chmod(man_globals->save_file, CHMOD_MODE) != 0) { + sprintf(error_buf, + "Couldn't set permissions on formatted man page '%s'.\n", + man_globals->save_file); + PopupWarning( man_globals, error_buf); + } + } else { + sprintf(error_buf, "Error while executing the command '%s'.\n", + cmdbuf); + PopupWarning( man_globals, error_buf); + } + break; + case 'C': + case 'c': + break; + default: + sprintf(error_buf,"%s %s", "Xman - SaveFormattedPagee:", + "Unknown argument must be either 'Save' or 'Cancel'."); + PopupWarning(man_globals, error_buf); + return; + } + +/* + * We do not need the filename anymore, and have the fd open. + * We will unlink it. + */ + + unlink(man_globals->tempfile); + XtPopdown( XtParent(XtParent(w)) ); +} + +/* Function Name: GotoPage + * Description: The Action routine that switches over to the manpage + * or directory. + * Arguments: w - any widget in the widget tree. + * event - NOT USED. + * params, num_params - the parameters paseed to the action + * routine, can be either Manpage or + * Directory. + * Returns: none. + */ + +/*ARGSUSED*/ +void +GotoPage(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals * man_globals; + char error_buf[BUFSIZ]; + Arg arglist[1]; + Boolean sensitive; + + if (*num_params != 1) { + XtAppWarning(XtWidgetToApplicationContext(w), + "Xman - GotoPage: This action routine requires one argument."); + return; + } + + man_globals = GetGlobals(w); + + if (man_globals->both_shown) { + ChangeLabel(man_globals->label, + man_globals->section_name[man_globals->current_directory]); + return; + } + + switch (params[0][0]) { + case 'M': + case 'm': + XtSetArg(arglist[0], XtNsensitive, &sensitive); + XtGetValues(man_globals->manpage_entry, arglist, ONE); + if (sensitive) { + ChangeLabel(man_globals->label,man_globals->manpage_title); + XtUnmanageChild(man_globals->manpagewidgets.directory); + XtManageChild(man_globals->manpagewidgets.manpage); + man_globals->dir_shown = FALSE; + } + break; + case 'D': + case 'd': + ChangeLabel(man_globals->label, + man_globals->section_name[man_globals->current_directory]); + XtUnmanageChild(man_globals->manpagewidgets.manpage); + XtManageChild(man_globals->manpagewidgets.directory); + man_globals->dir_shown = TRUE; + break; + default: + sprintf(error_buf,"%s %s", "Xman - GotoPage: Unknown argument must be", + "either Manpage or Directory."); + XtAppWarning(XtWidgetToApplicationContext(w), error_buf); + return; + } +} + +/* Function Name: Quit. + * Description: Quits Xman. + * Arguments: w - any widget. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +Quit(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + XtAppSetExitFlag(XtWidgetToApplicationContext(w)); +} + +/* Function Name: PopupHelp + * Description: Pops up xman's help. + * Arguments: w - NOT USED. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +PopupHelp(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + if (MakeHelpWidget()) + XtPopup(help_widget,XtGrabNone); +} + +/* Function Name: PopupSearch + * Description: Pops up this manual pages search widget. + * Arguments: w - any widget in this manpage. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +PopupSearch(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals * man_globals = GetGlobals(w); + + if (man_globals->search_widget) { + if (!XtIsRealized(man_globals->search_widget)) { + XtRealizeWidget(man_globals->search_widget); + AddCursor(man_globals->search_widget, resources.cursors.search_entry); + } + Popup(man_globals->search_widget, XtGrabNone); + } +} + +/* Function Name: CreateNewManpage + * Description: Creates A New Manual Page. + * Arguments: w - NOT USED. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +CreateNewManpage(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + (void) CreateManpage(NULL); + man_pages_shown++; +} + +/* Function Name: RemoveThisManpage + * Description: Removes a manual page. + * Arguments: w - any widget in the manpage. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +RemoveThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals * man_globals = GetGlobals(w); + + if (man_globals->This_Manpage != help_widget) { + RemoveGlobals(man_globals->This_Manpage); + XtDestroyWidget(man_globals->This_Manpage); + + XtFree( (char *) man_globals->section_name); + XtFree( (char *) man_globals->manpagewidgets.box); + XtFree( (char *) man_globals); + + if ( (--man_pages_shown) == 0) + Quit(w, NULL, NULL, NULL); + } + else + XtPopdown(help_widget); +} + +/* Function Name: Search + * Description: Actually performs a search. + * Arguments: w - any widget in the manpage. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +Search(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals * man_globals = GetGlobals(w); + FILE * file = NULL; + + XtPopdown( XtParent(XtParent(w)) ); /* popdown the search widget */ + + if ( (*num_params < 1) || (*num_params > 2) ) { + XtAppWarning(XtWidgetToApplicationContext(w), + "Xman - Search: This action routine requires one or two arguments."); + return; + } + + switch(params[0][0]) { + case 'a': + case 'A': + file = DoSearch(man_globals,APROPOS); + break; + case 'm': + case 'M': + file = DoSearch(man_globals,MANUAL); + break; + case 'c': + case 'C': + file = NULL; + break; + default: + XtAppWarning(XtWidgetToApplicationContext(w), + "Xman - Search: First parameter unknown."); + file = NULL; + break; + } + + if ( *num_params == 2 ) + switch (params[1][0]) { + case 'O': + case 'o': + if (file != NULL) { + Widget w; + char * label; + + w = CreateManpage(file); + man_pages_shown++; + + /* Put title into new manual page. */ + + label = man_globals->manpage_title; + man_globals = GetGlobals(w); + strcpy(man_globals->manpage_title, label); + ChangeLabel(man_globals->label, label); + } + break; + default: + XtAppWarning(XtWidgetToApplicationContext(w), + "Xman - Search: Second parameter unknown."); + break; + } + else { + PutUpManpage(man_globals, file); + } + if ((file != NULL) && (file != man_globals->curr_file)) { + fclose(file); + } +} + +#ifdef INCLUDE_XPRINT_SUPPORT +static void +printshellDestroyXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + ManpageGlobals *mg = GetGlobals(w); + XawPrintDialogClosePrinterConnection(mg->printdialog, False); +} + +static void +printOKXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + XawPrintDialogCallbackStruct *pdcs = (XawPrintDialogCallbackStruct *)callData; + Cardinal n; + Arg args[2]; + ManpageGlobals *mg = GetGlobals(w); + Widget topwindow = mg->This_Manpage; + FILE *file; + + Log(("printOKXtProc: OK.\n")); + + /* Get file object */ + n = 0; + XtSetArg(args[n], XtNfile, &file); n++; + XtGetValues(mg->manpagewidgets.manpage, args, n); + Assertion(file != NULL, (("printOKXtProc: file == NULL.\n"))); + + DoPrintManpage("Xman", + file, topwindow, + pdcs->pdpy, pdcs->pcontext, pdcs->colorspace, + printshellDestroyXtProc, + mg->manpage_title, + pdcs->printToFile?pdcs->printToFileName:NULL); + + XtPopdown(mg->printdialog_shell); +} + +static void +printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + ManpageGlobals * mg = GetGlobals(w); + + Log(("printCancelXtProc: cancel.\n")); + XtPopdown(mg->printdialog_shell); + + Log(("destroying print dialog shell...\n")); + XtDestroyWidget(mg->printdialog_shell); + mg->printdialog_shell = NULL; + mg->printdialog = NULL; + Log(("... done\n")); +} + +/* Function Name: PrintThisManpage + * Description: Print the current manual page. + * Arguments: mg - manpage globals + * Returns: none. + */ + +/*ARGSUSED*/ +void +PrintThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals *mg = GetGlobals(w); + Dimension width, height; + Position x, y; + Widget parent = mg->This_Manpage; + Widget topwindow = mg->This_Manpage; + Log(("print!\n")); + + if (!mg->printdialog) { + int n; + Arg args[20]; + + n = 0; + XtSetArg(args[n], XtNallowShellResize, True); n++; + mg->printdialog_shell = XtCreatePopupShell("printdialogshell", + transientShellWidgetClass, + topwindow, args, n); + n = 0; + mg->printdialog = XtCreateManagedWidget("printdialog", printDialogWidgetClass, + mg->printdialog_shell, args, n); + XtAddCallback(mg->printdialog, XawNOkCallback, printOKXtProc, NULL); + XtAddCallback(mg->printdialog, XawNCancelCallback, printCancelXtProc, NULL); + + XtRealizeWidget(mg->printdialog_shell); + } + + /* Center dialog */ + XtVaGetValues(mg->printdialog_shell, + XtNwidth, &width, + XtNheight, &height, + NULL); + + x = (Position)(XWidthOfScreen( XtScreen(parent)) - width) / 2; + y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3; + + XtVaSetValues(mg->printdialog_shell, + XtNx, x, + XtNy, y, + NULL); + + XtPopup(mg->printdialog_shell, XtGrabNonexclusive); +} +#endif /* INCLUDE_XPRINT_SUPPORT */ + +/* Function Name: ShowVersion + * Description: Show current version. + * Arguments: w - any widget in the manpage. + * event - NOT USED. + * params, num_params - NOT USED. + * Returns: none. + */ + +/*ARGSUSED*/ +void +ShowVersion(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals * man_globals = GetGlobals(w); + ChangeLabel(man_globals->label, XMAN_VERSION); +} diff --git a/xman/help.c b/xman/help.c new file mode 100644 index 0000000..76956df --- /dev/null +++ b/xman/help.c @@ -0,0 +1,110 @@ +/* $XConsortium: help.c,v 1.10 94/04/17 20:43:53 dave Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86$ */ + +/* + * xman - X window system manual page display program. + * Author: Chris D. Peterson, MIT Project Athena + * Created: January 19, 1988 + */ + +#include "globals.h" + +extern Atom wm_delete_window; /* in main.c */ + +/* Function Name: MakeHelpWidget. + * Description: This function creates the help widget so that it will be + * ready to be displayed. + * Arguments: none. + * Returns: none. + */ + +Boolean +MakeHelpWidget(void) +{ + + ManpageGlobals * man_globals; /* The psuedo global structure. */ + + if (help_widget != NULL) /* If we already have a help widget. + then do not create one. */ + return(TRUE); + + man_globals = InitPsuedoGlobals(); + + CreateManpageWidget(man_globals, HELPNAME, FALSE); + help_widget = man_globals->This_Manpage; + + if (OpenHelpfile(man_globals) == FALSE) { + XtDestroyWidget(help_widget); + help_widget = NULL; + return(FALSE); + } + + ChangeLabel(man_globals->label, "Xman Help"); + + XtManageChild( man_globals->manpagewidgets.manpage ); + XtRealizeWidget( help_widget ); + SaveGlobals( man_globals->This_Manpage, man_globals ); + AddCursor( help_widget, resources.cursors.manpage); + +/* + * Set up ICCCM delete window. + */ + XtOverrideTranslations + (man_globals->This_Manpage, + XtParseTranslationTable ("WM_PROTOCOLS: RemoveThisManpage()")); + (void) XSetWMProtocols (XtDisplay(man_globals->This_Manpage), + XtWindow(man_globals->This_Manpage), + &wm_delete_window, 1); + + return(TRUE); +} + +/* Function Name: OpenHelpfile + * Description: opens the helpfile. + * Arguments: man_globals - the psuedo globals structure. + * Returns: False if no helpfile was found. + */ + +Boolean +OpenHelpfile(ManpageGlobals * man_globals) +{ + FILE * help_file_ptr; + + if( (help_file_ptr = fopen(resources.help_file, "r")) == NULL ) { + PopupWarning(man_globals, + "Could not open help file, NO HELP WILL BE AVALIABLE."); + return(FALSE); + } + + OpenFile(man_globals, help_file_ptr); + return(TRUE); +} diff --git a/xman/icon_help.h b/xman/icon_help.h new file mode 100644 index 0000000..228c3c7 --- /dev/null +++ b/xman/icon_help.h @@ -0,0 +1,50 @@ +/* $XConsortium: icon_help.h,v 1.5 94/04/17 20:43:54 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +/* + * xman - X window system manual page display program. + * Author: Chris D. Peterson, MIT Project Athena + * Created: August 15, 1988 + */ + +#define icon_help_width 30 +#define icon_help_height 30 +static unsigned char icon_help_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0xf8, 0xdf, 0xfe, 0x07, + 0x3e, 0xfc, 0x0f, 0x1f, 0x06, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x18, + 0x06, 0xe0, 0x03, 0x18, 0x06, 0xf0, 0x07, 0x18, 0x06, 0x18, 0x0c, 0x18, + 0x06, 0x0c, 0x18, 0x18, 0x06, 0x0c, 0x18, 0x18, 0x06, 0x0c, 0x18, 0x18, + 0x06, 0x00, 0x18, 0x18, 0x06, 0x00, 0x18, 0x18, 0x06, 0x00, 0x0c, 0x18, + 0x06, 0x80, 0x07, 0x18, 0x06, 0xc0, 0x03, 0x18, 0x06, 0xc0, 0x00, 0x18, + 0x06, 0xc0, 0x00, 0x18, 0x06, 0xc0, 0x00, 0x18, 0x06, 0xc0, 0x00, 0x18, + 0x06, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x18, 0x06, 0xc0, 0x00, 0x18, + 0x06, 0xc0, 0x00, 0x18, 0xc6, 0x03, 0xf0, 0x18, 0xfe, 0x1f, 0xfe, 0x1f, + 0x3e, 0xfc, 0x0f, 0x1f, 0x06, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; diff --git a/xman/icon_open.h b/xman/icon_open.h new file mode 100644 index 0000000..b47b1d1 --- /dev/null +++ b/xman/icon_open.h @@ -0,0 +1,50 @@ +/* $XConsortium: icon_open.h,v 1.5 94/04/17 20:43:54 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +/* + * xman - X window system manual page display program. + * Author: Chris D. Peterson, MIT Project Athena + * Created: January 29, 1988 + */ + +#define icon_open_width 30 +#define icon_open_height 30 +static unsigned char icon_open_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0xf8, 0xdf, 0xfe, 0x07, + 0x3e, 0xfc, 0x0f, 0x1f, 0x06, 0x00, 0x00, 0x18, 0x06, 0x30, 0x03, 0x18, + 0xc6, 0x31, 0xe3, 0x18, 0x36, 0x32, 0x13, 0x1b, 0x06, 0x30, 0x03, 0x18, + 0xc6, 0xf1, 0xe3, 0x18, 0x36, 0xe2, 0x11, 0x1b, 0x06, 0x00, 0x00, 0x18, + 0xc6, 0xf1, 0xe3, 0x18, 0x36, 0x32, 0x13, 0x1b, 0x06, 0x30, 0x03, 0x18, + 0xc6, 0xf1, 0xe3, 0x18, 0x36, 0x32, 0x10, 0x1b, 0x06, 0x30, 0x00, 0x18, + 0xc6, 0x01, 0xe0, 0x18, 0x36, 0x3a, 0x17, 0x1b, 0x06, 0xf8, 0x07, 0x18, + 0xc6, 0xd9, 0xe6, 0x18, 0x36, 0xda, 0x16, 0x1b, 0x06, 0x18, 0x06, 0x18, + 0x06, 0x18, 0x06, 0x18, 0xc6, 0x03, 0xf0, 0x18, 0xfe, 0x1f, 0xfe, 0x1f, + 0x3e, 0xfc, 0x0f, 0x1f, 0x06, 0xc0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00}; diff --git a/xman/iconclosed.h b/xman/iconclosed.h new file mode 100644 index 0000000..106068c --- /dev/null +++ b/xman/iconclosed.h @@ -0,0 +1,47 @@ +/* $XConsortium: iconclosed.h,v 1.5 94/04/17 20:43:55 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +/* + * Author: Chris D. Peterson, MIT Project Athena + * Created: January 29, 1988 + */ + +#define iconclosed_width 20 +#define iconclosed_height 30 +static unsigned char iconclosed_bits[] = { + 0x00, 0x00, 0x00, 0xfc, 0xff, 0x07, 0x0e, 0xf8, 0x07, 0x06, 0x00, 0x05, + 0xfe, 0xff, 0x04, 0xbe, 0xfb, 0x04, 0xbe, 0xfb, 0x04, 0xbe, 0xfb, 0x04, + 0xbe, 0xfb, 0x04, 0xbe, 0xfb, 0x04, 0x3e, 0xf8, 0x04, 0xfe, 0xff, 0x04, + 0xfe, 0xff, 0x04, 0x3e, 0xf8, 0x04, 0xbe, 0xfb, 0x04, 0xbe, 0xfb, 0x04, + 0x3e, 0xf8, 0x04, 0xbe, 0xff, 0x04, 0xbe, 0xff, 0x04, 0xfe, 0xff, 0x04, + 0xfe, 0xff, 0x04, 0x3e, 0xf9, 0x04, 0x3e, 0xf9, 0x04, 0xbe, 0xfa, 0x04, + 0xbe, 0xfa, 0x04, 0xbe, 0xfb, 0x06, 0xbe, 0xfb, 0x05, 0xfe, 0xff, 0x00, + 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00}; diff --git a/xman/mkinstalldirs b/xman/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xman/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xman/print.c b/xman/print.c new file mode 100644 index 0000000..0d5b1d3 --- /dev/null +++ b/xman/print.c @@ -0,0 +1,396 @@ +/* + * $Xorg: print.c,v 1.1 2004/04/30 02:05:54 gisburn Exp $ + * +Copyright 2004 Roland Mainz + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +/* Turn a NULL pointer string into an empty string */ +#define NULLSTR(x) (((x)!=NULL)?(x):("")) + +#define Error(x) { printf x ; exit(EXIT_FAILURE); } +#define Assertion(expr, msg) { if (!(expr)) { Error msg } } +#define Log(x) { if(True) printf x; } + +#include "print.h" +#include "ScrollByL.h" +#include +#include +#include +#include + +static Widget +CreatePrintShell(Widget videoshell, + Screen *pscreen, + Visual *pvisual, + String printshell_name, + ArgList args, + Cardinal numargs) +{ + String videoname, + videoclass; + Widget pappshell, + printshell; + Display *pdpy = XDisplayOfScreen(pscreen); + int dummyc = 0; + String dummys = ""; + Cardinal shell_n; + Arg shell_args[5]; + + XtGetApplicationNameAndClass(XtDisplay(videoshell), + &videoname, &videoclass); + + /* XXX: Why is the |dummyc|&&|dummys| stuff needed here ? */ + XtDisplayInitialize(XtWidgetToApplicationContext(videoshell), pdpy, + videoname, videoclass, + NULL, 0, + &dummyc, &dummys); + + shell_n = 0; + XtSetArg(shell_args[shell_n], XtNscreen, pscreen); shell_n++; + if (pvisual) { + XtSetArg(shell_args[shell_n], XtNvisual, pvisual); shell_n++; + } + pappshell = XtAppCreateShell(videoname, videoclass, + applicationShellWidgetClass, + pdpy, + shell_args, shell_n); + printshell = XtCreatePopupShell(printshell_name, + xawPrintShellWidgetClass, + pappshell, args, numargs); + + + /* we're mapping/unmapping at start/end page time */ + XtSetMappedWhenManaged(printshell, False); + + /* We realise the widget when we're done with building the widget tree... */ + + return printshell; +} + +typedef struct +{ + const char *programname; + Widget toplevel; + Bool isPrinting; + Widget printshell; + struct + { + Widget form; + Widget pageheaderlabel; + Widget manpage; + } content; /* content to print */ + int numpages; + Display *pdpy; + Screen *pscreen; + XPContext pcontext; + XtCallbackProc pdpyDestroyCallback; + void *printtofile_handle; + const char *jobtitle; +} AppPrintData; + +static AppPrintData apdx; +static AppPrintData *apd = &apdx; + +/* "Count" pages in a scrollByLineWidgetClass widget */ +static +long CountPages(Widget sblw) +{ + long num_pages = 0; + Cardinal n; + Arg args[3]; + int num_total_lines = 0, + num_visible_lines = 0; + + n = 0; + XtSetArg(args[n], XtNNumTotalLines, &num_total_lines); n++; + XtSetArg(args[n], XtNNumVisibleLines, &num_visible_lines); n++; + XtGetValues(sblw, args, n); + +#define DIV_ROUND_UP(a, b) (((a)+((b)-1)) / (b)) + /* scrollByLineWidgetClass's "Page(forward)" always overlaps by one + * line so we use |num_visible_lines-1| instead of |num_visible_lines| */ + num_pages = DIV_ROUND_UP(num_total_lines, num_visible_lines-1); +#undef DIV_ROUND_UP + + return num_pages; +} + +static void +PageSetupCB(Widget widget, XtPointer client_data, XtPointer call_data) +{ + Widget pshell = widget; + XawPrintShellCallbackStruct *psp = (XawPrintShellCallbackStruct *)call_data; + AppPrintData *p = (AppPrintData *)client_data; + + Log(("--> PageSetupCB\n")); + + if (!psp->last_page_in_job) { + int currpage; + char buffer[256]; + + XtVaGetValues(pshell, XawNcurrPageNumInJob, &currpage, NULL); + + sprintf(buffer, "Title: %s / Page: %d/%d", p->jobtitle, currpage, p->numpages); + XtVaSetValues(apd->content.pageheaderlabel, XtNlabel, buffer, NULL); + + /* Note: XawPrintShell's pagecount starts with '1' + * (=first page is page no. '1') */ + if (currpage > 1) { + String params[] = { "Forward" }; + Log(("pagedown %d\n", currpage)); + /* "Page(Forward)" is scrollByLineWidgetClass's way to + * move one page forward */ + XtCallActionProc(p->content.manpage, "Page", NULL, params, ONE); + } + else + { + Log(("first page\n")); + } + + if (currpage >= p->numpages) { + psp->last_page_in_job = True; + } + } +} + +static +void FinishPrinting(AppPrintData *p) +{ + /* Wait for the job to finish */ + if (p->printtofile_handle) { + if (XpuWaitForPrintFileChild(p->printtofile_handle) != XPGetDocFinished) { + fprintf(stderr, "%s: Error while printing to file.\n", apd->programname); + } + p->printtofile_handle = NULL; + } + + /* Avoid that the manpage object tries to close the |FILE *|-handle at destruction time */ + XtVaSetValues(p->content.manpage, XtNfile, NULL, NULL); + + if (p->printshell) { + XtDestroyWidget(p->printshell); + p->printshell = NULL; + } + + /* Two issues here: + * 1. The print display connection is owned by the print dialog + * To avoid any problems with that use a callback back to the main + * application which calls + * |XawPrintDialogClosePrinterConnection(w, False)| to ask the + * print dialog widget to close all print display resources and + * disown the object. + * 2. We have to use XpDestroyContext() and XtCloseDisplay() + * instead of XpuClosePrinterDisplay() to make libXt happy... + * + * Call callback... */ + (*apd->pdpyDestroyCallback)(p->toplevel, NULL, NULL); /* HACK! */ + + /* ... and then get rid of the display */ + if (p->pcontext != None) { + XpDestroyContext(p->pdpy, p->pcontext); + } + XtCloseDisplay(p->pdpy); + + p->toplevel = NULL; + p->isPrinting = False; + p->pdpy = NULL; + p->pscreen = NULL; + p->pcontext = None; +} + +static +void PrintEndJobCB(Widget pshell, XtPointer client_data, XtPointer call_data) +{ + AppPrintData *p = (AppPrintData *)client_data; + + Log(("--> PrintEndJobCB\n")); + + /* Finish printing and destroy print shell (it's legal to destroy Xt + * widgets from within it's own callbacks) */ + FinishPrinting(p); +} + +static +XFontStruct *GetPrintTextFont(Display *pdpy, const char *fontprefix, long dpi_x, long dpi_y) +{ + XFontStruct *font; + char fontname[1024]; + + sprintf(fontname, "%s--*-120-%ld-%ld-*-*-iso8859-1", fontprefix, dpi_x, dpi_y); + font = XLoadQueryFont(pdpy, fontname); + if (!font) { + sprintf(fontname, "-adobe-courier-medium-r-normal--*-120-%ld-%ld-*-*-iso8859-1", dpi_x, dpi_y); + font = XLoadQueryFont(pdpy, fontname); + } + if (!font) { + sprintf(fontname, "-*-*-*-*-*-*-*-120-%ld-%ld-*-*-iso8859-1", dpi_x, dpi_y); + font = XLoadQueryFont(pdpy, fontname); + } + if (!font) + Error(("XLoadQueryFont failure.\n")); + return font; + +} + +void DoPrintManpage(const char *programname, + FILE *manpagefile, Widget toplevel, + Display *pdpy, XPContext pcontext, + XpuColorspaceRec *colorspace, + XtCallbackProc pdpyDestroyCB, + const char *jobtitle, const char *toFile) +{ + long dpi_x = 0L, + dpi_y = 0L; + int n; + Arg args[20]; + XFontStruct *printFontNormal; + XFontStruct *printFontBold; + XFontStruct *printFontItalic; + XFontStruct *printFontSymbol; + + if (!manpagefile) { + Error(("DoPrintManpage: No FILE given.")); + } + + apd->programname = programname; + apd->pdpyDestroyCallback = pdpyDestroyCB; + + if (apd->isPrinting) { + fprintf(stderr, "%s: Already busy with printing.\n", apd->programname); + return; + } + + /* Configure the print context (paper size, title etc.) + * We must do this before creating any Xt widgets - otherwise they will + * make wrong assuptions about fonts, resultions etc. ... + */ + XpuSetJobTitle(pdpy, pcontext, jobtitle); + + /* Configuration done, set the context */ + XpSetContext(pdpy, pcontext); + + /* Get default printer resolution */ + if (XpuGetResolution(pdpy, pcontext, &dpi_x, &dpi_y) != 1) { + fprintf(stderr, "%s: No default resolution for printer.\n", apd->programname); + XpuClosePrinterDisplay(pdpy, pcontext); + return; + } + + apd->toplevel = toplevel; + apd->pdpy = pdpy; + apd->pcontext = pcontext; + apd->pscreen = XpGetScreenOfContext(pdpy, pcontext); + apd->jobtitle = jobtitle; + + n = 0; + /* Override any geometry resource settings as XawPrintShell adjusts it's size + * to the current page siue when |XawPrintLAYOUTMODE_DRAWABLEAREA| or + * |XawPrintLAYOUTMODE_PAGESIZE| are used. */ + XtSetArg(args[n], XtNgeometry, "+0+0"); n++; + XtSetArg(args[n], XawNlayoutMode, XawPrintLAYOUTMODE_DRAWABLEAREA); n++; + if (colorspace) { + printf("Setting visual to id=0x%lx.\n", colorspace->visualinfo.visualid); + } + apd->printshell = CreatePrintShell(toplevel, apd->pscreen, + (colorspace?(colorspace->visualinfo.visual):(NULL)), + "printshell", args, n); + + n = 0; + XtSetArg(args[n], XtNresizable, True); n++; + XtSetArg(args[n], XtNright, XtChainRight); n++; + apd->content.form = XtCreateManagedWidget("form", formWidgetClass, apd->printshell, args, n); + + printFontNormal = GetPrintTextFont(pdpy, "-*-courier-medium-r-*", dpi_x, dpi_y); + printFontBold = GetPrintTextFont(pdpy, "-*-courier-bold-r-*", dpi_x, dpi_y); + printFontItalic = GetPrintTextFont(pdpy, "-*-courier-medium-o-*", dpi_x, dpi_y); + printFontSymbol = GetPrintTextFont(pdpy, "-*-symbol-*-*-*", dpi_x, dpi_y); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, NULL); n++; + XtSetArg(args[n], XtNtop, XtChainTop); n++; + XtSetArg(args[n], XtNright, XtChainRight); n++; + XtSetArg(args[n], XtNresizable, True); n++; + XtSetArg(args[n], XtNfont, printFontNormal); n++; /* fontset would be better */ + XtSetArg(args[n], XtNlabel, "Page: n/n"); n++; + XtSetArg(args[n], XtNjustify, XtJustifyRight); n++; + apd->content.pageheaderlabel = XtCreateManagedWidget("pageinfo", labelWidgetClass, apd->content.form, args, n); + + n = 0; + XtSetArg(args[n], XtNfile, manpagefile); n++; + +/* Usually I would expect that using |XtNfromVert, apd->content.pageheaderlabel| + * would be the correct way to place the text widget with the main content below + * the page header widget - but for an unknown reason this doesn not work: The + * text widget squishes itself into the bottom half of the page and only occupies + * 1/2 of the page's with... ;-(( */ +#define WORKAROUND_FOR_SOMETHING_IS_WRONG 1 +#ifdef WORKAROUND_FOR_SOMETHING_IS_WRONG + XtSetArg(args[n], XtNtop, XtChainTop); n++; + XtSetArg(args[n], XtNright, XtChainRight); n++; + XtSetArg(args[n], XtNvertDistance, (printFontNormal->ascent+printFontNormal->descent+2)*2); n++; +#else + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, apd->content.pageheaderlabel); n++; +#endif + + XtSetArg(args[n], XtNmanualFontNormal, printFontNormal); n++; + XtSetArg(args[n], XtNmanualFontBold, printFontBold); n++; + XtSetArg(args[n], XtNmanualFontItalic, printFontItalic); n++; + XtSetArg(args[n], XtNmanualFontSymbol, printFontSymbol); n++; + apd->content.manpage = XtCreateManagedWidget("manpage", scrollByLineWidgetClass, apd->content.form, args, n); + + XtAddCallback(apd->printshell, XawNpageSetupCallback, PageSetupCB, (XtPointer)apd); + XtAddCallback(apd->printshell, XawNendJobCallback, PrintEndJobCB, (XtPointer)apd); + + /* Realise print shell (which will set position+size of the child + * widgets based on the current page size) */ + XtRealizeWidget(apd->printshell); + + /* Count number of pages in the manpage widget */ + apd->numpages = CountPages(apd->content.manpage); + + /* Make sure that the Xt machinery is really using the right screen (assertion) */ + if (XpGetScreenOfContext(XtDisplay(apd->printshell), apd->pcontext) != XtScreen(apd->printshell)) + Error(("Widget's screen != print screen. BAD.\n")); + + apd->isPrinting = True; + + if (toFile) { + printf("%s: Printing to file '%s'...\n", apd->programname, toFile); + apd->printtofile_handle = XpuStartJobToFile(pdpy, pcontext, toFile); + if (!apd->printtofile_handle) { + perror("XpuStartJobToFile failure"); + apd->isPrinting = False; + return; + } + } + else + { + printf("%s: Printing to printer...\n", apd->programname); + XpuStartJobToSpooler(pdpy); + } +} + + diff --git a/xman/print.h b/xman/print.h new file mode 100644 index 0000000..892cd6c --- /dev/null +++ b/xman/print.h @@ -0,0 +1,50 @@ +/* + * $Xorg: print.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $ + * +Copyright 2004 Roland Mainz + +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 above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +#ifndef XMAN_PRINT_H +#define XMAN_PRINT_H 1 + +#include +#include +#include +#include +#include +#include + +#define PrintMsg(x) { printf("xman: "); printf x ; } + +/* Prototypes */ +void DoPrintManpage(const char *programname, + FILE *manpage, + Widget toplevel, + Display *pdpy, XPContext pcontext, + XpuColorspaceRec *colorspace, + XtCallbackProc printDisplayDestroyCallback, + const char *jobTitle, + const char *toFile); + +#endif /* !XMAN_PRINT_H */ diff --git a/xman/search.c b/xman/search.c new file mode 100644 index 0000000..48c4efe --- /dev/null +++ b/xman/search.c @@ -0,0 +1,401 @@ +/* $XConsortium: search.c,v 1.21 94/04/17 20:43:58 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xman/search.c,v 1.5 2001/01/27 17:24:27 herrb Exp $ */ + + +#include "globals.h" +#include "vendor.h" + +/* Map and control-M to goto begining of file. */ + +#define SEARCHARGS 10 + +static FILE * DoManualSearch(ManpageGlobals *man_globals, char * string); +static int BEntrySearch(char * string, char ** first, int number); + +/* Function Name: MakeSearchWidget + * Description: This Function Creates the Search Widget. + * Arguments: man_globals - the pseudo globas for this manpage. + * w - the widgets parent + * Returns: the search widget. + */ + +void +MakeSearchWidget(ManpageGlobals * man_globals, Widget parent) +{ + Widget dialog, command, text, cancel; + Arg arglist[2]; + Cardinal num_args = 0; + + XtSetArg(arglist[0], XtNtransientFor, parent); + man_globals->search_widget = XtCreatePopupShell(SEARCHNAME, + transientShellWidgetClass, + parent, + arglist, 1); + + if (resources.clear_search_string) { + XtSetArg(arglist[0], XtNvalue, ""); num_args++; + } + + dialog = XtCreateManagedWidget(DIALOG, dialogWidgetClass, + man_globals->search_widget, + arglist, num_args); + + if ( (text = XtNameToWidget(dialog, "value")) == (Widget) NULL) + PopupWarning(NULL, "Could not find text widget in MakeSearchWidget."); + else + XtSetKeyboardFocus(dialog, text); + + XawDialogAddButton(dialog, MANUALSEARCH, NULL, NULL); + XawDialogAddButton(dialog, APROPOSSEARCH, NULL, NULL); + XawDialogAddButton(dialog, CANCEL, NULL, NULL); + +/* + * This is a bit gross, but it get the cancel button underneath the + * others, and forms them up to the right size.. + */ + + if ( ((command = XtNameToWidget(dialog, MANUALSEARCH)) == (Widget) NULL) || + ((cancel = XtNameToWidget(dialog, CANCEL)) == (Widget) NULL) ) + PopupWarning(NULL, + "Could not find manual search widget in MakeSearchWidget."); + else { + static char * half_size[] = { + MANUALSEARCH, APROPOSSEARCH, NULL + }; + static char * full_size[] = { + "label", "value", CANCEL, NULL + }; + + num_args = 0; + XtSetArg(arglist[num_args], XtNfromVert, command); num_args++; + XtSetArg(arglist[num_args], XtNfromHoriz, NULL); num_args++; + XtSetValues(cancel, arglist, num_args); + FormUpWidgets(dialog, full_size, half_size); + } + +} + +/* Function Name: SearchString + * Description: Returns the search string. + * Arguments: man_globals - the globals. + * Returns: the search string. + */ + +static char * +SearchString( +ManpageGlobals * man_globals) +{ + Widget dialog; + + dialog = XtNameToWidget(man_globals->search_widget, DIALOG); + if (dialog != NULL) + return(XawDialogGetValueString(dialog)); + + PopupWarning(man_globals, + "Could not get the search string, no search will be preformed."); + return(NULL); +} + + +/* Function Name: DoSearch + * Description: This function performs a search for a man page or apropos + * search upon search string. + * Arguments: man_globals - the pseudo globas for this manpage. + * type - the type of search. + * Returns: none. + */ + +#define LOOKLINES 6 + +/* + * Manual searches look through the list of manual pages for the right one + * with a binary search. + * + * Apropos searches still exec man -k. + * + * If nothing is found then I send a warning message to the user, and do + * nothing. + */ + +FILE * +DoSearch(ManpageGlobals * man_globals, int type) +{ + char cmdbuf[BUFSIZ],*mantmp, *manpath; + char tmp[BUFSIZ],path[BUFSIZ]; + char string_buf[BUFSIZ], cmp_str[BUFSIZ], error_buf[BUFSIZ]; + char * search_string = SearchString(man_globals); + FILE * file; +#ifdef HAS_MKSTEMP + int fd; +#endif + int count; + Boolean flag; + + if (search_string == NULL) return(NULL); + + /* If the string is empty or starts with a space then do not search */ + + if ( streq(search_string,"") ) { + PopupWarning(man_globals, "Search string is empty."); + return(NULL); + } + + if (strlen(search_string) >= BUFSIZ) { + PopupWarning(man_globals, "Search string too long."); + return(NULL); + } + if (search_string[0] == ' ') { + PopupWarning(man_globals, "First character cannot be a space."); + return(NULL); + } + + if (type == APROPOS) { + char label[BUFSIZ]; + + strcpy(tmp, MANTEMP); /* get a temp file. */ +#ifdef HAS_MKSTEMP + fd = mkstemp(tmp); + if (fd < 0) { + PopupWarning(man_globals, "Cant create temp file"); + return NULL; + } +#else + (void)mktemp(tmp); +#endif + mantmp = tmp; + + manpath=getenv("MANPATH"); + if (manpath == NULL || streq(manpath,"") ) { +#ifdef MANCONF + if (!ReadManConfig(path)) +#endif + { + strcpy(path,SYSMANPATH); +#ifdef LOCALMANPATH + strcat(path,":"); + strcat(path,LOCALMANPATH); +#endif + } + } else { + strcpy(path,manpath); + } + + snprintf(label, sizeof(label), + "Results of apropos search on: %s", search_string); + +#ifdef NO_MANPATH_SUPPORT /* not quite correct, but the best I can do. */ + snprintf(cmdbuf, sizeof(cmdbuf), APROPOS_FORMAT, search_string, mantmp); +#else + snprintf(cmdbuf, sizeof(cmdbuf), APROPOS_FORMAT, path, search_string, mantmp); +#endif + + if(system(cmdbuf) != 0) { /* execute search. */ + snprintf(error_buf, sizeof(error_buf), "Something went wrong trying to run %s\n",cmdbuf); + PopupWarning(man_globals, error_buf); + } + +#ifdef HAS_MKSTEMP + if ((file = fdopen(fd, "r")) == NULL) +#else + if((file = fopen(mantmp,"r")) == NULL) +#endif + PrintError("lost temp file? out of temp space?"); + +/* + * Since we keep the FD open we can unlink the file safely, this + * will keep extra files out of /tmp. + */ + + unlink(mantmp); + + snprintf(string_buf, sizeof(string_buf), "%s: nothing appropriate", search_string); + + /* + * Check first LOOKLINES lines for "nothing appropriate". + */ + + count = 0; + flag = FALSE; + while ( (fgets(cmp_str, BUFSIZ, file) != NULL) && (count < LOOKLINES) ) { + if ( cmp_str[strlen(cmp_str) - 1] == '\n') /* strip off the '\n' */ + cmp_str[strlen(cmp_str) - 1] = '\0'; + + if (streq(cmp_str, string_buf)) { + flag = TRUE; + break; + } + count++; + } + + /* + * If the file is less than this number of lines then assume that there is + * nothing apropriate found. This does not confuse the apropos filter. + */ + + if (flag) { + fclose(file); + file = NULL; + ChangeLabel(man_globals->label,string_buf); + return(NULL); + } + + snprintf(man_globals->manpage_title, sizeof(man_globals->manpage_title), + "%s", label); + ChangeLabel(man_globals->label,label); + fseek(file, 0L, SEEK_SET); /* reset file to point at top. */ + } + else { /* MANUAL SEACH */ + file = DoManualSearch(man_globals, search_string); + if (file == NULL) { + snprintf(string_buf, sizeof(string_buf), "No manual entry for %s.", search_string); + ChangeLabel(man_globals->label, string_buf); + if (man_globals->label == NULL) + PopupWarning(man_globals, string_buf); + return(NULL); + } + } + + if (resources.clear_search_string) { + Arg arglist[1]; + Widget dialog; + + dialog = XtNameToWidget(man_globals->search_widget, DIALOG); + if (dialog == NULL) + PopupWarning(man_globals, "Could not clear the search string."); + + XtSetArg(arglist[0], XtNvalue, ""); + XtSetValues(dialog, arglist, (Cardinal) 1); + } + + return(file); +} + +/* Function Name: DoManualSearch + * Description: performs a manual search. + * Arguments: man_globals - the manual page specific globals. + * Returns: the filename of the man page. + */ + +#define NO_ENTRY -100 + +static FILE * +DoManualSearch(ManpageGlobals *man_globals, char * string) +{ + int e_num = NO_ENTRY; + int i; + +/* search current section first. */ + + i = man_globals->current_directory; + e_num = BEntrySearch(string, manual[i].entries, manual[i].nentries); + +/* search other sections. */ + + if (e_num == NO_ENTRY) { + i = 0; /* At the exit of the loop i needs to + be the one we used. */ + while ( TRUE ) { + if (i == man_globals->current_directory) + if (++i >= sections) return(NULL); + e_num = BEntrySearch(string, manual[i].entries, manual[i].nentries); + if (e_num != NO_ENTRY) break; + if (++i >= sections) return(NULL); + } + +/* + * Manual page found in some other section, unhighlight the current one. + */ + if ( man_globals->manpagewidgets.box != NULL) + XawListUnhighlight( + man_globals->manpagewidgets.box[man_globals->current_directory]); + } + else { + /* + * Highlight the element we are searching for if it is in the directory + * listing currently being shown. + */ + if ( man_globals->manpagewidgets.box != NULL) + XawListHighlight(man_globals->manpagewidgets.box[i], e_num); + } + return(FindManualFile(man_globals, i, e_num)); +} + +/* Function Name: BEntrySearch + * Description: binary search through entries. + * Arguments: string - the string to match. + * first - the first entry in the list. + * number - the number of entries. + * Returns: a pointer to the entry found. + */ + +static int +BEntrySearch( +char * string, +char ** first, +int number) +{ + int check, cmp, len_cmp, global_number; + char *head, *tail; + + global_number = 0; + while (TRUE) { + + if (number == 0) { + return(NO_ENTRY); /* didn't find it. */ + } + + check = number/2; + + head = rindex(first[ global_number + check ], '/'); + if (head == NULL) + PrintError("index failure in BEntrySearch"); + head++; + + tail = rindex(head, '.'); + if (tail == NULL) + /* not an error, some systems (e.g. sgi) have only a .z suffix */ + tail = head + strlen(head); + + cmp = strncmp(string, head, (tail - head)); + len_cmp = strlen(string) - (int) (tail - head); + + if ( cmp == 0 && len_cmp == 0) { + return(global_number + check); + } + else if ( cmp < 0 || ((cmp == 0) && (len_cmp < 0)) ) + number = check; + else /* cmp > 0 || ((cmp == 0) && (len_cmp > 0)) */ { + global_number += (check + 1); + number -= ( check + 1 ); + } + } +} diff --git a/xman/tkfuncs.c b/xman/tkfuncs.c new file mode 100644 index 0000000..0222e7c --- /dev/null +++ b/xman/tkfuncs.c @@ -0,0 +1,99 @@ +/* $XConsortium: tkfuncs.c,v 1.6 94/04/17 20:43:59 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86$ */ + +#include +#include +#include +#include +#include +#include + +#include "globals.h" + +/* + * I am doing the "wrong" thing here by looking in the core field for the + * widget to get this info, the "right" thing to do is to do a XtGetValues + * to get this information. + */ + +/* Function Name: Width + * Description: finds the width of a widget. + * Arguments: w - the widget. + * Returns: the width of that widget. + */ + +int +Width(Widget w) +{ + return( (int) w->core.width ); +} + +/* Function Name: Height + * Description: finds the height of a widget. + * Arguments: w - the widget. + * Returns: the height of that widget. + */ + +int +Height(Widget w) +{ + return( (int) w->core.height ); +} + +/* Function Name: BorderWidth + * Description: finds the BorderWidth of a widget. + * Arguments: w - the widget. + * Returns: the BorderWidth of that widget. + */ + +int +BorderWidth(Widget w) +{ + return( (int) w->core.border_width ); +} + +/* + * These functions have got to be able to get at the widget tree, I don't see + * any way around this one. + */ + +/* Function Name: Name + * Description: This function returns the correct popup child + * Arguments: w - widget + * Returns: the popup child. + */ + +char * +Name(Widget w) +{ + return( w->core.name); +} diff --git a/xman/vendor.c b/xman/vendor.c new file mode 100644 index 0000000..56257b3 --- /dev/null +++ b/xman/vendor.c @@ -0,0 +1,318 @@ +/* $XConsortium: vendor.c,v 1.10 94/04/17 20:43:59 rws Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xman/vendor.c,v 1.2 2000/03/03 20:02:25 dawes Exp $ */ + +/* Vendor-specific data structures and operations */ + +#include "globals.h" +#include "vendor.h" + +typedef struct sectionName { + char * name; + char * suffix; +} SectionNameRec; + +#if defined(SYSV) || defined(__osf__) || defined(SVR4) && !defined(sun) + +static SectionNameRec SectionNames[] = { + {"(1) User Commands", "1"}, + {"(1m) Sys, Administration", "1m"}, + {"(2) System Calls", "2"}, + {"(3) Subroutines", "3"}, + {"(4) File Formats", "4"}, + {"(5) Miscellaneous", "5"}, + {"(6) Games", "6"}, + {"(7) Devices", "7"}, + {"(8) Sys. Administration", "8"}, + {"(l) Local", "l"}, + {"(n) New", "n"}, + {"(o) Old", "o"} +#ifdef __SCO__ + , + { "(ADM) System Administration", "ADM" }, + { "(ADMN) Network Administration", "ADMN" }, + { "(ADMP) Protocol Administration", "ADMP" }, + { "(C) Commands", "C" }, + { "(CMD) DOS Commands", "CMD" }, + { "(CP) Programming Commands", "CP" }, + { "(DOS) DOS Subroutines and Libraries", "DOS" }, + { "(F) File Formats", "F" }, + { "(HW) Hardware Dependant", "HW" }, + { "(K) Kernel Subroutines", "K" }, + { "(LOCAL) Local utilities for your system", "LOCAL" }, + { "(M) Miscellaneous", "M" }, + { "(NADM) NFS Administration", "NADM" }, + { "(NC) Network Commands", "NC" }, + { "(NF) Network File Formats", "NF" }, + { "(NS) Network Subroutines", "NS" }, + { "(NSL) Network Services", "NSL" }, + { "(S) Subroutines and Libraries", "S" }, + { "(SCO) Product Engineering Toolkit", "SCO" }, + { "(SFF) Socket File Formats", "SFF" }, + { "(STR) Streams", "STR" }, + { "(TC) Transport Layer Commands", "TC" }, + { "(X) X Man pages", "X" }, + { "(XNX) Xenix Subroutines, Commands and Libs", "XNX" }, + { "(XS) X11 Subroutines and Libraries", "XS" }, + { "(Xm) Motif Commands and Subroutines", "Xm" }, + { "(Xt) X Intrinsics", "Xt" } +#endif +}; + +#else + +#if defined(sun) && defined(SVR4) +/* losing man.cf is useless because it has no section names */ + +static SectionNameRec SectionNames[] = { + {"(1) User Commands", "1"}, + {"(1b) SunOS/BSD Compatibility Commands", "1b"}, + {"(1c) Communication Commands", "1c"}, + {"(1f) FMLI Commands", "1f"}, + {"(1m) Maintenance Commands", "1m"}, + {"(1s) SunOS Specific Commands", "1s"}, + {"(2) System Calls", "2"}, + {"(3) C Library Functions", "3"}, + {"(3b) SunOS/BSD Compatibility Functions", "3b"}, + {"(3c) C Library Functions", "3c"}, + {"(3e) ELF Library Functions", "3e"}, + {"(3g) C Library Functions", "3g"}, + {"(3i) Wid Character Functions", "3i"}, + {"(3k) Kernel VM Library Functions", "3k"}, + {"(3m) Mathematical Library", "3m"}, + {"(3n) Network Functions", "3n"}, + {"(3r) RPC Services Library", "3r"}, + {"(3s) Standard I/O Functions", "3s"}, +#if OSMINORVERSION == 5 + {"(3t) Threads Library", "3t"}, +#endif + {"(3x) Miscellaneous Library Functions", "3x"}, + {"(4) File Formats", "4"}, + {"(4b) Misc. Reference Manual Pages", "4b"}, + {"(5) Environments, Tables, and TROFF Macros", "5"}, + {"(6) Games and Demos", "6"}, + {"(7) Special Files", "7"}, +#if OSMINORVERSION == 5 + {"(7d) Devices", "7d"}, + {"(7fs) File Systems", "7fs"}, + {"(7i) Ioctl Requests", "7i"}, + {"(7m) STREAMS Modules", "7m"}, + {"(7p) Protocols", "7p"}, +#endif + {"(9) Device Driver Information", "9"}, + {"(9e) DDI and DKI Driver Entry Points", "9e"}, + {"(9f) DDI and DKI Kernel Functions", "9f"}, + {"(9s) DDI and DKI Data Structures", "9s"}, + {"(l) Local", "l"}, + {"(n) New", "n"}, +}; + +#else + +static SectionNameRec SectionNames[] = { + {"(1) User Commands", "1"}, + {"(2) System Calls", "2"}, + {"(3) Subroutines", "3"}, + {"(4) Devices", "4"}, + {"(5) File Formats", "5"}, + {"(6) Games", "6"}, + {"(7) Miscellaneous", "7"}, + {"(8) Sys. Administration", "8"}, +#ifdef Lynx + {"(9) Device driver service calls", "9"}, +#endif +#if defined(__OpenBSD__) || defined(__NetBSD__) + {"(9) Kernel Manual", "9"}, +#endif +#if defined(__FreeBSD__) + {"(9) Kernel Interfaces", "9"}, +#endif + {"(l) Local", "l"}, + {"(n) New", "n"}, + {"(o) Old", "o"}, +#ifdef sony + {"(p) Public Domain", "p"}, + {"(s) Sony Specific", "s"}, +#endif +}; + +#endif +#endif + +/* Function Name: AddStandardSections + * Description: Adds all the standard sections to the list for this path. + * Arguments: list - a pointer to the section list. + * path - the path to these standard sections. + * Returns: none. + */ + +void AddStandardSections( +SectionList **list, +char * path) +{ +#ifdef CRAY + AddStandardCraySections(list, path); + return; +#else + register int i; + char file[BUFSIZ]; + int numSections = sizeof(SectionNames) / sizeof(SectionNames[0]); + + for (i=0; i < numSections; i++) { + sprintf(file, "%s%s", SEARCHDIR, SectionNames[i].suffix); + AddNewSection(list, path, file, SectionNames[i].name, TRUE); +#ifdef SEARCHOTHER + sprintf(file, "%s%s", SEARCHOTHER, SectionNames[i].suffix); + AddNewSection(list, path, file, SectionNames[i].name, TRUE); +#endif + } +#endif +} + +#ifdef CRAY +/* Function Name: AddStandardCraySections + * Description: Add sections specific to the Cray. + * Arguments: list - a pointer to the section list. + * path - the path to these standard sections. + * names - standard section names. + * Returns: none. + */ + +void AddStandardCraySections( +SectionList **list, +char *path) +{ + char file[BUFSIZ]; + int i; +#define NoSuf (char *)0 +#define Suffix (char *)1 +#define Fold (char *)2 +#define FoldSuffix (char *)3 + static char *cname[] = { + "(1) User Commands", Suffix, "1", "1bsd", NULL, + "(1) User Commands (instant)", NoSuf, "1r", "1rb", NULL, + "(1m) System Administration", NoSuf, "1m", NULL, + "(2) System Calls", Suffix, "2", NULL, + "(3) Subroutines", FoldSuffix, "3", "3bsd", "3c", "3m", "3mt", "3s", "3sl", "3z", NULL, + "(3) Subroutines (FORTRAN)", Fold, "3f", NULL, + "(3) Subroutines (I/O)", Fold, "3io", NULL, + "(3) Subroutines (X11)", NoSuf, "3X11", NULL, + "(3) Subroutines (Xt)", NoSuf, "3Xt", NULL, + "(3) Subroutines (misc.)", Suffix, "3q", NULL, + "(3) Subroutines (misc.)", Fold, "3x", NULL, + "(3) Subroutines (networking)", Suffix, "3n", "3rpc", "3svc", "3w", "3yp", NULL, + "(3) Subroutines (scientific)", Fold, "3sci", NULL, + "(3) Subroutines (utilities)", FoldSuffix, "3db", "3u", NULL, + "(4) Devices", Suffix, "4", "4d", "4f", "4n", "4p", "4s", NULL, + "(5) File Formats", Suffix, "5", NULL, + "(6) Games", Suffix, "6", NULL, + "(7) Miscellaneous", Suffix, "7", NULL, + "(8) Sys. Administration", NoSuf, "8", NULL, + "(l) Local", Suffix, "l", NULL, + "(n) New", Suffix, "n", NULL, + "(o) Old", Suffix, "o", NULL, + "(info) Information", NoSuf, "info", NULL, + "(osi) Miscellaneous", NoSuf, "osi", NULL, + "(sl) Miscellaneous", NoSuf, "sl", NULL, + "(ultra) Miscellaneous", NoSuf, "ultra", NULL, + NULL + }; + char **p = cname; + + while (*p != NULL) { + char *message = *p++; + int flags = (int) *p++; + while (*p != NULL) { + sprintf(file, "%s%s", SEARCHDIR, *p++); + AddNewSection(list, path, file, message, flags); + } + p++; + } +} +#endif /* CRAY */ + + +/* Function Name: CreateManpageName + * Description: Creates the manual page name for a given item. + * Arguments: entry - the entry to convert. + * Returns: the manual page properly allocated. + */ + +/* + * If the filename is foo.3 - Create an entry of the form: foo + * If the filename is foo.3X11 - Create an entry of the form: foo(X11) + * IF the filename is a.out.1 - Create an entry of the form: a.out + */ + +char * +CreateManpageName( +char * entry, +int section, /* FIXME: unused */ +int flags) +{ + char * cp; + char page[BUFSIZ]; + char sect[BUFSIZ]; + + ParseEntry(entry, NULL, sect, page); + +#ifndef CRAY + if ( (cp = rindex(page, '.')) != NULL) { + if ( (int)strlen(cp) > 2 ) { + *cp++ = '('; + while( (cp[1] != '\0') ) { + *cp = *(cp + 1); + cp++; + } + *cp++ = ')'; + *cp = '\0'; + } + else + *cp = '\0'; + } + +#else /* CRAY - pick up the Cray name from the section */ + + if ( (cp = rindex(page, '.')) == NULL) + cp = page + strlen(page); + if ((flags & MSUFFIX) && strlen(sect) > 4) { + char *p = sect + 4; + *cp++ = '('; + while (*p) + *cp++ = *p++; + *cp++ = ')'; + } + *cp = '\0'; + +#endif /* CRAY */ + + return(StrAlloc(page)); +} diff --git a/xman/version.h b/xman/version.h new file mode 100644 index 0000000..f10367d --- /dev/null +++ b/xman/version.h @@ -0,0 +1,32 @@ +/* $XConsortium: version.h,v 1.11 94/04/17 20:44:00 gildea Exp $ */ +/* + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +#define XMAN_VERSION "Xman Version 3.2.0 - X11R7.0" diff --git a/xman/xman.help b/xman/xman.help new file mode 100644 index 0000000..247ed7c --- /dev/null +++ b/xman/xman.help @@ -0,0 +1,228 @@ + + +XMAN is an X Window System manual browsing tool. + + + +GETTING STARTED + +By default, xman starts by creating a small window that contains three +"buttons" (places on which to click a pointer button). Two of these +buttons, Help and Quit, are self-explanatory. The third, Manual Page, +creates a new manual page browser window; you may use this button to +open a new manual page any time xman is running. + +A new manual page starts up displaying this help information. The +manual page contains three sections. In the upper left corner are two +menu buttons. When the mouse is clicked on either of these buttons a +menu is popped up. The contents of these menus is described below. +Directly to the right of the menu buttons is an informational display. +This display usually contains the name of the directory or manual page +being displayed. It is also used to display warning messages and the +current version of xman. The last and largest section is the +information display. This section of the application contains either a +list of manual pages to choose from or the text of a manual page. + +To use xman pull down the Sections menu to select a manual section. +When the section is displayed, click the left pointer button on the name +of the manual page that you would like to see. Xman will replace the +directory listing with the manual page you selected. + +That should be enough to get you started. Once you understand the +basics of how to use xman, take a look at the rest of this file to see +the advanced features that are available to make using xman fast and +efficient. + + +SCROLLING TEXT + +The scroll bars are similar to xterm and xmh scroll bars; clicking the +left or right pointer button with the pointer at the bottom of the +scroll bar will scroll the text down or up one page, respectively. +Clicking with the pointer farther up the scroll bar scrolls +proportionally less than one page. Clicking the middle button a portion +of the way down the scroll bar will move the text window that portion of +the way down the text. Holding the middle button and moving the pointer +up and down allows the text to be scrolled dynamically. + +You may also type 'f' or to scroll down one page, and 'b' to +scroll up one page. + + +RESIZING WINDOWS + +You can resize any of the windows in xman with your window manager, and +xman will do the best it can to resize everything internally into a +useful configuration. The only control over the internal arrangement +that you have is moving the border between the manual page and directory +when both are displayed. This is done by clicking and holding the any +pointer button when the cursor is over the small square (grip) on the +right side of the screen. The grip is located on the horizontal line +which separates the panes. The grip may be moved up and down to resize +the panes of the screen, and when the pointer button is released xman +will move the pane boundary to the newly specified location. + + +MENU COMMANDS + +There are two ways to activate the menus. The first is to click any +pointer button in the menu button corresponding to the menu you want to +activate. The second method is to hold down the "Control" key and click +the left pointer button for the Options menu or the middle pointer +button for the Sections menu. Reguardless of how the menu was +activated, selecting items is the same. + +Once a menu is activated, continue to hold down the pointer button and +drag the pointer cursor over the item that you would like to activate. +Once the item that you want to select is highlighted, select it by +releasing the pointer button. To avoid making a menu selection, move +the pointer cursor outside the menu and release the button. + +Selecting one of the items in the Sections menu will display the named +directory. + +The following commands are available through the Options menu: + +Display Directory Show the current section directory. + +Display Manual Page Show the current manual page. + +Help Create a help window with this text displayed. + +Search Pop up a dialogue box that allows the entire + tree of manual pages to be searched for a + specific name. A keyword (apropos) search is + also available through this dialogue box. + +Show Both Screens Split the manual page display window to display + both the current manual page and the directory. +Show One Screen Return to a single screen display of either a + manual page or directory listing. + +Remove This Man Page Remove this manual page, do not quit. + +Open New Man Page Pop up a new manual page browser window. + +Show Version Print the current version of xman to the + information display window. Please include the + version number when reporting bugs. + +Quit Close all xman windows and quit xman. + + +SUMMARY OF BASIC ACTIONS + +In a menu button: + + CLICK: Pop up a menu + +In a directory, manual page, or scroll bar: + + CLICK LEFT: Pop up the Options menu. + CLICK MIDDLE: Pop up the Sections menu. + +In a directory: + + CLICK LEFT: Bring up named manual page + CLICK MIDDLE: Go to manual page previously chosen. + +In a manual page or apropos listing: + + CLICK MIDDLE: Go to directory of manual pages. + +In scroll bars: + + CLICK LEFT: Move down - more if pointer is near bottom + of window, less if at top. + CLICK MIDDLE: Move top of page to current pointer position. + CLICK RIGHT: Move up - more if pointer is near bottom + of window, less if at top. + +SEARCHING + +Xman has a built-in searching utility that allows the user to search the +entire manual page tree for a specific topic (manual page search) or a +keyword (apropos search). The search dialogue box can be activated from +the Options menu, or by the key Control-s. If the search is started +from the small initial topbox xman will open a new manual page if the +search was successful, and fail silently if the search was unsuccessful. + +Manual page searches are performed starting in the currently displayed +section. If no match is found then the remaining sections are searched +in the order that the sections appear in the Sections menu, starting at +the top. The current version of xman immediately displays the first +manual page that it finds. If the manual page cannot be found that fact +is noted in the informational display. + +An apropos search will search a list of short descriptions for all +manual pages on the system and return a list of all descriptions which +contain the keyword specified. + + +KEYBOARD ACCELERATORS + +Xman contains a set of preinstalled keyboard accelerators. These are a +set of key bindings that perform many of the same operations as the menu +items. Since it is not necessary to pull down the menu, these actions +can be performed more quickly, hence the name accelerators. + +The default key bindings for xman are: + +Anywhere: + + Control - c Exit xman + Control - h Create the help window + Control - n Create a new man page + Control - q Exit xman + Control - s Create a search popup + +In a manual page, directory, or help window: + + Control - r Remove this manual page or help display + Control - v Show the current version of xman + +In a manual page or directory: + + Control - d Display Directory + Control - m Display Man Page + +In a manual page only: + + b Page Back + f Page forward + Page forward + 1 One line forward + 2 Two lines forward + 3 Three lines forward + 4 Four lines forward + +Note: Control-s does not have any effect in the help window. + + +FURTHER INFORMATION + +Xman is highly customizable. Through the X resource database a user can +customize the look and feel of this application so that it meets a +preferred style of interaction. Almost any configuration that is +available dynamically can be specified through resources. This includes +changing the size, color, and fonts, starting with no topbox, showing +both screens, and rebinding the keyboard accelerators. + +The information on customizing xman is contained in the xman manual +page, I will leave it to you to figure out how to find and display that +information :-) + + + Chris D. Peterson MIT X + Consortium + +CREDITS + +Version: Use 'Show Version' menu item. +Written By: Chris D. Peterson - formerly MIT X Consortium +Based Upon: Xman for X10 by Barry Shein - Boston University + +Copyright 1988, 1989 X Consortium +Edited by Donna Converse and Dave Sternlicht + + diff --git a/xman/xman.man b/xman/xman.man new file mode 100644 index 0000000..4aaabc0 --- /dev/null +++ b/xman/xman.man @@ -0,0 +1,387 @@ +.\" $XConsortium: xman.man,v 1.23 94/04/17 20:44:02 matt Exp $ +.\" +.\" $XFree86: xc/programs/xman/xman.man,v 1.3 2001/01/27 18:21:18 dawes Exp $ +.\" +.TH XMAN 1 __xorgversion__ +.SH NAME +xman \- Manual page display program for the X Window System +.SH SYNOPSIS +.B xman +[ +.I \-options +\&.\|.\|. ] +.SH DESCRIPTION +.I Xman +is a manual page browser. The default size of the initial \fIxman\fP +window is small so that you can leave it running throughout your entire login +session. In the initial window there are three options: +\fIHelp\fP will pop up a window with on-line help, \fIQuit\fP will +exit, and \fIManual Page\fP will pop up a window with a manual page +browser in it. +Typing Control-S will pop up a window prompting for a specific manual +page to display. +You may display more than one manual page browser window at a time +from a single execution of \fIxman\fP. +.PP +For further information on using \fIxman\fP, please read the on-line +help information. Most of this manual will discuss +customization of \fIxman\fP. +.SH "OPTIONS" +.PP +Xman supports all standard Toolkit command line arguments (see +\fIX\fP(1)). The following additional arguments are supported. +.sp +.IP "\fB\-helpfile\fP \fIfilename\fP" +Specifies a helpfile to use other than the default. +.IP \fB\-bothshown\fP +Allows both the manual page and manual directory to be on the screen at +the same time. +.IP \fB\-notopbox\fP +Starts without the Top Menu with the three buttons in it. +.IP "\fB\-geometry\fP \fIWxH+X+Y\fP" +Sets the size and location of the Top Menu with the three buttons in it. +.IP "\fB\-pagesize\fP \fIWxH+X+Y\fP" +Sets the size and location of all the Manual Pages. +.SH "CUSTOMIZING XMAN" +.PP +.I Xman +allows customization of both the directories to be searched for manual pages, +and the name that each directory will map to in the \fISections\fP +menu. Xman determines which directories it will +search by reading the \fIMANPATH\fP environment variable. If no +\fIMANPATH\fP is found then the directory is /usr/man is searched on +POSIX systems. This environment +is expected to be a colon-separated list of directories for xman to search. +.sp +.nf +setenv MANPATH /mit/kit/man:/usr/man +.fi +.PP +By default, +.I xman +will search each of the following directories (in each of the directories +specified in the users MANPATH) for manual pages. If manual pages exist +in that directory then they are added to list of manual pages for +the corresponding menu item. +A menu item is only displayed for those sections that actually contain +manual pages. +.ta 1.5i +.nf + +Directory Section Name +--------- ------------ +man1 (1) User Commands +man2 (2) System Calls +man3 (3) Subroutines +man4 (4) Devices +man5 (5) File Formats +man6 (6) Games +man7 (7) Miscellaneous +man8 (8) Sys. Administration +manl (l) Local +mann (n) New +mano (o) Old + +.fi +For instance, a user has three directories in her manual path and each +contain a directory called \fIman3\fP. All these manual pages will appear +alphabetically sorted when the user selects the menu item called +\fI(3) Subroutines\fP. If there is no directory called \fImano\fP in +any of the directories in her MANPATH, or there are no manual pages +in any of the directories called \fImano\fP then no menu item will be +displayed for the section called \fI(o) Old\fP. +.SH "BSD AND LINUX SYSTEMS" +.PP +In newer BSD and Linux systems, \fIXman\fP will search for a file named +\fI/etc/man.conf\fP which will contain the list of directories containing +manual pages. See \fIman.conf\fP(5) for a complete description of the file +format. +.SH "THE MANDESC FILE" +.PP +By using the \fImandesc\fP file a user or system manager is able to +more closely control which manual pages will appear in each of the sections +represented by menu items in the \fISections\fP menu. This +functionality is only available on a section by section basis, and individual +manual pages may not be handled in this manner. +(Although generous use of +symbolic links \(em see \fIln\fP(1) \(em will allow +almost any configuration you can imagine.) +.PP +The format of the mandesc file is a character followed by a label. The +character determines which of the sections will be added under this label. +For instance suppose that you would like to create an extra menu item that +contains all programmer subroutines. This label should contain all manual +pages in both sections two and three. The \fImandesc\fP file +would look like this: +.nf + +2Programmer Subroutines +3Programmer Subroutines + +.fi +This will add a menu item to the \fISections\fP menu that would +bring up a listing of all manual pages in sections two and three of +the Programmers Manual. Since the label names are \fIexactly\fP the +same they will be added to the same section. Note, however, that the +original sections still exist. +.PP +If you want to completely ignore the default sections in a manual directory +then add the line: +.nf + +no default sections + +.fi +anywhere in your mandesc file. This keeps xman from searching +the default manual sections \fIIn that directory only\fP. As an example, +suppose you want to do the same thing as above, but you don't think that +it is useful to have the \fISystem Calls\fP or \fISubroutines\fP sections +any longer. You would need to duplicate the default entries, as well as +adding your new one. +.nf + +no default sections +1(1) User Commands +2Programmer Subroutines +3Programmer Subroutines +4(4) Devices +5(5) File Formats +6(6) Games +7(7) Miscellaneous +8(8) Sys. Administration +l(l) Local +n(n) New +o(o) Old + +.fi +Xman will read any section that is of the from \fIman\fP, where + is an upper or lower case letter (they are treated distinctly) or +a numeral (0-9). Be warned, however, that man(1) and catman(8) will +not search directories that are non-standard. +.SH WIDGETS +In order to specify resources, it is useful to know the hierarchy of +the widgets which compose \fIxman\fR. In the notation below, +indentation indicates hierarchical structure. The widget class name +is given first, followed by the widget instance name. +.sp +.nf +.ta .5i 1.0i 1.5i 2.0i 2.5i 3.0i 3.5i +Xman xman \fI(This widget is never used)\fP + TopLevelShell topBox + Form form + Label topLabel + Command helpButton + Command quitButton + Command manpageButton + TransientShell search + DialogWidgetClass dialog + Label label + Text value + Command manualPage + Command apropos + Command cancel + TransientShell pleaseStandBy + Label label + TopLevelShell manualBrowser + Paned Manpage_Vpane + Paned horizPane + MenuButton options + MenuButton sections + Label manualBrowser + Viewport directory + List directory + List directory + . + . (one for each section, + . created on the fly) + . + ScrollByLine manualPage + SimpleMenu optionMenu + SmeBSB displayDirectory + SmeBSB displayManualPage + SmeBSB help + SmeBSB search + SmeBSB showBothScreens + SmeBSB removeThisManpage + SmeBSB openNewManpage + SmeBSB showVersion + SmeBSB quit + SimpleMenu sectionMenu + SmeBSB + . + . (one for each section) + . + TransientShell search + DialogWidgetClass dialog + Label label + Text value + Command manualPage + Command apropos + Command cancel + TransientShell pleaseStandBy + Label label + TransientShell likeToSave + Dialog dialog + Label label + Text value + Command yes + Command no + TopLevelShell help + Paned Manpage_Vpane + Paned horizPane + MenuButton options + MenuButton sections + Label manualBrowser + ScrollByLine manualPage + SimpleMenu optionMenu + SmeBSB displayDirectory + SmeBSB displayManualPage + SmeBSB help + SmeBSB search + SmeBSB showBothScreens + SmeBSB removeThisManpage + SmeBSB openNewManpage + SmeBSB showVersion + SmeBSB quit + +.fi +.SH "APPLICATION RESOURCES" +\fIxman\fP has the following application-specific resources which allow +customizations unique to \fIxman\fP. +.PP +.TP 18 +\fBmanualFontNormal\fP (Class \fBFont\fP) +The font to use for normal text in the manual pages. +.TP 18 +\fBmanualFontBold\fP (Class \fBFont\fP) +The font to use for bold text in the manual pages. +.TP 18 +\fBmanualFontItalic\fP (Class \fBFont\fP) +The font to use for italic text in the manual pages. +.TP 18 +\fBdirectoryFontNormal\fP (Class \fBFont\fP) +The font to use for the directory text. +.TP 18 +\fBbothShown\fP (Class \fBBoolean\fP) +Either `true' or `false,' specifies whether or not you want both the +directory and the manual page shown at start up. +.TP 18 +\fBdirectoryHeight\fP (Class \fBDirectoryHeight\fP) +The height in pixels of the directory, when the directory and the manual page +are shown simultaneously. +.TP 18 +\fBtopCursor\fP (Class \fBCursor\fP) +The cursor to use in the top box. +.TP 18 +\fBhelpCursor\fP (Class \fBCursor\fP) +The cursor to use in the help window. +.TP 18 +\fBmanpageCursor\fP (Class \fBCursor\fP) +The cursor to use in the manual page window. +.TP 18 +\fBsearchEntryCursor\fP (Class \fBCursor\fP) +The cursor to use in the search entry text widget. +.TP 18 +\fBpointerColor\fP (Class \fBForeground\fP) +This is the color of all the cursors (pointers) specified above. The +name was chosen to be compatible with xterm. +.TP 18 +\fBhelpFile\fP (Class \fBFile\fP) +Use this rather than the system default helpfile. +.TP 18 +\fBtopBox\fP (Class \fBBoolean\fP) +Either `true' or `false,' determines whether the top box (containing +the help, quit and manual page buttons) or a manual page is put on the screen +at start-up. The default is true. +.TP 18 +\fBverticalList\fP (Class \fBBoolean\fP) +Either `true' or `false,' determines whether the directory listing is +vertically or horizontally organized. The default is horizontal (false). +.SH "GLOBAL ACTIONS" +\fIXman\fP defines all user interaction through global actions. This allows +the user to modify the translation table of any widget, and bind any event +to the new user action. The list of actions supported by \fIxman\fP are: +.TP 1.5i +.B GotoPage(\fIpage\fB) +When used in a manual page display window this will allow the user to +move between a directory and manual page display. The \fIpage\fP argument can +be either \fBDirectory\fP or \fBManualPage\fP. +.TP 1.5i +.B Quit() +This action may be used anywhere, and will exit xman. +.TP 1.5i +.B Search(\fItype\fB, \fIaction\fB) +Only useful when used in a search popup, this action will cause the search +widget to perform the named search type on the string in the search popup's +value widget. This action will also pop down the search widget. The +\fItype\fP argument can be either \fBApropos\fP, \fBManpage\fP or +\fBCancel\fP. If an \fIaction\fP of \fBOpen\fP is specified then xman +will open a new manual page to display the results of the search, otherwise +xman will attempt to display the results in the parent of the search popup. +.TP 1.5i +.B PopupHelp() +This action may be used anywhere, and will popup the help widget. +.TP 1.5i +.B PopupSearch() +This action may be used anywhere except in a help window. It will cause +the search popup to become active and visible on the screen, allowing +the user search for a manual page. +.TP 1.5i +.B CreateNewManpage() +This action may be used anywhere, and will create a new manual page +display window. +.TP 1.5i +.B RemoveThisManpage() +This action may be used in any manual page or help display window. When +called it will remove the window, and clean up all resources +associated with it. +.TP 1.5i +.B SaveFormattedPage(\fIaction\fP) +This action can only be used in the \fBlikeToSave\fP popup widget, and +tells xman whether to \fBSave\fP or \fBCancel\fP a save of the +manual page that has just been formatted. +.TP 1.5i +.B ShowVersion() +This action may be called from any manual page or help display window, and +will cause the informational display line to show the current version +of xman. +.SH FILES +.IP "\fI\fP/man<\fIcharacter\fP>" 2.5i +.IP "\fI\fP/cat<\fIcharacter\fP>" +.IP "\fI\fP/mandesc" +.IP __apploaddir__/Xman +specifies required resources. +.IP /tmp +.I Xman +creates temporary files in /tmp for all unformatted man pages and all apropos +searches. +.SH "SEE ALSO" +.IR X (__miscmansuffix__), +.IR man (1), +.IR apropos (1), +.IR catman (8), +.I "Athena Widget Set" +.SH ENVIRONMENT +.TP 1.5i +.B DISPLAY +the default host and display to use. +.TP 1.5i +.B MANPATH +the search path for manual pages. Directories are separated by +colons (e.g. /usr/man:/mit/kit/man:/foo/bar/man). +.TP 1.5i +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.TP 1.5i +.B XAPPLRESDIR +A string that will have ``Xman'' appended to it. This string will be +the full path name of a user app-defaults file to be merged into the +resource database after the system app-defaults file, and before +the resources that are attached to the display. +.br +See \fIX(__miscmansuffix__)\fP for a full statement of rights and permissions. +.SH AUTHORS +Chris Peterson, MIT X Consortium from the V10 version written by Barry +Shein formerly of Boston University. +Bug fixes and Linux support by Carlos A M dos Santos, for The XFree86 Project. diff --git a/xmodmap/AUTHORS b/xmodmap/AUTHORS new file mode 100644 index 0000000..ed2c04d --- /dev/null +++ b/xmodmap/AUTHORS @@ -0,0 +1,2 @@ +Jim Fulton, MIT X Consortium; derived from parts of the original +xmodmap, written by David Rosenthal, of Sun Microsystems. diff --git a/xmodmap/COPYING b/xmodmap/COPYING new file mode 100644 index 0000000..6bd6257 --- /dev/null +++ b/xmodmap/COPYING @@ -0,0 +1,53 @@ +Copyright 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + + + +Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright no- +tice appear in all copies and that both that copyright no- +tice and this permission notice appear in supporting docu- +mentation, and that the name of Sun not be used in +advertising or publicity pertaining to distribution of the +software without specific prior written permission. Sun +makes no representations about the suitability of this +software for any purpose. It is provided "as is" without any +express or implied warranty. + +SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- +NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI- +ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Author: Jim Fulton, MIT X Consortium; derived from parts of the +original xmodmap, written by David Rosenthal, of Sun Microsystems. diff --git a/xmodmap/INSTALL b/xmodmap/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xmodmap/Makefile.am b/xmodmap/Makefile.am new file mode 100644 index 0000000..4c2a2b2 --- /dev/null +++ b/xmodmap/Makefile.am @@ -0,0 +1,70 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xmodmap + +xmodmap_CFLAGS = $(DEP_CFLAGS) +xmodmap_LDADD = $(DEP_LIBS) + +xmodmap_SOURCES = \ + exec.c \ + handle.c \ + pf.c \ + wq.h \ + xmodmap.c \ + xmodmap.h + +appman_PRE = \ + xmodmap.man + +EXTRA_DIST = \ + swap.km + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST += $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xmodmap/NEWS b/xmodmap/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xmodmap/README b/xmodmap/README new file mode 100644 index 0000000..0568ddb --- /dev/null +++ b/xmodmap/README @@ -0,0 +1,5 @@ +The xmodmap program is used to edit and display the keyboard modifier +map and keymap table that are used by client applications to convert +event keycodes into keysyms. It is usually run from the user's +session startup script to configure the keyboard according to personal +tastes. diff --git a/xmodmap/config.h.in b/xmodmap/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/xmodmap/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xmodmap/mkinstalldirs b/xmodmap/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xmodmap/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xmodmap/pf.c b/xmodmap/pf.c new file mode 100644 index 0000000..99c20f7 --- /dev/null +++ b/xmodmap/pf.c @@ -0,0 +1,122 @@ +/* $Xorg: pf.c,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ +/* + +Copyright 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#include +#include +#include +#include +#include "xmodmap.h" + +#define NOTINFILEFILENAME "commandline" +char *inputFilename = NOTINFILEFILENAME; +int lineno = 0; + +void process_file (filename) + char *filename; /* NULL means use stdin */ +{ + FILE *fp; + char buffer[BUFSIZ]; + + /* open the file, eventually we'll want to pipe through cpp */ + + if (!filename) { + fp = stdin; + inputFilename = "stdin"; + } else { + fp = fopen (filename, "r"); + if (!fp) { + fprintf (stderr, "%s: unable to open file '%s' for reading\n", + ProgramName, filename); + parse_errors++; + return; + } + inputFilename = filename; + } + + + /* read the input and filter */ + + if (verbose) { + printf ("! %s:\n", inputFilename); + } + + for (lineno = 0; ; lineno++) { + buffer[0] = '\0'; + if (fgets (buffer, BUFSIZ, fp) == NULL) + break; + + process_line (buffer); + } + + inputFilename = NOTINFILEFILENAME; + lineno = 0; + (void) fclose (fp); +} + + +void process_line (buffer) + char *buffer; +{ + int len; + int i; + char *cp; + + /* copy buffer since it may point to unwritable date */ + len = strlen(buffer); + cp = chk_malloc(len + 1); + strcpy(cp, buffer); + buffer = cp; + + for (i = 0; i < len; i++) { /* look for blank lines */ + register char c = buffer[i]; + if (!(isspace(c) || c == '\n')) break; + } + if (i == len) return; + + cp = &buffer[i]; + + if (*cp == '!') return; /* look for comments */ + len -= (cp - buffer); /* adjust len by how much we skipped */ + + /* pipe through cpp */ + + /* strip trailing space */ + for (i = len-1; i >= 0; i--) { + register char c = cp[i]; + if (!(isspace(c) || c == '\n')) break; + } + if (i >= 0) cp[len = (i+1)] = '\0'; /* nul terminate */ + + if (verbose) { + printf ("! %d: %s\n", lineno+1, cp); + } + + /* handle input */ + handle_line (cp, len); +} diff --git a/xmodmap/swap.km b/xmodmap/swap.km new file mode 100644 index 0000000..64c55e5 --- /dev/null +++ b/xmodmap/swap.km @@ -0,0 +1,11 @@ +! +! Swap Caps_Lock and Control_L +! + +remove Lock = Caps_Lock +remove Control = Control_L +keysym Control_L = Caps_Lock +keysym Caps_Lock = Control_L +add Lock = Caps_Lock +add Control = Control_L + diff --git a/xmodmap/wq.h b/xmodmap/wq.h new file mode 100644 index 0000000..3aab10f --- /dev/null +++ b/xmodmap/wq.h @@ -0,0 +1,149 @@ +/* $Xorg: wq.h,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ +/* + +Copyright 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/xmodmap/wq.h,v 1.4 2001/01/17 23:46:21 dawes Exp $ */ + +#ifndef _WQ_H +#define _WQ_H + +/* + * Input is parsed and a work queue is built that is executed later. This + * allows us to swap keys as well as ensure that we don't mess up the keyboard + * by doing a partial rebind. + */ + +enum opcode { doKeycode, doAddModifier, doRemoveModifier, doClearModifier, + doPointer }; + +struct op_generic { + enum opcode type; /* oneof enum opcode */ + union op *next; /* next element in list or NULL */ +}; + + +/* + * keycode KEYCODE = KEYSYM + * keysym OLDKEYSYM = NEWKEYSYM + * + * want to eval the OLDKEYSYM before executing the work list so that it isn't + * effected by any assignments. + */ + +struct op_keycode { + enum opcode type; /* doKeycode */ + union op *next; /* next element in list or NULL */ + KeyCode target_keycode; /* key to which we are assigning */ + int count; /* number of new keysyms */ + KeySym *keysyms; /* new values to insert */ +}; + + +/* + * add MODIFIER = KEYSYM ... + */ + +struct op_addmodifier { + enum opcode type; /* doAddModifier */ + union op *next; /* next element in list or NULL */ + int modifier; /* index into modifier list */ + int count; /* number of keysyms */ + KeySym *keysyms; /* new values to insert */ +}; + + +/* + * remove MODIFIER = OLDKEYSYM ... + * + * want to eval the OLDKEYSYM before executing the work list so that it isn't + * effected by any assignments. + */ + +struct op_removemodifier { + enum opcode type; /* doRemoveModifier */ + union op *next; /* next element in list or NULL */ + int modifier; /* index into modifier list */ + int count; /* number of keysyms */ + KeyCode *keycodes; /* old values to remove */ +}; + + +/* + * clear MODIFIER + */ + +struct op_clearmodifier { + enum opcode type; /* doClearModifier */ + union op *next; /* next element in list or NULL */ + int modifier; /* index into modifier list */ +}; + +/* + * pointer = NUMBER ... + * + * set pointer map to the positive numbers given on the right hand side + */ + +#define MAXBUTTONCODES 256 /* there are eight bits of buttons */ + +struct op_pointer { + enum opcode type; /* doPointer */ + union op *next; /* next element in list or NULL */ + int count; /* number of new button codes */ + unsigned char button_codes[MAXBUTTONCODES]; +}; + + +/* + * all together now + */ +union op { + struct op_generic generic; + struct op_keycode keycode; + struct op_addmodifier addmodifier; + struct op_removemodifier removemodifier; + struct op_clearmodifier clearmodifier; + struct op_pointer pointer; +}; + +extern struct wq { + union op *head; + union op *tail; +} work_queue; + + +extern struct modtab { + char *name; + int length; + int value; +} modifier_table[]; + +#define AllocStruct(s) ((s *) malloc (sizeof (s))) + +#define MAXKEYSYMNAMESIZE 80 /* absurdly large */ + +#endif diff --git a/xmodmap/xmodmap.c b/xmodmap/xmodmap.c new file mode 100644 index 0000000..c59f07b --- /dev/null +++ b/xmodmap/xmodmap.c @@ -0,0 +1,359 @@ +/* $Xorg: xmodmap.c,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ +/* + +Copyright 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/xmodmap/xmodmap.c,v 1.8tsi Exp $ */ + +#include +#include +#include +#include +#include +#include "xmodmap.h" + +char *ProgramName; +Display *dpy = NULL; +int min_keycode, max_keycode; +Bool verbose = False; +Bool dontExecute = False; + +static void +Exit(int status) +{ + if (dpy) { + XCloseDisplay (dpy); + dpy = NULL; + } + exit (status); +} + +void * +chk_malloc(size_t n_bytes) +{ + void *buf = malloc(n_bytes); + if (!buf) { + fprintf(stderr, "%s: Could not allocate %d bytes\n", ProgramName, (int)n_bytes); + Exit(-1); + } + return buf; +} + +static char *help_message[] = { +"\nwhere options include:", +" -display host:dpy X server to use", +" -verbose, -quiet turn logging on or off", +" -n don't execute changes, just show like make", +" -e expression execute string", +" -pm print modifier map", +" -pk print keymap table", +" -pke print keymap table as expressions", +" -pp print pointer map", +" -grammar print out short help on allowable input", +" - read standard input", +"", +NULL}; + + +static void +usage(void) +{ + char **cpp; + + fprintf (stderr, "usage: %s [-options ...] [filename]\n", ProgramName); + for (cpp = help_message; *cpp; cpp++) { + fprintf (stderr, "%s\n", *cpp); + } + Exit (1); +} + +static char *grammar_message[] = { +" pointer = default reset pointer buttons to default", +" pointer = NUMBER ... set pointer button codes", +" keycode NUMBER = [KEYSYM ...] map keycode to given keysyms", +" keysym KEYSYM = [KEYSYM ...] look up keysym and do a keycode operation", +" clear MODIFIER remove all keys for this modifier", +" add MODIFIER = KEYSYM ... add the keysyms to the modifier", +" remove MODIFIER = KEYSYM ... remove the keysyms from the modifier", +"", +"where NUMBER is a decimal, octal, or hex constant; KEYSYM is a valid", +"Key Symbol name; and MODIFIER is one of the eight modifier names: Shift,", +"Lock, Control, Mod1, Mod2, Mod3, Mod4, or Mod5. Lines beginning with", +"an exclamation mark (!) are taken as comments. Case is significant except", +"for MODIFIER names.", +"", +"Keysyms on the left hand side of the = sign are looked up before any changes", +"are made; keysyms on the right are looked up after all of those on the left", +"have been resolved. This makes it possible to swap modifier keys.", +"", +NULL }; + + +static void +grammar_usage(void) +{ + char **cpp; + + fprintf (stderr, "%s accepts the following input expressions:\n\n", + ProgramName); + for (cpp = grammar_message; *cpp; cpp++) { + fprintf (stderr, "%s\n", *cpp); + } + Exit (0); +} + +int parse_errors = 0; + +int +main(int argc, char *argv[]) +{ + int i; + char *displayname = NULL; + int status; + Bool printMap = False; + Bool printKeyTable = False; + Bool printKeyTableExprs = False; + Bool printPointerMap = False; + Bool didAnything = False; + + ProgramName = argv[0]; + + /* + * scan the arg list once to find out which display to use + */ + + for (i = 1; i < argc; i++) { + if (strncmp (argv[i], "-d", 2) == 0) { + if (++i >= argc) usage (); + displayname = argv[i]; + } + } + + dpy = XOpenDisplay (displayname); + if (!dpy) { + fprintf (stderr, "%s: unable to open display '%s'\n", + ProgramName, XDisplayName (displayname)); + Exit (1); + } + + XDisplayKeycodes (dpy, &min_keycode, &max_keycode); + + initialize_map (); + + /* + * scan the arg list again to do the actual work (since it requires + * the display being open. + */ + + status = 0; + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (arg[0] == '-') { + switch (arg[1]) { + case 'd': /* -display host:dpy */ + ++i; /* handled above */ + continue; + case 'v': /* -verbose */ + verbose = True; + continue; + case 'q': /* -quiet */ + verbose = False; + continue; + case 'n': /* -n (like make) */ + dontExecute = True; + continue; + case 'e': /* -e expression */ + didAnything = True; + if (++i >= argc) usage (); + process_line (argv[i]); + continue; + case 'p': /* -p... */ + switch (arg[2]) { + case '\0': + case 'm': /* -pm */ + printMap = True; + break; + case 'k': /* -pk, -pke */ + switch (arg[3]) { + case '\0': + printKeyTable = True; + break; + case 'e': + printKeyTableExprs = True; + break; + default: + usage (); + } + break; + case 'p': /* -pp */ + printPointerMap = True; + break; + default: + usage (); + /* NOTREACHED */ + } + didAnything = True; + continue; + case 'g': /* -grammar */ + grammar_usage (); + /*NOTREACHED*/ + case '\0': /* - (use standard input) */ + didAnything = True; + process_file (NULL); + continue; + + /* + * provide old xmodmap args + */ + case 'S': + didAnything = True; + process_line ("clear shift"); + continue; + case 'L': + didAnything = True; + process_line ("clear lock"); + continue; + case 'C': + didAnything = True; + process_line ("clear control"); + continue; + case '1': + case '2': + case '3': + case '4': + case '5': { + char cmd[11] = "clear modX"; + cmd[9] = arg[1]; + process_line (cmd); + continue; + } + case 's': + case 'l': + case 'c': { + char *cmd; + didAnything = True; + if (++i >= argc) usage (); + cmd = chk_malloc (strlen ("remove control = ") + strlen (argv[i]) + 1); + (void) sprintf (cmd, "remove %s = %s", + ((arg[1] == 's') ? "shift" : + ((arg[1] == 'l') ? "lock" : + "control")), argv[i]); + process_line (cmd); + continue; + } + default: + usage (); + /*NOTREACHED*/ + } + } else if (arg[0] == '+') { /* old xmodmap args */ + switch (arg[1]) { + case '1': + case '2': + case '3': + case '4': + case '5': { + char *cmd; + didAnything = True; + if (++i >= argc) usage (); + cmd = chk_malloc (strlen ("add modX = ") + strlen (argv[i]) + 1); + (void) sprintf (cmd, "add mod%c = %s", arg[1], argv[i]); + process_line (cmd); + continue; + } + case 'S': + case 'L': + case 'C': + arg[1] = tolower (arg[1]); + /* fall through to handler below */ + case 's': + case 'l': + case 'c': { + char *cmd; + didAnything = True; + if (++i >= argc) usage (); + cmd = chk_malloc (strlen ("add control = ") + strlen (argv[i]) + 1); + (void) sprintf (cmd, "add %s = %s", + ((arg[1] == 's') ? "shift" : + ((arg[1] == 'l') ? "lock" : + "control")), argv[i]); + process_line (cmd); + continue; + } + default: + usage (); + } + } else { + didAnything = True; + process_file (arg); + continue; + } + } /* end for loop */ + + /* for compatibility */ + if (!didAnything) printMap = True; + + /* + * at this point, the work list has been built and we can view it or + * execute it + */ + + if (dontExecute) { + print_work_queue (); + Exit (0); + } + + if (parse_errors != 0) { + fprintf (stderr, "%s: %d error%s encountered, aborting.\n", + ProgramName, parse_errors, + (parse_errors == 1 ? "" : "s")); + status = -1; /* return an error condition */ + } else { + status = execute_work_queue (); + } + + if (printMap) { + print_modifier_map (); + } + + if (printKeyTable) { + print_key_table (False); + } + + if (printKeyTableExprs) { + print_key_table (True); + } + + if (printPointerMap) { + print_pointer_map (); + } + + Exit (status < 0 ? 1 : 0); + + /* Muffle gcc */ + return 0; +} + diff --git a/xmodmap/xmodmap.h b/xmodmap/xmodmap.h new file mode 100644 index 0000000..d52ef5e --- /dev/null +++ b/xmodmap/xmodmap.h @@ -0,0 +1,60 @@ +/* $Xorg: xmodmap.h,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ */ +/* + +Copyright 1988, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/xmodmap/xmodmap.h,v 1.4 2001/01/17 23:46:21 dawes Exp $ */ + +extern char *ProgramName; +extern Display *dpy; +extern int min_keycode, max_keycode; +extern Bool verbose; +extern Bool dontExecute; +extern char *inputFilename; +extern int lineno; +extern int parse_errors; + +extern void initialize_map(void); +extern void process_file(char *filename); +extern void process_line(char *buffer); +extern void handle_line(char *line, int len); +extern void print_work_queue(void); +extern int execute_work_queue(void); +extern void print_modifier_map(void); +extern void print_key_table(Bool exprs); +extern void print_pointer_map(void); + +extern int UpdateModifierMapping(XModifierKeymap *map); +extern int AddModifier(XModifierKeymap **mapp, KeyCode keycode, int modifier); +extern int RemoveModifier(XModifierKeymap **mapp, KeyCode keycode, + int modifier); +extern int ClearModifier(XModifierKeymap **mapp, int modifier); +extern void PrintModifierMapping(XModifierKeymap *map, FILE *fp); +extern void PrintKeyTable(Bool exprs, FILE *fp); +extern void PrintPointerMap(FILE *fp); +extern int SetPointerMap(unsigned char *map, int n); + +extern void *chk_malloc(size_t n_bytes); diff --git a/xmodmap/xmodmap.man b/xmodmap/xmodmap.man new file mode 100644 index 0000000..17425e8 --- /dev/null +++ b/xmodmap/xmodmap.man @@ -0,0 +1,308 @@ +.\" $Xorg: xmodmap.man,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ +.\" Copyright 1988, 1989, 1990, 1998 The Open Group +.\" Copyright 1987 Sun Microsystems, Inc. +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/xmodmap/xmodmap.man,v 1.11 2002/10/12 16:06:48 herrb Exp $ +.\" +.de EX \"Begin example +.ne 5 +.if n .sp 1 +.if t .sp .5 +.nf +.in +.5i +.. +.de EE +.fi +.in -.5i +.if n .sp 1 +.if t .sp .5 +.. +.TH XMODMAP 1 __xorgversion__ +.SH NAME +xmodmap - utility for modifying keymaps and pointer button mappings in X +.SH SYNOPSIS +.B xmodmap +[-options ...] [filename] +.SH DESCRIPTION +.PP +The \fIxmodmap\fP program is used to edit and display the +keyboard \fImodifier map\fP and \fIkeymap table\fP that are used by client +applications to convert event keycodes into keysyms. It is usually run from +the user's session startup script to configure the keyboard according to +personal tastes. +.SH OPTIONS +.PP +The following options may be used with \fIxmodmap\fP: +.TP 8 +.B \-display \fIdisplay\fP +This option specifies the host and display to use. +.TP 8 +.B \-help +This option indicates that a brief description of the command line arguments +should be printed on the standard error channel. This will be done whenever an +unhandled argument is given to +.I xmodmap. +.TP 8 +.B \-grammar +This option indicates that a help message describing the expression grammar +used in files and with \-e expressions should be printed on the standard error. +.TP 8 +.B \-verbose +This option indicates that +.I xmodmap +should print logging information as it parses its input. +.TP 8 +.B \-quiet +This option turns off the verbose logging. This is the default. +.TP 8 +.B \-n +This option indicates that +.I xmodmap +should not change the mappings, but should display what it would do, like +\fImake(1)\fP does when given this option. +.TP 8 +.B \-e \fIexpression\fB +This option specifies an expression to be executed. Any number of expressions +may be specified from the command line. +.TP 8 +.B \-pm +This option indicates that the current modifier map should be printed on the +standard output. +.TP 8 +.B \-pk +This option indicates that the current keymap table should be printed on the +standard output. +.TP 8 +.B \-pke +This option indicates that the current keymap table should be printed on the +standard output in the form of expressions that can be fed back to +\fIxmodmap\fP. +.TP 8 +.B \-pp +This option indicates that the current pointer map should be printed on the +standard output. +.TP 8 +.B \- +A lone dash means that the standard input should be used as the input file. +.PP +The \fIfilename\fP specifies a file containing \fIxmodmap\fP expressions +to be executed. This file is usually kept in the user's home directory with +a name like \fI.xmodmaprc\fP. +.SH EXPRESSION GRAMMAR +.PP +The +.I xmodmap +program reads a list of expressions and parses them all before attempting +to execute any of them. This makes it possible to refer to keysyms that are +being redefined in a natural way without having to worry as much about name +conflicts. +.TP 8 +.B keycode \fINUMBER\fP = \fIKEYSYMNAME ...\fP +The list of keysyms is assigned to the indicated keycode +(which may be specified in decimal, hex or octal and can be determined by +running the +.I xev +program). Up to eight keysyms may be attached to a key, however the last four +are not used in any major X server implementation. The first keysym is used +when no modifier key is pressed in conjunction with this key, the second with +Shift, the third when the Mode_switch key is used with this key and the fourth +when both the Mode_switch and Shift keys are used. +.TP 8 +.B keycode any = \fIKEYSYMNAME ...\fP +If no existing key has the specified list of keysyms assigned to it, +a spare key on the keyboard is selected and the keysyms are assigned to it. +The list of keysyms may be specified in decimal, hex or octal. +.TP 8 +.B keysym \fIKEYSYMNAME\fP = \fIKEYSYMNAME ...\fP +The \fIKEYSYMNAME\fP on the left hand side is translated into matching keycodes +used to perform the corresponding set of \fBkeycode\fP expressions. +The list of keysym names may be +found in the header file \fI\fP (without the \fIXK_\fP prefix) +or the keysym database\fI __projectroot__/lib/X11/XKeysymDB\fP. Note that +if the same keysym is bound to multiple keys, the expression is executed +for each matching keycode. +.TP 8 +.B clear \fIMODIFIERNAME\fP +This removes all entries in the modifier map for the given modifier, where +valid name are: +.BR Shift , +.BR Lock , +.BR Control , +.BR Mod1 , +.BR Mod2 , +.BR Mod3 , +.BR Mod4 , +and \fBMod5\fP (case +does not matter in modifier names, although it does matter for all other +names). For example, ``clear Lock'' will remove +all any keys that were bound to the shift lock modifier. +.TP 8 +.B add \fIMODIFIERNAME\fP = \fIKEYSYMNAME ...\fP +This adds all keys containing the given keysyms to the indicated modifier map. +The keysym names +are evaluated after all input expressions are read to make it easy to write +expressions to swap keys (see the EXAMPLES section). +.TP 8 +.B remove \fIMODIFIERNAME\fP = \fIKEYSYMNAME ...\fP +This removes all keys containing the given keysyms from the indicated +modifier map. Unlike +.B add, +the keysym names are evaluated as the line is read in. This allows you to +remove keys from a modifier without having to worry about whether or not they +have been reassigned. +.TP 8 +.B "pointer = default" +This sets the pointer map back to its default settings (button 1 generates a +code of 1, button 2 generates a 2, etc.). +.TP 8 +.B pointer = \fINUMBER ...\fP +This sets the pointer map to contain the indicated button codes. The list +always starts with the first physical button. +.PP +Lines that begin with an exclamation point (!) are taken as comments. +.PP +If you want to change the binding of a modifier key, you must also remove it +from the appropriate modifier map. +.SH EXAMPLES +.PP +Many pointers are designed such that the first button is pressed using the +index finger of the right hand. People who are left-handed frequently find +that it is more comfortable to reverse the button codes that get generated +so that the primary button is pressed using the index finger of the left hand. +This could be done on a 3 button pointer as follows: +.EX +% xmodmap -e "pointer = 3 2 1" +.EE +.PP +Many applications support the notion of Meta keys (similar to Control +keys except that Meta is held down instead of Control). However, +some servers do not have a Meta keysym in the default keymap table, so one +needs to be added by hand. +The following command will attach Meta to the Multi-language key (sometimes +labeled Compose Character). It also takes advantage of the fact that +applications that need a Meta key simply need to get the keycode and don't +require the keysym to be in the first column of the keymap table. This +means that applications that are looking for a Multi_key (including the +default modifier map) won't notice any change. +.EX +% xmodmap -e "keysym Multi_key = Multi_key Meta_L" +.EE +.PP +Similarly, some keyboards have an Alt key but no Meta key. +In that case the following may be useful: +.EX +% xmodmap -e "keysym Alt_L = Meta_L Alt_L" +.EE +.PP +One of the more simple, yet convenient, uses of \fIxmodmap\fP is to set the +keyboard's "rubout" key to generate an alternate keysym. This frequently +involves exchanging Backspace with Delete to be more comfortable to the user. +If the \fIttyModes\fP resource in \fIxterm\fP is set as well, all terminal +emulator windows will use the same key for erasing characters: +.EX +% xmodmap -e "keysym BackSpace = Delete" +% echo "XTerm*ttyModes: erase ^?" | xrdb -merge +.EE +.PP +Some keyboards do not automatically generate less than and greater than +characters when the comma and period keys are shifted. This can be remedied +with \fIxmodmap\fP by resetting the bindings for the comma and period with +the following scripts: +.EX +! +! make shift-, be < and shift-. be > +! +keysym comma = comma less +keysym period = period greater +.EE +.PP +One of the more irritating differences between keyboards is the location of the +Control and Shift Lock keys. A common use of \fIxmodmap\fP is to swap these +two keys as follows: +.EX +! +! Swap Caps_Lock and Control_L +! +remove Lock = Caps_Lock +remove Control = Control_L +keysym Control_L = Caps_Lock +keysym Caps_Lock = Control_L +add Lock = Caps_Lock +add Control = Control_L +.EE +.PP +The \fIkeycode\fP command is useful for assigning the same keysym to +multiple keycodes. Although unportable, it also makes it possible to write +scripts that can reset the keyboard to a known state. The following script +sets the backspace key to generate Delete (as shown above), flushes all +existing caps lock bindings, makes the CapsLock +key be a control key, make F5 generate Escape, and makes Break/Reset be a +shift lock. +.EX +! +! On the HP, the following keycodes have key caps as listed: +! +! 101 Backspace +! 55 Caps +! 14 Ctrl +! 15 Break/Reset +! 86 Stop +! 89 F5 +! +keycode 101 = Delete +keycode 55 = Control_R +clear Lock +add Control = Control_R +keycode 89 = Escape +keycode 15 = Caps_Lock +add Lock = Caps_Lock +.EE +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get default host and display number. +.SH SEE ALSO +X(__miscmansuffix__), xev(1), \fIXlib\fP documentation on key and pointer events +.SH BUGS +.PP +Every time a \fBkeycode\fP expression is evaluated, the server generates +a \fIMappingNotify\fP event on every client. This can cause some thrashing. +All of the changes should be batched together and done at once. +Clients that receive keyboard input and ignore \fIMappingNotify\fP events +will not notice any changes made to keyboard mappings. +.PP +.I Xmodmap +should generate "add" and "remove" expressions automatically +whenever a keycode that is already bound to a modifier is changed. +.PP +There should be a way to have the +.I remove +expression accept keycodes as well as keysyms for those times when you really +mess up your mappings. +.SH AUTHOR +Jim Fulton, MIT X Consortium, rewritten from an earlier version by +David Rosenthal of Sun Microsystems. + diff --git a/xrandr/AUTHORS b/xrandr/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xrandr/COPYING b/xrandr/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xrandr/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xrandr/INSTALL b/xrandr/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xrandr/Makefile.am b/xrandr/Makefile.am new file mode 100644 index 0000000..178585d --- /dev/null +++ b/xrandr/Makefile.am @@ -0,0 +1,62 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xrandr + +xrandr_CFLAGS = $(XRANDR_CFLAGS) +xrandr_LDADD = $(XRANDR_LIBS) + +xrandr_SOURCES = \ + xrandr.c + +appman_PRE = \ + xrandr.man + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xrandr/NEWS b/xrandr/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xrandr/README b/xrandr/README new file mode 100644 index 0000000..e69de29 diff --git a/xrandr/config.h.in b/xrandr/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/xrandr/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xrandr/mkinstalldirs b/xrandr/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xrandr/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xrandr/xrandr.man b/xrandr/xrandr.man new file mode 100644 index 0000000..2e1d114 --- /dev/null +++ b/xrandr/xrandr.man @@ -0,0 +1,74 @@ +.\" +.\" Copyright 2001 Keith Packard.\" +.\" 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, and that the name of Keith Packard not be used in +.\" advertising or publicity pertaining to distribution of the software without +.\" specific, written prior permission. Keith Packard makes no +.\" representations about the suitability of this software for any purpose. It +.\" is provided "as is" without express or implied warranty. +.\" +.\" KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +.\" EVENT SHALL KEITH PACKARD 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. +.\" +.\" +.\" $XFree86: xc/programs/xrandr/xrandr.man,v 1.6 2003/06/12 14:12:39 eich Exp $ +.\" +.TH XRANDR __appmansuffix__ __vendorversion__ +.SH NAME +xrandr \- primitive command line interface to RandR extension +.SH SYNOPSIS +.B "xrandr" +[-help] [-display \fIdisplay\fP] +[-o \fIorientation\fP] +[-q] [-v] +[-s \fIsize\fP] +[-x] [-y] +[--screen \fIsnum\fP] +[--verbose] +.SH DESCRIPTION +.I Xrandr +is used to set the screen size, orientation and/or reflection. +The +.I -s +option is a small integer index used to specify which size the screen should be set to. +To find out what sizes are available, use the +.I -q +option, which reports the sizes available, the current rotation, and +the possible rotations and reflections. +The default size is the first size specified in the list. +The +.I -o +option is used to specify the orientation of the screen, +and can be one of +\fI"normal inverted left right 0 1 2 3"\fP. +.PP +The +.I -x +option instructs the server to reflect the screen on the X axis. +The +.I -y +option instructs the server to reflect the screen on the Y axis. +Reflection is applied after rotation. +.PP +The +.I -help +option prints out a usage summary. +The +.I --verbose +option tells you what xrandr is doing, selects for events, and tells you +when events are received to enable debugging. +.SH "SEE ALSO" +Xrandr(3) +.SH AUTHORS +Keith Packard, +and +Jim Gettys, +Cambridge Research Laboratory, HP Labs, HP. diff --git a/xrdb/COPYING b/xrdb/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xrdb/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xrdb/INSTALL b/xrdb/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xrdb/Makefile.am b/xrdb/Makefile.am new file mode 100644 index 0000000..4e379af --- /dev/null +++ b/xrdb/Makefile.am @@ -0,0 +1,62 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xrdb + +xrdb_CFLAGS = $(XRDB_CFLAGS) +xrdb_LDADD = $(XRDB_LIBS) + +xrdb_SOURCES = \ + xrdb.c + +appman_PRE = \ + xrdb.man + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xrdb/NEWS b/xrdb/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xrdb/README b/xrdb/README new file mode 100644 index 0000000..e69de29 diff --git a/xrdb/mkinstalldirs b/xrdb/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xrdb/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xrefresh/AUTHORS b/xrefresh/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xrefresh/COPYING b/xrefresh/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xrefresh/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xrefresh/INSTALL b/xrefresh/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xrefresh/Makefile.am b/xrefresh/Makefile.am new file mode 100644 index 0000000..1434adc --- /dev/null +++ b/xrefresh/Makefile.am @@ -0,0 +1,63 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xrefresh + +xrefresh_CFLAGS = $(XREFRESH_CFLAGS) +xrefresh_LDADD = $(XREFRESH_LIBS) + +xrefresh_SOURCES = \ + xrefresh.c + +appman_PRE = \ + xrefresh.man + + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xrefresh/NEWS b/xrefresh/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xrefresh/README b/xrefresh/README new file mode 100644 index 0000000..e69de29 diff --git a/xrefresh/config.h.in b/xrefresh/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/xrefresh/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xrefresh/mkinstalldirs b/xrefresh/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xrefresh/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xrefresh/xrefresh.man b/xrefresh/xrefresh.man new file mode 100644 index 0000000..4030c1e --- /dev/null +++ b/xrefresh/xrefresh.man @@ -0,0 +1,104 @@ +.\" $Xorg: xrefresh.man,v 1.4 2001/02/09 02:05:56 xorgcvs Exp $ +.\" Copyright 1988, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/xrefresh/xrefresh.man,v 1.7 2001/01/27 18:21:22 dawes Exp $ +.\" +.TH XREFRESH 1 __xorgversion__ +.SH NAME +xrefresh - refresh all or part of an X screen +.SH SYNOPSIS +.B "xrefresh" +[-option ...] +.SH DESCRIPTION +.PP +.I Xrefresh +is a simple X program that causes all or part of your screen to be repainted. +This is useful when system messages have messed up your screen. +.I Xrefresh +maps a window on top of the desired area of the screen and then immediately +unmaps it, +causing refresh events to be sent to all applications. By default, +a window with no background is used, causing all applications to repaint +``smoothly.'' +However, the various options can be used to indicate that a solid background +(of any color) or the root window background should be used instead. +.SH ARGUMENTS +.PP +.TP 10 +.B \-white +Use a white background. The screen just appears to flash quickly, and then +repaint. +.PP +.TP 10 +.B \-black +Use a black background (in effect, turning off all of the electron guns to +the tube). This can be somewhat disorienting as everything goes black for +a moment. +.PP +.TP 10 +.B \-solid \fIcolor\fP +Use a solid background of the specified color. Try green. +.PP +.TP 10 +.B \-root +Use the root window background. +.PP +.TP 10 +.B \-none +This is the default. All of the windows simply repaint. +.PP +.TP 10 +.B \-geometry \fIWxH+X+Y\fP +Specifies the portion of the screen to be repainted; see \fIX(__miscmansuffix__)\fP. +.PP +.TP 10 +.B \-display \fIdisplay\fP +This argument allows you to specify the server and screen to +refresh; see \fIX(__miscmansuffix__)\fP. +.SH X DEFAULTS +The +.I xrefresh +program uses the routine +.I XGetDefault(3X) +to read defaults, so its resource names are all capitalized. +.PP +.TP 8 +.B Black\fP, \fBWhite\fP, \fBSolid\fP, \fBNone\fP, \fBRoot\fP +Determines what sort of window background to use. +.PP +.TP 8 +.B Geometry +Determines the area to refresh. Not very useful. +.SH ENVIRONMENT +.PP +.TP 8 +DISPLAY - To get default host and display number. +.SH SEE ALSO +X(__miscmansuffix__) +.SH BUGS +.PP +It should have just one default type for the background. +.SH AUTHORS +Jim Gettys, Digital Equipment Corp., MIT Project Athena diff --git a/xset/AUTHORS b/xset/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xset/COPYING b/xset/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xset/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xset/INSTALL b/xset/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xset/Makefile.am b/xset/Makefile.am new file mode 100644 index 0000000..ababd43 --- /dev/null +++ b/xset/Makefile.am @@ -0,0 +1,63 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xset + +xset_CFLAGS = $(XSET_CFLAGS) -D_BSD_SOURCE +xset_LDADD = $(XSET_LIBS) + +xset_SOURCES = \ + xset.c + +appman_PRE = \ + xset.man + + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xset/NEWS b/xset/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xset/README b/xset/README new file mode 100644 index 0000000..e69de29 diff --git a/xset/config.h.in b/xset/config.h.in new file mode 100644 index 0000000..727aedd --- /dev/null +++ b/xset/config.h.in @@ -0,0 +1,46 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_DPMS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_FONTCACHEP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_FONTCACHE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_MITMISC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_PRINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_XF86MISC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_EXTENSIONS_XF86MSCSTR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_XKBLIB_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xset/mkinstalldirs b/xset/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xset/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xset/xset.man b/xset/xset.man new file mode 100644 index 0000000..9c204aa --- /dev/null +++ b/xset/xset.man @@ -0,0 +1,255 @@ +.\" $Xorg: xset.man,v 1.4 2001/02/09 02:05:59 xorgcvs Exp $ +.\" Copyright 1988, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xc/programs/xset/xset.man,v 3.14 2001/12/14 20:02:22 dawes Exp $ +.\" +.TH XSET 1 __xorgversion__ +.SH NAME +xset - user preference utility for X +.SH SYNOPSIS +.B xset +[-display \fIdisplay\fP] +[-b] [b on/off] [b [\fIvolume\fP [\fIpitch\fP [\fIduration\fP]]] +[[-]bc] +[-c] [c on/off] [c [\fIvolume\fP]] +[[+-]dpms] [dpms \fIstandby\fP [\fI suspend\fP [\fI off\fP]]] [dpms force standby/suspend/off/on] +[[-+]fp[-+=] \fIpath\fP[,\fIpath\fP[,...]]] [fp default] [fp rehash] +[[-]led [\fIinteger\fP]] [led on/off] +[m[ouse] [\fIaccel_mult\fP[/\fIaccel_div\fP] [\fIthreshold\fP]]] [m[ouse] default] +[p \fIpixel\fP \fIcolor\fP] +[[-]r [keycode]] [r on/off] [r rate \fIdelay\fP [\fIrate\fP]] +[s [\fIlength\fP [\fIperiod\fP]]] [s blank/noblank] +[s expose/noexpose] [s on/off] [s default] [s activate] [s reset] +[q] +.SH DESCRIPTION +This program is used to set various user preference options of the display. +.SH OPTIONS +.PP +.TP 8 +.B \-display \fIdisplay\fP +This option specifies the server to use; see \fIX(__miscmansuffix__)\fP. +.PP +.TP 8 +.B b +The \fBb\fP option controls bell volume, pitch and duration. +This option accepts up to three numerical parameters, a preceding +dash(-), or a 'on/off' flag. If no parameters are +given, or the 'on' flag is used, the system defaults will be used. +If the dash or 'off' are given, the bell will be turned +off. +If only one numerical parameter is given, the +bell volume will be set to that value, as a percentage of its maximum. +Likewise, the second numerical +parameter specifies the bell pitch, in hertz, and +the third numerical parameter +specifies the duration in milliseconds. Note that not +all hardware can vary the bell characteristics. The X server will set +the characteristics of the bell as closely as it can to the user's +specifications. +.PP +.TP 8 +.B bc +The \fBbc\fP option controls \fIbug compatibility\fP mode in the server, +if possible; a preceding dash(-) disables the mode, otherwise the mode +is enabled. Various pre-R4 clients pass illegal values in some +protocol requests, and pre-R4 servers did not correctly generate +errors in these cases. Such clients, when run against an R4 server, +will terminate abnormally or otherwise fail to operate correctly. +Bug compatibility mode explicitly reintroduces certain bugs into the +X server, so that many such clients can still be run. This mode should be +used with care; new application development should be done with this mode +disabled. The server must support the MIT-SUNDRY-NONSTANDARD +protocol extension in order for this option to work. +.TP 8 +.B c +The \fBc\fP option controls key click. +This option can take an optional value, a preceding dash(-), +or an 'on/off' flag. +If no parameter or the 'on' flag is given, the system defaults +will be used. If the dash or 'off' flag is used, keyclick will be +disabled. +If a value from 0 to 100 is given, it is used to +indicate volume, as a percentage of the maximum. +The X server will set +the volume to the nearest value that the hardware can support. +.PP +.TP 8 +.B \-dpms +The \fB\-dpms\fP option disables DPMS (Energy Star) features. +.TP 8 +.B +dpms +The \fB+dpms\fP option enables DPMS (Energy Star) features. +.TP 8 +.B dpms \fIflags...\fP +The \fBdpms\fP option allows the DPMS (Energy Star) parameters to be +set. The option can take up to three numerical values, or the `force' +flag followed by a DPMS state. The `force' flags forces the server +to immediately switch to the DPMS state specified. The DPMS state can +be one of `standby', `suspend', `off', or `on'. When numerical values are +given, they set the inactivity period +(in units of seconds) +before the three modes are activated. +The first value given is for the `standby' mode, the second is for the +`suspend' mode, and the third is for the `off' mode. Setting these +values implicitly enables the DPMS features. A value of zero disables +a particular mode. +.TP 8 +.B fp= \fIpath,...\fP +The \fBfp=\fP sets the font path to the entries given in the path argument. +The entries are interpreted by the server, not by the client. +Typically they are directory names or font server names, but the +interpretation is server-dependent. +.TP 8 +.B fp \fBdefault\fP +The \fBdefault\fP argument causes the font path to be reset to the server's +default. +.TP 8 +.B fp \fBrehash\fP +The \fBrehash\fP argument resets the font path to its current value, +causing the server to reread the font databases in +the current font path. This is generally only used when adding new fonts to +a font directory (after running \fImkfontdir\fP to recreate the font database). +.PP +.TP 8 +.B "\-fp \fRor\fP fp\-" +The \fB\-fp\fP and \fBfp\-\fP options remove elements from the current +font path. They must be followed by a comma-separated list of entries. +.PP +.TP 8 +.B "\+fp \fRor\fP fp\+" +This \fB\+fp\fP and \fBfp\+\fP options prepend and append elements to the +current font path, respectively. They must be followed by a comma-separated +list of entries. +.PP +.TP 8 +.B led +The \fBled\fP option controls the keyboard LEDs. +This controls the turning on or off of one or all of the LEDs. +It accepts an optional integer, a preceding dash(-) or an 'on/off' flag. +If no parameter or the 'on' flag is given, all LEDs are turned on. +If a preceding dash or the flag 'off' is given, all LEDs are turned off. +If a value between 1 and 32 is given, that LED will be turned on or off +depending on the existence of a preceding dash. +A common LED which can be controlled is the ``Caps Lock'' LED. ``xset +led 3'' would turn led #3 on. ``xset -led 3'' would turn it off. +The particular LED values may refer to different LEDs on different +hardware. +.PP +.TP 8 +.B m +The \fBm\fP option controls the mouse parameters. +The parameters for the mouse are `acceleration' and `threshold'. +The acceleration can be specified as an integer, or as a simple +fraction. +The mouse, or whatever pointer the machine is connected to, +will go `acceleration' times as fast when it travels more than `threshold' +pixels in a short time. This way, the mouse can be used for precise +alignment when it is moved slowly, yet it can be set to travel across +the screen in a flick of the wrist when desired. One or both +parameters for the +.B m +option can be omitted, but if only one is +given, it will be interpreted as the acceleration. +If no parameters or the flag 'default' is used, the system defaults will +be set. +.PP +.TP 8 +.B p +The \fBp\fP option controls pixel color values. +The parameters are the color map entry number in decimal, +and a color specification. The root background colors may be changed +on some servers by altering the entries for BlackPixel and WhitePixel. +Although these are often 0 and 1, they need not be. Also, a server may +choose to allocate those colors privately, in which case an error will +be generated. The map entry must not be a read-only color, +or an error will result. +.PP +.TP 8 +.B r +The \fBr\fP option controls the autorepeat. +Invoking with "\fB-r\fP", or "\fBr\ off\fP", will disable autorepeat, whereas +"\fBr\fP", or "\fBr\ on\fP" will enable autorepeat. +Following the "\fB-r\fP" or "\fBr\fP" option with an integer keycode between 0 and +255 will disable or enable autorepeat on that key respectively, but only +if it makes sense for the particular keycode. Keycodes below 8 are +not typically valid for this command. Example: "\fBxset\ -r\ 10\fP" will +disable autorepeat for the "1" key on the top row of an IBM PC keyboard. + +If the server supports the XFree86-Misc extension, or the XKB extension, +then a parameter +of 'rate' is accepted and should be followed by zero, one or two numeric +values. The first specifies the delay before autorepeat starts and +the second specifies the repeat rate. In the case that the server +supports the XKB extension, the delay is the number of milliseconds +before autorepeat starts, and the rate is the number of repeats +per second. If the rate or delay is not given, it will be set +to the default value. +.PP +.TP 8 +.B s +The \fBs\fP option lets you set the screen saver parameters. +This option accepts up to two numerical parameters, a 'blank/noblank' +flag, an 'expose/noexpose' flag, an 'on/off' flag, an 'activate/reset' flag, +or the 'default' flag. +If no parameters or the 'default' flag is used, the system will be set +to its default screen saver characteristics. +The 'on/off' flags simply turn the screen saver functions on or off. +The 'activate' flag forces activation of screen saver even if the screen +saver had been turned off. +The 'reset' flag forces deactivation of screen saver if it is active. +The 'blank' flag sets the +preference to blank the video (if the hardware can do so) rather than +display a background pattern, while 'noblank' sets the +preference to display a pattern rather than blank the video. +The 'expose' flag sets the +preference to allow window exposures (the server can freely discard +window contents), while 'noexpose' sets the preference to disable +screen saver unless the server can regenerate the screens without +causing exposure events. +The length and period +parameters for the screen saver function determines how long the +server must be inactive for screen saving to activate, and the period +to change the background pattern to avoid burn in. +The arguments are specified in seconds. +If only one numerical parameter is given, it will be used for the length. +.PP +.TP 8 +.B q +The \fBq\fP option gives you information on the current settings. +.PP +These settings will be reset to default values when you log out. +.PP +Note that not all X implementations are guaranteed to honor all of these +options. +.SH "SEE ALSO" +X(__miscmansuffix__), Xserver(1), xmodmap(1), xrdb(1), xsetroot(1) +.SH AUTHOR +Bob Scheifler, MIT Laboratory for Computer Science +.br +David Krikorian, MIT Project Athena (X11 version) +.br +XFree86-Misc support added by David Dawes and Joe Moss +.br +Manpage updates added by Mike A. Harris diff --git a/xwininfo/AUTHORS b/xwininfo/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/xwininfo/COPYING b/xwininfo/COPYING new file mode 100644 index 0000000..7f33cbf --- /dev/null +++ b/xwininfo/COPYING @@ -0,0 +1,12 @@ +This is a stub file. This package has not yet had its complete licensing +information compiled. Please see the individual source files for details on +your rights to use and modify this software. + +Please submit updated COPYING files to the Xorg bugzilla: + +https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +All licensing questions regarding this software should be directed at the +Xorg mailing list: + +http://lists.freedesktop.org/mailman/listinfo/xorg diff --git a/xwininfo/INSTALL b/xwininfo/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/xwininfo/Makefile.am b/xwininfo/Makefile.am new file mode 100644 index 0000000..d5bb27c --- /dev/null +++ b/xwininfo/Makefile.am @@ -0,0 +1,65 @@ +# +# Copyright 2005 Red Hat, Inc. +# +# 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, and that the name of Red Hat not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Red Hat makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL RED HAT 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. + +bin_PROGRAMS = xwininfo + +xwininfo_CFLAGS = $(XWININFO_CFLAGS) +xwininfo_LDADD = $(XWININFO_LIBS) + +xwininfo_SOURCES = \ + dsimple.c \ + dsimple.h \ + xwininfo.c + +appman_PRE = \ + xwininfo.man + + +appmandir = $(APP_MAN_DIR) + +appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__apploaddir__|$(appdefaultdir)|' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +.man.$(APP_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/xwininfo/NEWS b/xwininfo/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/xwininfo/README b/xwininfo/README new file mode 100644 index 0000000..e69de29 diff --git a/xwininfo/config.h.in b/xwininfo/config.h.in new file mode 100644 index 0000000..c364eda --- /dev/null +++ b/xwininfo/config.h.in @@ -0,0 +1,22 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Version number of package */ +#undef VERSION diff --git a/xwininfo/dsimple.c b/xwininfo/dsimple.c new file mode 100644 index 0000000..c84ac3b --- /dev/null +++ b/xwininfo/dsimple.c @@ -0,0 +1,618 @@ +/* $Xorg: dsimple.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $ */ +/* + +Copyright 1993, 1998 The Open Group + +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 above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/programs/xlsfonts/dsimple.c,v 3.6 2001/12/14 20:02:09 dawes Exp $ */ + +#include +#include +#include +#include +#include +#include +#include +/* + * Other_stuff.h: Definitions of routines in other_stuff. + * + * Written by Mark Lillibridge. Last updated 7/1/87 + */ + +#ifdef BUILD_PRINTSUPPORT +#include +#endif /* BUILD_PRINTSUPPORT */ +#include "dsimple.h" + +/* + * Just_display: A group of routines designed to make the writting of simple + * X11 applications which open a display but do not open + * any windows much faster and easier. Unless a routine says + * otherwise, it may be assumed to require program_name, dpy, + * and screen already defined on entry. + * + * Written by Mark Lillibridge. Last updated 7/1/87 + */ + + +/* This stuff is defined in the calling program by just_display.h */ +char *program_name = "unknown_program"; +Display *dpy = NULL; +int screen = 0; +Bool printer_output = False; /* Video or printer output ? */ +#ifdef BUILD_PRINTSUPPORT +XPContext pcontext = None; +#endif /* BUILD_PRINTSUPPORT */ + +static void _bitmap_error(int, char *); + +/* + * Malloc: like malloc but handles out of memory using Fatal_Error. + */ +char *Malloc(size) + unsigned size; +{ + char *data; + + if (!(data = malloc(size))) + Fatal_Error("Out of memory!"); + + return(data); +} + + +/* + * Realloc: like Malloc except for realloc, handles NULL using Malloc. + */ +char *Realloc(ptr, size) + char *ptr; + int size; +{ + char *new_ptr; + + if (!ptr) + return(Malloc(size)); + + if (!(new_ptr = realloc(ptr, size))) + Fatal_Error("Out of memory!"); + + return(new_ptr); +} + + +/* + * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete) + * If found, remove it from command line. Don't go past a lone -. + */ +char *Get_Display_Name(pargc, argv) + int *pargc; /* MODIFIED */ + char **argv; /* MODIFIED */ +{ + int argc = *pargc; + char **pargv = argv+1; + char *displayname = NULL; + int i; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) { + if (++i >= argc) usage (); + + displayname = argv[i]; + *pargc -= 2; + continue; + } + if (!strcmp(arg,"-")) { + while (i= argc) usage (); + + printername = argv[i]; + *pargc -= 2; + continue; + } + if (!strcmp(arg,"-")) { + while (i Selects window with id . may + * be either in decimal or hex. + * -name Selects the window with name . + * + * Call as Select_Window_Args(&argc, argv) in main before + * parsing any of your program's command line arguments. + * Select_Window_Args will remove its arguments so that + * your program does not have to worry about them. + * The window returned is the window selected or 0 if + * none of the above arguments was present. If 0 is + * returned, Select_Window should probably be called after + * all command line arguments, and other setup is done. + * For examples of usage, see xwininfo, xwd, or xprop. + */ +Window Select_Window_Args(rargc, argv) + int *rargc; + char **argv; +#define ARGC (*rargc) +{ + int nargc=1; + int argc; + char **nargv; + Window w=0; + + nargv = argv+1; argc = ARGC; +#define OPTION argv[0] +#define NXTOPTP ++argv, --argc>0 +#define NXTOPT if (++argv, --argc==0) usage() +#define COPYOPT nargv++[0]=OPTION, nargc++ + + while (NXTOPTP) { + if (!strcmp(OPTION, "-")) { + COPYOPT; + while (NXTOPTP) + COPYOPT; + break; + } + if (!strcmp(OPTION, "-root")) { + w=RootWindow(dpy, screen); + continue; + } + if (!strcmp(OPTION, "-name")) { + NXTOPT; + w = Window_With_Name(dpy, RootWindow(dpy, screen), + OPTION); + if (!w) + Fatal_Error("No window with name %s exists!",OPTION); + continue; + } + if (!strcmp(OPTION, "-id")) { + NXTOPT; + w=0; + sscanf(OPTION, "0x%lx", &w); + if (!w) + sscanf(OPTION, "%lu", &w); + if (!w) + Fatal_Error("Invalid window id format: %s.", OPTION); + continue; + } + COPYOPT; + } + ARGC = nargc; + + return(w); +} + +/* + * Other_stuff: A group of routines which do common X11 tasks. + * + * Written by Mark Lillibridge. Last updated 7/1/87 + */ + +/* + * Resolve_Color: This routine takes a color name and returns the pixel # + * that when used in the window w will be of color name. + * (WARNING: The colormap of w MAY be modified! ) + * If colors are run out of, only the first n colors will be + * as correct as the hardware can make them where n depends + * on the display. This routine does not require wind to + * be defined. + */ +unsigned long Resolve_Color(w, name) + Window w; + char *name; +{ + XColor c; + Colormap colormap; + XWindowAttributes wind_info; + + /* + * The following is a hack to insure machines without a rgb table + * handle at least white & black right. + */ + if (!strcmp(name, "white")) + name="#ffffffffffff"; + if (!strcmp(name, "black")) + name="#000000000000"; + + XGetWindowAttributes(dpy, w, &wind_info); + colormap = wind_info.colormap; + + if (!XParseColor(dpy, colormap, name, &c)) + Fatal_Error("Bad color format '%s'.", name); + + if (!XAllocColor(dpy, colormap, &c)) + Fatal_Error("XAllocColor failed!"); + + return(c.pixel); +} + + +/* + * Bitmap_To_Pixmap: Convert a bitmap to a 2 colored pixmap. The colors come + * from the foreground and background colors of the gc. + * Width and height are required solely for efficiency. + * If needed, they can be obtained via. XGetGeometry. + */ +Pixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height) + Display *dpy; + Drawable d; + GC gc; + Pixmap bitmap; + int width, height; +{ + Pixmap pix; + int x; + unsigned int i, depth; + Drawable root; + + if (!XGetGeometry(dpy, d, &root, &x, &x, &i, &i, &i, &depth)) + return(0); + + pix = XCreatePixmap(dpy, d, width, height, (int)depth); + + XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, 1); + + return(pix); +} + + +/* + * blip: a debugging routine. Prints Blip! on stderr with flushing. + */ +void blip() +{ + fflush(stdout); + fprintf(stderr, "blip!\n"); + fflush(stderr); +} + + +/* + * Routine to let user select a window using the mouse + */ + +Window Select_Window(dpy) + Display *dpy; +{ + int status; + Cursor cursor; + XEvent event; + Window target_win = None, root = RootWindow(dpy,screen); + int buttons = 0; + + /* Make the target cursor */ + cursor = XCreateFontCursor(dpy, XC_crosshair); + + /* Grab the pointer using target cursor, letting it room all over */ + status = XGrabPointer(dpy, root, False, + ButtonPressMask|ButtonReleaseMask, GrabModeSync, + GrabModeAsync, root, cursor, CurrentTime); + if (status != GrabSuccess) Fatal_Error("Can't grab the mouse."); + + /* Let the user select a window... */ + while ((target_win == None) || (buttons != 0)) { + /* allow one more event */ + XAllowEvents(dpy, SyncPointer, CurrentTime); + XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event); + switch (event.type) { + case ButtonPress: + if (target_win == None) { + target_win = event.xbutton.subwindow; /* window selected */ + if (target_win == None) target_win = root; + } + buttons++; + break; + case ButtonRelease: + if (buttons > 0) /* there may have been some down before we started */ + buttons--; + break; + } + } + + XUngrabPointer(dpy, CurrentTime); /* Done with pointer */ + + return(target_win); +} + + +/* + * Window_With_Name: routine to locate a window with a given name on a display. + * If no window with the given name is found, 0 is returned. + * If more than one window has the given name, the first + * one found will be returned. Only top and its subwindows + * are looked at. Normally, top should be the RootWindow. + */ +Window Window_With_Name(dpy, top, name) + Display *dpy; + Window top; + char *name; +{ + Window *children, dummy; + unsigned int nchildren; + int i; + Window w=0; + char *window_name; + + if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name)) + return(top); + + if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren)) + return(0); + + for (i=0; i(b))?(a):(b)) +#endif /* MAX */ +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif /* MIN */ + + /* Global variables used by routines in just_display.c */ + +extern char *program_name; /* Name of this program */ +extern Display *dpy; /* The current display */ +extern int screen; /* The current screen */ +extern Bool printer_output; /* Video or printer output ? */ +#ifdef BUILD_PRINTSUPPORT +extern XPContext pcontext; /* The current print context */ +#endif /* BUILD_PRINTSUPPORT */ + +#define INIT_NAME program_name=argv[0] /* use this in main to setup + program_name */ + + /* Declaritions for functions in just_display.c */ + +char *Malloc(unsigned); +char *Realloc(char *, int); +char *Get_Display_Name(int *, char **); +#ifdef BUILD_PRINTSUPPORT +char *Get_Printer_Name(int *, char **); +#endif /* BUILD_PRINTSUPPORT */ +Display *Open_Display(char *); +void Setup_Display_And_Screen(int *, char **); +void Close_Display(void); +XFontStruct *Open_Font(char *); +void Beep(void); +Pixmap ReadBitmapFile(Drawable, char *, int *, int *, int *, int *); +void WriteBitmapFile(char *, Pixmap, int, int, int, int); +Window Select_Window_Args(int *, char **); +void usage(void); + +#define X_USAGE "[host:display]" /* X arguments handled by + Get_Display_Name */ + +/* + * Other_stuff.h: Definitions of routines in other_stuff. + * + * Written by Mark Lillibridge. Last updated 7/1/87 + * + * Send bugs, etc. to chariot@athena.mit.edu. + */ + +unsigned long Resolve_Color(Window, char *); +Pixmap Bitmap_To_Pixmap(Display *, Drawable, GC, Pixmap, int, int); +Window Select_Window(Display *); +void blip(void); +Window Window_With_Name(Display *, Window, char *); +#ifdef __GNUC__ +void Fatal_Error(char *, ...) __attribute__((__noreturn__)); +#else +void Fatal_Error(char *, ...); +#endif +void outl(char *, ...); diff --git a/xwininfo/mkinstalldirs b/xwininfo/mkinstalldirs new file mode 100755 index 0000000..d2d5f21 --- /dev/null +++ b/xwininfo/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/xwininfo/xwininfo.man b/xwininfo/xwininfo.man new file mode 100644 index 0000000..8493df0 --- /dev/null +++ b/xwininfo/xwininfo.man @@ -0,0 +1,200 @@ +.\" $Xorg: xwininfo.man,v 1.4 2001/02/09 02:06:04 xorgcvs Exp $ +.\" Copyright 1988, 1998 The Open Group +.\" +.\" 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 above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of The Open Group shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from The Open Group. +.\" +.\" $XFree86: xwininfo.man,v 1.8 2001/12/14 20:02:35 dawes Exp $ +.\" +.TH XWININFO 1 __xorgversion__ +.SH NAME +xwininfo \- window information utility for X +.SH SYNOPSIS +.B "xwininfo" +[\-help] [\-id \fIid\fP] [\-root] [\-name \fIname\fP] [\-int] +[\-children] [\-tree] [\-stats] [\-bits] [\-events] [\-size] [\-wm] [\-shape] +[\-frame] [\-all] +[\-english] [\-metric] +[\-display \fIdisplay\fP] +.SH DESCRIPTION +.PP +.I Xwininfo +is a utility for displaying information about windows. +Various information is displayed depending on which options are selected. +If no options are chosen, \fB\-stats\fP is assumed. +.PP +The user has the option of selecting the target window with +the mouse (by clicking any mouse button in the desired window) or by +specifying its window id on the command line with the \fB\-id\fP option. +Or instead of specifying +the window by its id number, the \fB\-name\fP option may be used to specify +which window is desired by name. +There is also a special \fB\-root\fP option to quickly obtain information +on the screen's root window. +.SH OPTIONS +.PP +.TP 8 +.B "\-help" +Print out the `Usage:' command syntax summary. +.PP +.TP 8 +.B "\-id \fIid\fP" +This option allows the user to specify a target window \fIid\fP on the +command line rather than using the mouse to select the target window. +This is very useful in debugging X applications where the target +window is not mapped to the screen or where the use of the mouse might +be impossible or interfere with the application. +.PP +.TP 8 +.B "\-name \fIname\fP" +This option allows the user to specify that the window named \fIname\fP +is the target window on the command line rather than using the mouse to +select the target window. +.PP +.TP 8 +.B "\-root" +This option specifies that X's root window is the target window. +This is useful in situations where the root window is completely obscured. +.PP +.TP 8 +.B "\-int" +This option specifies that all X window ids should be displayed as +integer values. The default is to display them as hexadecimal values. +.PP +.TP 8 +.B \-children +This option causes the root, parent, and children windows' ids and names of +the selected window to be displayed. +.PP +.TP 8 +.B \-tree +This option is like \fB\-children\fP but displays all children recursively. +.PP +.TP 8 +.B \-stats +This option causes the display of various attributes pertaining to +the location and appearance of the selected window. +Information displayed includes the location of the window, +its width and height, its depth, border width, class, colormap id if any, +map state, backing-store hint, and location of the corners. +.PP +.TP 8 +.B \-bits +This option causes the display of various attributes pertaining to +the selected window's raw bits and how the selected window is to be stored. +Displayed information includes the selected window's bit gravity, +window gravity, backing-store hint, backing-planes value, backing pixel, +and whether or not the window has save-under set. +.PP +.TP 8 +.B \-events +This option causes the selected window's event masks to be displayed. +Both the event mask of events wanted by some client and the event mask of +events not to propagate are displayed. +.PP +.TP 8 +.B \-size +This option causes the selected window's sizing hints to be displayed. +Displayed information includes: for both the normal size hints and the +zoom size hints, the user supplied location if any; the program supplied +location if any; the user supplied size if any; the program supplied size if +any; the minimum size if any; the maximum size if any; the resize increments +if any; and the minimum and maximum aspect ratios if any. +.PP +.TP 8 +.B \-wm +This option causes the selected window's window manager hints to be +displayed. Information displayed may include whether or not the application +accepts input, what the window's icon window # and name is, where the window's +icon should go, and what the window's initial state should be. +.PP +.TP 8 +.B \-shape +This option causes the selected window's window and border shape extents to +be displayed. +.TP 8 +.B \-frame +This option causes window manager frames to be considered when manually +selecting windows. +.PP +.TP 8 +.B \-metric +This option causes all individual height, width, and x and y positions to be +displayed in millimeters as well as number of pixels, based on what the +server thinks the resolution is. Geometry specifications that are in +\fB+x+y\fP form are not changed. +.TP 8 +.B \-english +This option causes all individual height, width, and x and y positions to be +displayed in inches (and feet, yards, and miles if necessary) as well as +number of pixels. \fB\-metric\fP and \fB\-english\fP may both be enabled at the +same time. +.PP +.TP 8 +.B \-all +This option is a quick way to ask for all information possible. +.PP +.TP 8 +.B \-display \fIdisplay\fP +This option allows you to specify the server to connect to; see \fIX(__miscmansuffix__)\fP. +.SH EXAMPLE +.PP +The following is a sample summary taken with no options specified: + +xwininfo: Window id: 0x60000f "xterm" + + Absolute upper-left X: 2 + Absolute upper-left Y: 85 + Relative upper-left X: 0 + Relative upper-left Y: 25 + Width: 579 + Height: 316 + Depth: 8 + Visual Class: PseudoColor + Border width: 0 + Class: InputOutput + Colormap: 0x27 (installed) + Bit Gravity State: NorthWestGravity + Window Gravity State: NorthWestGravity + Backing Store State: NotUseful + Save Under State: no + Map State: IsViewable + Override Redirect State: no + Corners: +2+85 -699+85 -699-623 +2-623 + -geometry 80x24+0+58 + +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +To get the default host and display number. +.SH SEE ALSO +X(__miscmansuffix__), xprop(1) +.SH BUGS +Using \fB\-stats \-bits\fP shows some redundant information. +.PP +The -geometry string displayed must make assumptions about the +window's border width and the behavior of the application and the +window manager. As a result, the location given is not always +correct. +.SH AUTHOR +Mark Lillibridge, MIT Project Athena