fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fl_arg.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fl_arg.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // Optional argument initialization code for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 // OPTIONAL initialization code for a program using fltk.
00029 // You do not need to call this!  Feel free to make up your own switches.
00030 
00031 #include <FL/Fl.H>
00032 #include <FL/x.H>
00033 #include <FL/Fl_Window.H>
00034 #include <FL/Fl_Tooltip.H>
00035 #include <FL/filename.H>
00036 #include <FL/fl_draw.H>
00037 #include <ctype.h>
00038 #include "flstring.h"
00039 
00040 #if defined(WIN32) || defined(__APPLE__)
00041 int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
00042 #  define NoValue       0x0000
00043 #  define XValue        0x0001
00044 #  define YValue        0x0002
00045 #  define WidthValue    0x0004
00046 #  define HeightValue   0x0008
00047 #  define AllValues     0x000F
00048 #  define XNegative     0x0010
00049 #  define YNegative     0x0020
00050 #endif
00051 
00052 static int fl_match(const char *a, const char *s, int atleast = 1) {
00053   const char *b = s;
00054   while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;}
00055   return !*a && b >= s+atleast;
00056 }
00057 
00058 // flags set by previously parsed arguments:
00059 extern char fl_show_iconic; // in Fl_x.cxx
00060 static char arg_called;
00061 static char return_i;
00062 static const char *name;
00063 static const char *geometry;
00064 static const char *title;
00065 // these are in Fl_get_system_colors and are set by the switches:
00066 extern const char *fl_fg;
00067 extern const char *fl_bg;
00068 extern const char *fl_bg2;
00069 
00139 int Fl::arg(int argc, char **argv, int &i) {
00140   arg_called = 1;
00141   const char *s = argv[i];
00142 
00143   if (!s) {i++; return 1;}      // something removed by calling program?
00144 
00145   // a word that does not start with '-', or a word after a '--', or
00146   // the word '-' by itself all start the "non-switch arguments" to
00147   // a program.  Return 0 to indicate that we don't understand the
00148   // word, but set a flag (return_i) so that args() will return at
00149   // that point:
00150   if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;}
00151   s++; // point after the dash
00152 
00153   if (fl_match(s, "iconic")) {
00154     fl_show_iconic = 1;
00155     i++;
00156     return 1;
00157   } else if (fl_match(s, "kbd")) {
00158     Fl::visible_focus(1);
00159     i++;
00160     return 1;
00161   } else if (fl_match(s, "nokbd", 3)) {
00162     Fl::visible_focus(0);
00163     i++;
00164     return 1;
00165   } else if (fl_match(s, "dnd", 2)) {
00166     Fl::dnd_text_ops(1);
00167     i++;
00168     return 1;
00169   } else if (fl_match(s, "nodnd", 3)) {
00170     Fl::dnd_text_ops(0);
00171     i++;
00172     return 1;
00173   } else if (fl_match(s, "tooltips", 2)) {
00174     Fl_Tooltip::enable();
00175     i++;
00176     return 1;
00177   } else if (fl_match(s, "notooltips", 3)) {
00178     Fl_Tooltip::disable();
00179     i++;
00180     return 1;
00181   }
00182 #ifdef __APPLE__
00183   // The Finder application in MacOS X passes the "-psn_N_NNNNN" option
00184   // to all apps...
00185   else if (strncmp(s, "psn_", 4) == 0) {
00186     i++;
00187     return 1;
00188   }
00189 #endif // __APPLE__
00190 
00191   const char *v = argv[i+1];
00192   if (i >= argc-1 || !v)
00193     return 0;   // all the rest need an argument, so if missing it is an error
00194 
00195   if (fl_match(s, "geometry")) {
00196 
00197     int flags, gx, gy; unsigned int gw, gh;
00198     flags = XParseGeometry(v, &gx, &gy, &gw, &gh);
00199     if (!flags) return 0;
00200     geometry = v;
00201 
00202 #if !defined(WIN32) && !defined(__APPLE__)
00203   } else if (fl_match(s, "display", 2)) {
00204     Fl::display(v);
00205 #endif
00206 
00207   } else if (fl_match(s, "title", 2)) {
00208     title = v;
00209 
00210   } else if (fl_match(s, "name", 2)) {
00211     name = v;
00212 
00213   } else if (fl_match(s, "bg2", 3) || fl_match(s, "background2", 11)) {
00214     fl_bg2 = v;
00215 
00216   } else if (fl_match(s, "bg", 2) || fl_match(s, "background", 10)) {
00217     fl_bg = v;
00218 
00219   } else if (fl_match(s, "fg", 2) || fl_match(s, "foreground", 10)) {
00220     fl_fg = v;
00221 
00222   } else if (fl_match(s, "scheme", 1)) {
00223     Fl::scheme(v);
00224 
00225   } else return 0; // unrecognized
00226 
00227   i += 2;
00228   return 2;
00229 }
00230 
00231 
00287 int Fl::args(int argc, char** argv, int& i, Fl_Args_Handler cb) {
00288   arg_called = 1;
00289   i = 1; // skip argv[0]
00290   while (i < argc) {
00291     if (cb && cb(argc,argv,i)) continue;
00292     if (!arg(argc,argv,i)) return return_i ? i : 0;
00293   }
00294   return i;
00295 }
00296 
00297 // show a main window, use any parsed arguments
00298 void Fl_Window::show(int argc, char **argv) {
00299   if (argc && !arg_called) Fl::args(argc,argv);
00300 
00301   Fl::get_system_colors();
00302 
00303 #if !defined(WIN32) && !defined(__APPLE__)
00304   // Get defaults for drag-n-drop and focus...
00305   const char *key = 0, *val;
00306 
00307   if (Fl::first_window()) key = Fl::first_window()->xclass();
00308   if (!key) key = "fltk";
00309 
00310   val = XGetDefault(fl_display, key, "dndTextOps");
00311   if (val) Fl::dnd_text_ops(strcasecmp(val, "true") == 0 ||
00312                             strcasecmp(val, "on") == 0 ||
00313                             strcasecmp(val, "yes") == 0);
00314 
00315   val = XGetDefault(fl_display, key, "tooltips");
00316   if (val) Fl_Tooltip::enable(strcasecmp(val, "true") == 0 ||
00317                               strcasecmp(val, "on") == 0 ||
00318                               strcasecmp(val, "yes") == 0);
00319 
00320   val = XGetDefault(fl_display, key, "visibleFocus");
00321   if (val) Fl::visible_focus(strcasecmp(val, "true") == 0 ||
00322                              strcasecmp(val, "on") == 0 ||
00323                              strcasecmp(val, "yes") == 0);
00324 #endif // !WIN32 && !__APPLE__
00325 
00326   // set colors first, so background_pixel is correct:
00327   static char beenhere;
00328   if (!beenhere) {
00329     if (geometry) {
00330       int fl = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
00331       fl = XParseGeometry(geometry, &gx, &gy, &gw, &gh);
00332       if (fl & XNegative) gx = Fl::w()-w()+gx;
00333       if (fl & YNegative) gy = Fl::h()-h()+gy;
00334       //  int mw,mh; minsize(mw,mh);
00335       //  if (mw > gw) gw = mw;
00336       //  if (mh > gh) gh = mh;
00337       Fl_Widget *r = resizable();
00338       if (!r) resizable(this);
00339       // for WIN32 we assume window is not mapped yet:
00340       if (fl & (XValue | YValue))
00341         x(-1), resize(gx,gy,gw,gh);
00342       else
00343         size(gw,gh);
00344       resizable(r);
00345     }
00346   }
00347 
00348   // set the class, which is used by X version of get_system_colors:
00349   if (name) {xclass(name); name = 0;}
00350   else if (!xclass()) xclass(fl_filename_name(argv[0]));
00351 
00352   if (title) {label(title); title = 0;}
00353   else if (!label()) label(xclass());
00354 
00355   if (!beenhere) {
00356     beenhere = 1;
00357     Fl::scheme(Fl::scheme()); // opens display!  May call Fl::fatal()
00358   }
00359 
00360   // Show the window AFTER we have set the colors and scheme.
00361   show();
00362 
00363 #if !defined(WIN32) && !defined(__APPLE__)
00364   // set the command string, used by state-saving window managers:
00365   int j;
00366   int n=0; for (j=0; j<argc; j++) n += strlen(argv[j])+1;
00367   char *buffer = new char[n];
00368   char *p = buffer;
00369   for (j=0; j<argc; j++) for (const char *q = argv[j]; (*p++ = *q++););
00370   XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0,
00371                   (unsigned char *)buffer, p-buffer-1);
00372   delete[] buffer;
00373 #endif // !WIN32 && !__APPLE__
00374 }
00375 
00376 // Calls useful for simple demo programs, with automatic help message:
00377 
00378 static const char * const helpmsg =
00379 "options are:\n"
00380 " -bg2 color\n"
00381 " -bg color\n"
00382 " -di[splay] host:n.n\n"
00383 " -dn[d]\n"
00384 " -fg color\n"
00385 " -g[eometry] WxH+X+Y\n"
00386 " -i[conic]\n"
00387 " -k[bd]\n"
00388 " -na[me] classname\n"
00389 " -nod[nd]\n"
00390 " -nok[bd]\n"
00391 " -not[ooltips]\n"
00392 " -s[cheme] scheme\n"
00393 " -ti[tle] windowtitle\n"
00394 " -to[oltips]";
00395 
00396 const char * const Fl::help = helpmsg+13;
00397 
00406 void Fl::args(int argc, char **argv) {
00407   int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg);
00408 }
00409 
00410 #if defined(WIN32) || defined(__APPLE__)
00411 
00412 /* the following function was stolen from the X sources as indicated. */
00413 
00414 /* Copyright    Massachusetts Institute of Technology  1985, 1986, 1987 */
00415 /* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
00416 
00417 /*
00418 Permission to use, copy, modify, distribute, and sell this software and its
00419 documentation for any purpose is hereby granted without fee, provided that
00420 the above copyright notice appear in all copies and that both that
00421 copyright notice and this permission notice appear in supporting
00422 documentation, and that the name of M.I.T. not be used in advertising or
00423 publicity pertaining to distribution of the software without specific,
00424 written prior permission.  M.I.T. makes no representations about the
00425 suitability of this software for any purpose.  It is provided "as is"
00426 without express or implied warranty.
00427 */
00428 
00429 /*
00430  *    XParseGeometry parses strings of the form
00431  *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
00432  *   width, height, xoffset, and yoffset are unsigned integers.
00433  *   Example:  "=80x24+300-49"
00434  *   The equal sign is optional.
00435  *   It returns a bitmask that indicates which of the four values
00436  *   were actually found in the string.  For each value found,
00437  *   the corresponding argument is updated;  for each value
00438  *   not found, the corresponding argument is left unchanged. 
00439  */
00440 
00441 static int ReadInteger(char* string, char** NextString)
00442 {
00443   register int Result = 0;
00444   int Sign = 1;
00445     
00446   if (*string == '+')
00447     string++;
00448   else if (*string == '-') {
00449     string++;
00450     Sign = -1;
00451   }
00452   for (; (*string >= '0') && (*string <= '9'); string++) {
00453     Result = (Result * 10) + (*string - '0');
00454   }
00455   *NextString = string;
00456   if (Sign >= 0)
00457     return (Result);
00458   else
00459     return (-Result);
00460 }
00461 
00462 int XParseGeometry(const char* string, int* x, int* y,
00463                    unsigned int* width, unsigned int* height)
00464 {
00465   int mask = NoValue;
00466   register char *strind;
00467   unsigned int tempWidth = 0, tempHeight = 0;
00468   int tempX = 0, tempY = 0;
00469   char *nextCharacter;
00470 
00471   if ( (string == NULL) || (*string == '\0')) return(mask);
00472   if (*string == '=')
00473     string++;  /* ignore possible '=' at beg of geometry spec */
00474 
00475   strind = (char *)string;
00476   if (*strind != '+' && *strind != '-' && *strind != 'x') {
00477     tempWidth = ReadInteger(strind, &nextCharacter);
00478     if (strind == nextCharacter) 
00479       return (0);
00480     strind = nextCharacter;
00481     mask |= WidthValue;
00482   }
00483 
00484   if (*strind == 'x' || *strind == 'X') {       
00485     strind++;
00486     tempHeight = ReadInteger(strind, &nextCharacter);
00487     if (strind == nextCharacter)
00488       return (0);
00489     strind = nextCharacter;
00490     mask |= HeightValue;
00491   }
00492 
00493   if ((*strind == '+') || (*strind == '-')) {
00494     if (*strind == '-') {
00495       strind++;
00496       tempX = -ReadInteger(strind, &nextCharacter);
00497       if (strind == nextCharacter)
00498         return (0);
00499       strind = nextCharacter;
00500       mask |= XNegative;
00501 
00502     } else {
00503       strind++;
00504       tempX = ReadInteger(strind, &nextCharacter);
00505       if (strind == nextCharacter)
00506         return(0);
00507       strind = nextCharacter;
00508       }
00509     mask |= XValue;
00510     if ((*strind == '+') || (*strind == '-')) {
00511       if (*strind == '-') {
00512         strind++;
00513         tempY = -ReadInteger(strind, &nextCharacter);
00514         if (strind == nextCharacter)
00515           return(0);
00516         strind = nextCharacter;
00517         mask |= YNegative;
00518 
00519       } else {
00520         strind++;
00521         tempY = ReadInteger(strind, &nextCharacter);
00522         if (strind == nextCharacter)
00523           return(0);
00524         strind = nextCharacter;
00525       }
00526       mask |= YValue;
00527     }
00528   }
00529         
00530   /* If strind isn't at the end of the string the it's an invalid
00531      geometry specification. */
00532 
00533   if (*strind != '\0') return (0);
00534 
00535   if (mask & XValue)
00536     *x = tempX;
00537   if (mask & YValue)
00538     *y = tempY;
00539   if (mask & WidthValue)
00540     *width = tempWidth;
00541   if (mask & HeightValue)
00542     *height = tempHeight;
00543   return (mask);
00544 }
00545 
00546 #endif // ifdef WIN32
00547 
00548 //
00549 // End of "$Id: Fl_arg.cxx 7903 2010-11-28 21:06:39Z matt $".
00550 //