summaryrefslogtreecommitdiff
path: root/src/Fl_arg.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_arg.cxx')
-rw-r--r--src/Fl_arg.cxx377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/Fl_arg.cxx b/src/Fl_arg.cxx
new file mode 100644
index 000000000..f15d4b5b7
--- /dev/null
+++ b/src/Fl_arg.cxx
@@ -0,0 +1,377 @@
+// Fl_arg.C
+
+// OPTIONAL initialization code for a program using fltk.
+// You do not need to call this! Feel free to make up your own switches.
+
+#include <FL/Fl.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <FL/filename.H>
+#include <FL/fl_draw.H>
+#include <ctype.h>
+#include <string.h>
+
+#ifdef WIN32
+int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
+#define NoValue 0x0000
+#define XValue 0x0001
+#define YValue 0x0002
+#define WidthValue 0x0004
+#define HeightValue 0x0008
+#define AllValues 0x000F
+#define XNegative 0x0010
+#define YNegative 0x0020
+#endif
+
+static int match(const char *a, const char *match, int atleast = 1) {
+ const char *b = match;
+ while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;}
+ return !*a && b >= match+atleast;
+}
+
+// flags set by previously parsed arguments:
+extern char fl_show_iconic; // in Fl_x.C
+static char arg_called;
+static char return_i;
+static const char *name;
+static const char *fg;
+static const char *bg;
+static const char *bg2;
+static const char *geometry;
+static const char *title;
+
+// consume a switch from argv. Returns number of words eaten, 0 on error:
+int Fl::arg(int argc, char **argv, int &i) {
+ arg_called = 1;
+ const char *s = argv[i];
+
+ if (!s) {i++; return 1;} // something removed by calling program?
+
+ // a word that does not start with '-', or a word after a '--', or
+ // the word '-' by itself all start the "non-switch arguments" to
+ // a program. Return 0 to indicate that we don't understand the
+ // word, but set a flag (return_i) so that args() will return at
+ // that point:
+ if (s[0] != '-' || !s[1]) {return_i = 1; return 0;}
+ if (s[1] == '-') {
+ if (!s[2]) {i++; return_i = 1; return 0;}
+ s++; // make "--word" work the same as "-word" for Gnu compatability
+ }
+ s++; // point after the dash
+
+ if (match(s, "iconic")) {
+ fl_show_iconic = 1;
+ i++;
+ return 1;
+ }
+
+ const char *v = argv[i+1];
+ if (i >= argc-1 || !v)
+ return 0; // all the rest need an argument, so if missing it is an error
+
+ if (match(s, "geometry")) {
+
+ int flags, gx, gy; unsigned int gw, gh;
+ flags = XParseGeometry(v, &gx, &gy, &gw, &gh);
+ if (!flags) return 0;
+ geometry = v;
+
+#ifndef WIN32
+ } else if (match(s, "display")) {
+ Fl::display(v);
+#endif
+
+ } else if (match(s, "title")) {
+ title = v;
+
+ } else if (match(s, "name")) {
+ name = v;
+
+ } else if (match(s, "bg2", 3) || match(s, "background2", 11)) {
+ bg2 = v;
+
+ } else if (match(s, "bg") || match(s, "background")) {
+ bg = v;
+
+ } else if (match(s, "fg") || match(s, "foreground")) {
+ fg = v;
+
+ } else return 0; // unrecognized
+
+ i += 2;
+ return 2;
+}
+
+// consume all switches from argv. Returns number of words eaten.
+// Returns zero on error. 'i' will either point at first word that
+// does not start with '-', at the error word, or after a '--', or at
+// argc. If your program does not take any word arguments you can
+// report an error if i < argc.
+
+int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) {
+ arg_called = 1;
+ i = 1; // skip argv[0]
+ while (i < argc) {
+ if (cb && cb(argc,argv,i)) continue;
+ if (!arg(argc,argv,i)) return return_i ? i : 0;
+ }
+ return i;
+}
+
+#ifdef WIN32
+#include <stdio.h>
+// simulation of XParseColor:
+int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) {
+ if (*p == '#') p++;
+ int n = strlen(p);
+ int m = n/3;
+ const char *pattern = 0;
+ switch(m) {
+ case 1: pattern = "%1x%1x%1x"; break;
+ case 2: pattern = "%2x%2x%2x"; break;
+ case 3: pattern = "%3x%3x%3x"; break;
+ case 4: pattern = "%4x%4x%4x"; break;
+ default: return 0;
+ }
+ int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0;
+ r = R; g = G; b = B;
+ return 1;
+}
+
+static void parsecolor(const char *name, void (*func)(uchar,uchar,uchar)) {
+ uchar r,g,b;
+ if (!name) return;
+ if (!fl_parse_color(name, r,g,b))
+ Fl::error("Unknown color: %s", name);
+ else
+ func(r,g,b);
+}
+
+#else
+
+static void parsecolor(const char *name, void (*func)(uchar,uchar,uchar)) {
+ XColor x;
+ if (!name) return;
+ if (!XParseColor(fl_display, fl_colormap, name, &x))
+ Fl::error("Unknown color: %s", name);
+ else
+ func(x.red>>8, x.green>>8, x.blue>>8);
+}
+
+#endif
+
+// show a main window, use any parsed arguments
+void Fl_Window::show(int argc, char **argv) {
+ if (!arg_called) Fl::args(argc,argv);
+
+ // set colors first, so background_pixel is correct:
+ static char beenhere;
+ if (!beenhere) {
+ beenhere = 1;
+ Fl::get_system_colors(); // opens display! May call Fl::fatal()
+ parsecolor(fg, Fl::foreground);
+ parsecolor(bg, Fl::background);
+ parsecolor(bg2,Fl::background2);
+ if (geometry) {
+ int flags = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
+ flags = XParseGeometry(geometry, &gx, &gy, &gw, &gh);
+ if (flags & XNegative) gx = Fl::w()-w()+gx;
+ if (flags & YNegative) gy = Fl::h()-h()+gy;
+ // int mw,mh; minsize(mw,mh);
+ // if (mw > gw) gw = mw;
+ // if (mh > gh) gh = mh;
+ Fl_Widget *r = resizable();
+ if (!r) resizable(this);
+ // for WIN32 we assumme window is not mapped yet:
+ if (flags & (XValue | YValue))
+ x(-1), resize(gx,gy,gw,gh);
+ else
+ size(gw,gh);
+ resizable(r);
+ }
+ }
+
+ if (name) {xclass(name); name = 0;}
+ else if (!xclass()) xclass(filename_name(argv[0]));
+ if (title) {label(title); title = 0;}
+ else if (!label()) label(xclass());
+ show();
+
+#ifndef WIN32
+ // set the command string, used by state-saving window managers:
+ int i;
+ int n=0; for (i=0; i<argc; i++) n += strlen(argv[i])+1;
+#ifdef __GNUC__
+ char buffer[n];
+#else
+ char *buffer = new char[n];
+#endif
+ char *p = buffer;
+ for (i=0; i<argc; i++) for (const char *q = argv[i]; (*p++ = *q++););
+ XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0,
+ (unsigned char *)buffer, p-buffer-1);
+#ifndef __GNUC__
+ delete[] buffer;
+#endif
+#endif
+
+}
+
+// Calls useful for simple demo programs, with automatic help message:
+
+static const char * const helpmsg =
+"options are:\n"
+" -display host:n.n\n"
+" -geometry WxH+X+Y\n"
+" -title windowtitle\n"
+" -name classname\n"
+" -iconic\n"
+" -fg color\n"
+" -bg color\n"
+" -bg2 color";
+
+const char * const Fl::help = helpmsg+13;
+
+void Fl::args(int argc, char **argv) {
+ int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg);
+}
+
+#ifdef WIN32
+
+/* the following function was stolen from the X sources as indicated. */
+
+/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */
+/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
+
+/*
+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 M.I.T. not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission. M.I.T. makes no representations about the
+suitability of this software for any purpose. It is provided "as is"
+without express or implied warranty.
+*/
+
+/*
+ * XParseGeometry parses strings of the form
+ * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ * width, height, xoffset, and yoffset are unsigned integers.
+ * Example: "=80x24+300-49"
+ * The equal sign is optional.
+ * It returns a bitmask that indicates which of the four values
+ * were actually found in the string. For each value found,
+ * the corresponding argument is updated; for each value
+ * not found, the corresponding argument is left unchanged.
+ */
+
+static int ReadInteger(char* string, char** NextString)
+{
+ register int Result = 0;
+ int Sign = 1;
+
+ if (*string == '+')
+ string++;
+ else if (*string == '-') {
+ string++;
+ Sign = -1;
+ }
+ for (; (*string >= '0') && (*string <= '9'); string++) {
+ Result = (Result * 10) + (*string - '0');
+ }
+ *NextString = string;
+ if (Sign >= 0)
+ return (Result);
+ else
+ return (-Result);
+}
+
+int XParseGeometry(const char* string, int* x, int* y,
+ unsigned int* width, unsigned int* height)
+{
+ int mask = NoValue;
+ register char *strind;
+ unsigned int tempWidth, tempHeight;
+ int tempX, tempY;
+ char *nextCharacter;
+
+ if ( (string == NULL) || (*string == '\0')) return(mask);
+ if (*string == '=')
+ string++; /* ignore possible '=' at beg of geometry spec */
+
+ strind = (char *)string;
+ if (*strind != '+' && *strind != '-' && *strind != 'x') {
+ tempWidth = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= WidthValue;
+ }
+
+ if (*strind == 'x' || *strind == 'X') {
+ strind++;
+ tempHeight = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= HeightValue;
+ }
+
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempX = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= XNegative;
+
+ } else {
+ strind++;
+ tempX = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= XValue;
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempY = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ mask |= YNegative;
+
+ } else {
+ strind++;
+ tempY = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= YValue;
+ }
+ }
+
+ /* If strind isn't at the end of the string the it's an invalid
+ geometry specification. */
+
+ if (*strind != '\0') return (0);
+
+ if (mask & XValue)
+ *x = tempX;
+ if (mask & YValue)
+ *y = tempY;
+ if (mask & WidthValue)
+ *width = tempWidth;
+ if (mask & HeightValue)
+ *height = tempHeight;
+ return (mask);
+}
+
+#endif // ifdef WIN32
+
+// end of Fl_Window_arg.C