Two parts submitted for committal:

1) Adds handling of the old-style ordered/unnamed options to LibGG.
See comments in the diff.  The second patch removes some cruft by
using this new feature.  A couple targets, though, I was not able
to get rid of all the cruft, most notably X/Xlib, because the ordered 
option (the display) can have colons in it (easiest solution is to 
require quoting of the display name)

2) Adds the -physz option to supply or override the physical size
of the display.  Size is given as a string "x,y" in millimeters,
or as a string "x,ydpi" in dots-per-inch.  If an extra "=" is
supplied, then the option's values are always used, even if the target
knows its physical size.  Here is the status of support for this
option in each target.


    target        physz option  tested?   ordered options named
    -----------------------------------------------------------
    X             done          yes       
    Xlib          done          yes
    aa            not done
    directx       not done
    fbdev         done          no        :dev
    file          not done
    glide         not done
    kgi           not done
    ipc           not done
    lcd823        not done
    memory        not complete  no
    monotext      not done
    multi         not done
    palemu        n/a           no
    sub           n/a           no
    suidkgi       not done
    svgalib       done          no        
    tele          n/a           no
    terminfo      done          yes       :path, :term
    tile          n/a           no
    truemu        n/a           no
    vcsa          done          yes       :file
    vgagl         not done
    vgl           not done
    xf86dga       not done

I'll be working on getting some of the others done/tested, but help
is of course appreciated.  If someone could test the 
tele/sub/palemu/

And, for the directx, glide, vgagl, and vgl targets, I either
don't know how (or if it is possible) to determine the screen size
and/or cannot develop/test for those targets, so someone else
will have to do those.

kgi, suidkgi I am assuming we will be stowing in an attic for now.
I didn't complete the memory target, because I am expecting we will
be pulling the SHM option processing out of there now that we have
display-ipc (?) and that the messiest target for option handling.


--
Brian
Index: libgii/gg/parse.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libgii/gg/parse.c,v
retrieving revision 1.2
diff -U2 -r1.2 parse.c
--- libgii/gg/parse.c   2001/05/22 21:44:38     1.2
+++ libgii/gg/parse.c   2001/05/28 04:24:52
@@ -197,4 +197,34 @@
                optlist[1].result: "4"        (out)
 
+       Unnamed/ordered options support:
+
+       If in the optlist an option name is prefixed with a ":",
+       it is an eligible unnamed/ordered option.  If it is 
+       found as a named option as described above, the ":" is
+       changed to a "-", and it is processed normally.  
+
+       After all named options have been processed, any leftover
+       fields are assigned to any unnamed/ordered options which
+       were not found in named form, in the order they appear 
+       in the optlist.
+
+       For Example:
+
+               "terminfo:-physz==240,180:-path=/dev/ttyS0:vt100"
+                         ^                                     ^
+                         |__str                                |__result
+
+               optlist[0].name: ":path"     (in)
+               optlist[1].name: ":term"     (in)
+               optlist[2].name: "physz"     (in)
+
+               optlist[0].name: "-path"     (out)
+               optlist[1].name: ":term"     (out)
+               optlist[2].name: "physz"     (out)
+ 
+               optlist[0].result: "/dev/ttyS0"        (out)
+               optlist[1].result: "vt100"             (out)
+               optlist[2].result: "=240,180"          (out)
+
 ******************************************************************************
 */
@@ -246,5 +276,4 @@
        gg_option *cur; int i;
 
-
        for (;;) {
 
@@ -295,4 +324,10 @@
                                cur = optlist + i;
                        }
+                       else if (*(optlist[i].name) == ':' &&
+                                strncmp(optlist[i].name + 1, name, len) == 0){
+                               /* found it */
+                               cur = optlist + i;
+                               *(optlist[i].name) = '-';
+                       }
                }
 
@@ -316,4 +351,15 @@
        }
 
+       /* Now fill in any unfound eligible unnamed options from excess */
+       for (i=0; i < count; i++) {
+               if (*(optlist[i].name) == ':') {
+                       cur = optlist + i;
+                       str = ggParseOptionValue(str, cur->result);
+                       if (*str == ':')
+                               str++;
+               }
+       }
+
        return (char *)str;
 }
+
Index: libggi/display/X/mode.inc
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/X/mode.inc,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 mode.inc
--- libggi/display/X/mode.inc   2001/05/12 23:01:53     1.1.1.1
+++ libggi/display/X/mode.inc   2001/05/28 04:21:17
@@ -226,5 +226,4 @@
        XVisualInfo vinfo;      /* Dummy here */
        ggi_x_priv *priv;
-       int xsize, ysize;
        int err = 0;
 
@@ -279,16 +278,23 @@
        tm->dpp.x = tm->dpp.y = 1;
 
-       xsize = tm->visible.x
-               * DisplayWidthMM(priv->xwin.x.display, priv->xwin.x.screen)
-               / DisplayWidth(priv->xwin.x.display, priv->xwin.x.screen);
-       ysize = tm->visible.y
-               * DisplayHeightMM(priv->xwin.x.display, priv->xwin.x.screen)
-               / DisplayHeight  (priv->xwin.x.display, priv->xwin.x.screen);
-       if ((tm->size.x != xsize && tm->size.x != GGI_AUTO) ||
-           (tm->size.y != ysize && tm->size.y != GGI_AUTO)) {
-               err = -1;
-       }
-       tm->size.x = xsize;
-       tm->size.y = ysize;
+#define SCREENWMM DisplayWidthMM(priv->xwin.x.display, priv->xwin.x.screen)
+#define SCREENW   DisplayWidth(priv->xwin.x.display, priv->xwin.x.screen)
+#define SCREENHMM DisplayHeightMM(priv->xwin.x.display, priv->xwin.x.screen)
+#define SCREENH   DisplayHeight(priv->xwin.x.display, priv->xwin.x.screen)
+#define SCREENDPIX \
+((SCREENWMM <= 0) ?  0 : (SCREENW * tm->dpp.x * 254 / SCREENWMM / 10))
+#define SCREENDPIY \
+((SCREENHMM <= 0) ?  0 : (SCREENH * tm->dpp.x * 254 / SCREENHMM / 10))
+
+        err = _ggi_figure_physz(tm, 
+                               priv->xwin.x.physzflags, &(priv->xwin.x.physz),
+                                SCREENDPIX, SCREENDPIY, SCREENW, SCREENH);
+
+#undef SCREENWMM 
+#undef SCREENW   
+#undef SCREENHMM 
+#undef SCREENH   
+#undef SCREENDPIX
+#undef SCREENDPIY
 
        err = _GGIbasiccheck(vis, tm, &vinfo);
Index: libggi/display/X/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/X/visual.c,v
retrieving revision 1.2
diff -U2 -r1.2 visual.c
--- libggi/display/X/visual.c   2001/05/23 17:46:03     1.2
+++ libggi/display/X/visual.c   2001/05/28 04:21:17
@@ -43,5 +43,6 @@
        { "inwin",  "no" },
        { "noinput", "no" },
-       { "nocursor", "no" }
+       { "nocursor", "no" },
+       { "physz", "0,0"}
 };
 
@@ -50,4 +51,5 @@
 #define OPT_NOINPUT    2
 #define OPT_NOCURSOR   3
+#define OPT_PHYSZ      4
 
 #define NUM_OPTS       (sizeof(optlist)/sizeof(gg_option))
@@ -160,4 +162,9 @@
                goto out_freepriv;
        }
+
+       err = _ggi_parse_physz(options[OPT_PHYSZ].result, 
+                              &(priv->xwin.x.physzflags), 
+                              &(priv->xwin.x.physz)); 
+       if (err != GGI_OK) goto out_freepriv;
 
        priv->xwin.x.display = disp;
Index: libggi/display/Xlib/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/Xlib/visual.c,v
retrieving revision 1.2
diff -U2 -r1.2 visual.c
--- libggi/display/Xlib/visual.c        2001/05/23 17:46:03     1.2
+++ libggi/display/Xlib/visual.c        2001/05/28 04:21:17
@@ -43,5 +43,6 @@
        { "inwin",  "no" },
        { "noinput", "no" },
-       { "nocursor", "no" }
+       { "nocursor", "no" },
+       { "physz", "0,0" }
 };
 
@@ -50,4 +51,5 @@
 #define OPT_NOINPUT    2
 #define OPT_NOCURSOR   3
+#define OPT_PHYSZ      4
 
 #define NUM_OPTS       (sizeof(optlist)/sizeof(gg_option))
@@ -122,4 +124,9 @@
        }
 
+       err = _ggi_parse_physz(options[OPT_PHYSZ].result, 
+                              &(priv->xwin.x.physzflags), 
+                              &(priv->xwin.x.physz)); 
+       if (err != GGI_OK) goto out_freepriv;
+
        priv->xwin.x.display = disp;
        priv->xwin.x.screen = DefaultScreen(priv->xwin.x.display);
@@ -220,4 +227,6 @@
        return 0;
 
+  out_freepriv:
+       free(priv);
   out_freegc:
        free(LIBGGI_GC(vis));
Index: libggi/display/fbdev/mode.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/fbdev/mode.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 mode.c
--- libggi/display/fbdev/mode.c 2001/05/12 23:02:03     1.1.1.1
+++ libggi/display/fbdev/mode.c 2001/05/28 04:21:18
@@ -703,8 +703,12 @@
        mode->dpp.y = ydpp;
 
-       if (mode->size.x != GGI_AUTO || mode->size.y != GGI_AUTO) {
-               err = -1;
-       }
-       mode->size.x = mode->size.y = GGI_AUTO;
+#define DPI(dim, d) \
+       ((priv->orig_var.dim <= 0) ? 0 : \
+        (mode->visible.d * mode->dpp.d * 254 / priv->orig_var.dim / 10))
+
+       err = _ggi_figure_physz(mode, priv->physzflags, &(priv->physz),
+                                DPI(width, x), DPI(height,y), 
+                               mode->visible.x, mode->visible.y);
+#undef DPI
 
        if (mode->frames == GGI_AUTO) {
Index: libggi/display/fbdev/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/fbdev/visual.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 visual.c
--- libggi/display/fbdev/visual.c       2001/05/12 23:02:01     1.1.1.1
+++ libggi/display/fbdev/visual.c       2001/05/28 04:21:19
@@ -94,5 +94,7 @@
        { "nomouse", "no" },
        { "noinput", "no" },  /* shorthand for nokbd + nomouse */
-       { "novt",    "no" }
+       { "novt",    "no" },
+       { "physz",    "no" },
+       { ":dev",    ""}
 };
 
@@ -101,4 +103,6 @@
 #define OPT_NOINPUT    2
 #define OPT_NOVT       3
+#define OPT_PHYSZ      4
+#define OPT_DEV                5
 
 #define NUM_OPTS       (sizeof(optlist)/sizeof(gg_option))
@@ -742,9 +746,6 @@
        priv->idleaccel = NULL;
 
-       /* handle args */
-       while (args && *args && isspace(*args)) args++;
-
-       if (args && *args) {
-               devfile = args;
+       if (strlen(options[OPT_DEV].result)) {
+               devfile = options[OPT_DEV].result;
        } else if (getenv("FRAMEBUFFER") != NULL) {
                strncpy(devicename, getenv("FRAMEBUFFER"), MAX_DEV_LEN);
@@ -771,4 +772,14 @@
                novt = 1;
        }
+
+       do {
+               int err;
+               err = _ggi_parse_physz(options[OPT_PHYSZ].result, 
+                                      &(priv->physzflags), &(priv->physz)); 
+               if (err != GGI_OK) {
+                       do_cleanup(vis);
+                       return err;
+               }
+       } while (0);
 
        ggLock(_ggi_global_lock);
Index: libggi/display/memory/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/memory/visual.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 visual.c
--- libggi/display/memory/visual.c      2001/05/12 23:02:12     1.1.1.1
+++ libggi/display/memory/visual.c      2001/05/28 04:21:19
@@ -35,8 +35,10 @@
 static const gg_option optlist[] =
 {
-       { "input", "" }
+       { "input", "" },
+       { "physz", "0,0" }
 };
 
 #define OPT_INPUT      0
+#define OPT_PHYSZ      1
 
 #define NUM_OPTS       (sizeof(optlist)/sizeof(gg_option))
Index: libggi/display/svgalib/mode.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/svgalib/mode.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 mode.c
--- libggi/display/svgalib/mode.c       2001/05/12 23:02:24     1.1.1.1
+++ libggi/display/svgalib/mode.c       2001/05/28 04:21:19
@@ -276,4 +276,6 @@
 int GGI_svga_checkmode(ggi_visual *vis,ggi_mode *tm)
 {
+       svga_priv *priv = LIBGGI_PRIVATE(vis);
+
        int ret, err = 0;
 
@@ -322,8 +324,6 @@
        tm->dpp.x = tm->dpp.y = 1;
 
-       if (tm->size.x != GGI_AUTO || tm->size.y != GGI_AUTO) {
-               err = -1;
-       }
-       tm->size.x = tm->size.y = GGI_AUTO;
+       err = _ggi_figure_physz(tm, priv->physzflags, &(priv->physz),
+                               0, 0, tm->visible.x, tm->visible.y);
 
        return err;
Index: libggi/display/svgalib/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/svgalib/visual.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 visual.c
--- libggi/display/svgalib/visual.c     2001/05/12 23:02:26     1.1.1.1
+++ libggi/display/svgalib/visual.c     2001/05/28 04:21:20
@@ -82,4 +82,11 @@
 
 
+static const gg_option optlist[] =
+{
+        { "physz",      "0,0" }
+};
+#define OPT_PHYSZ       0
+#define NUM_OPTS        (sizeof(optlist)/sizeof(gg_option))
+
 void _GGI_svga_freedbs(ggi_visual *vis) {
        int i;
@@ -315,4 +322,5 @@
                        const char *args, void *argptr, uint32 *dlret)
 {
+       gg_option options[NUM_OPTS];
        ggi_linvtsw_arg vtswarg;
        int  vtnum = -1, novt = 0;
@@ -323,4 +331,13 @@
 #endif
        int i, err;
+
+       memcpy(options, optlist, sizeof(options));
+        if (args != NULL) {
+                args = ggParseOptions((char *)args, options, NUM_OPTS);
+                if (args == NULL) {
+                        fprintf(stderr, "display-x: error in arguments.\n");
+                        return GGI_EARGINVAL;
+                }
+        }
        
        if (__svgalib_tty_fd == GSW_MAGIC) {
@@ -403,4 +420,12 @@
        priv->ismapped = 1;
        priv->doswitch = NULL;
+
+       err = _ggi_parse_physz(options[OPT_PHYSZ].result, 
+                               &(priv->physzflags), &(priv->physz)); 
+        if (err != GGI_OK) {
+          do_cleanup(vis);
+          return err;
+        }
+
 
        priv->availmodes = 
Index: libggi/display/terminfo/TIvisual.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/terminfo/TIvisual.h,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 TIvisual.h
--- libggi/display/terminfo/TIvisual.h  2001/05/12 23:02:32     1.1.1.1
+++ libggi/display/terminfo/TIvisual.h  2001/05/28 04:21:20
@@ -61,4 +61,6 @@
        chtype charmap[256];
        ggi_visual *vis;
+       int physzflags;
+       ggi_coord physz;
 };
 
Index: libggi/display/terminfo/mode.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/terminfo/mode.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 mode.c
--- libggi/display/terminfo/mode.c      2001/05/12 23:02:33     1.1.1.1
+++ libggi/display/terminfo/mode.c      2001/05/28 04:21:20
@@ -242,11 +242,7 @@
        tm->dpp.y = ydpp;
 
-       if (tm->size.x != GGI_AUTO || tm->size.y != GGI_AUTO) {
-               err = -1;
-       }
-       tm->size.x = tm->size.y = GGI_AUTO;
-
        _terminfo_select_screen(priv->scr);
-       if (tm->visible.x != COLS || tm->visible.y != LINES) {
+       if ((tm->visible.x != COLS  && tm->visible.x != GGI_AUTO) || 
+           (tm->visible.y != LINES && tm->visible.y != GGI_AUTO)) {
                err = -1;
        }
@@ -255,4 +251,7 @@
        _terminfo_release_screen();
 
+       if (tm->virt.x == GGI_AUTO) tm->virt.x = tm->visible.x;
+       if (tm->virt.y == GGI_AUTO) tm->virt.y = tm->visible.y;
+
        if (tm->virt.x < tm->visible.x) {
                tm->virt.x = tm->visible.x;
@@ -264,4 +263,8 @@
        }
 
+       err = _ggi_figure_physz(tm, priv->physzflags, &(priv->physz),
+                               0, 0, tm->visible.x, tm->visible.y);
+
+       if (tm->graphtype == GT_TEXT) tm->graphtype = GT_TEXT32;
        if (tm->graphtype != GT_TEXT16 && tm->graphtype != GT_TEXT32) {
                tm->graphtype = GT_TEXT16;
Index: libggi/display/terminfo/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/terminfo/visual.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 visual.c
--- libggi/display/terminfo/visual.c    2001/05/12 23:02:32     1.1.1.1
+++ libggi/display/terminfo/visual.c    2001/05/28 04:21:20
@@ -33,4 +33,16 @@
 #include "TIvisual.h"
 
+static const gg_option optlist[] =
+{
+       { ":path",      "" },
+       { ":term",      "" },
+       { "physz",      "0,0" },
+};
+
+#define OPT_PATH       0
+#define OPT_TERM       1
+#define OPT_PHYSZ      2
+#define NUM_OPTS        (sizeof(optlist)/sizeof(gg_option))
+
 void _GGI_terminfo_freedbs(ggi_visual *vis) {
        int i;
@@ -176,24 +188,20 @@
 {
        struct TIhooks *priv;
+       gg_option options[NUM_OPTS];
        char *term_type;
        char *term_path;
-       char *finger;
-       int i;
-
-       term_type = NULL;
-       if ( args == NULL ) {
-               term_path = alloca(1);
-               *term_path = '\0';
-       } else {
-               term_path = alloca(strlen(args) + 1);
-       }
+       int i, err;
 
-       for ( finger = term_path ; *finger != '\0' ; finger++ ) {
-               if ( *finger == ':' ) {
-                       *finger = '\0';
-                       term_type = finger + 1;
-                       break;
+        memcpy(options, optlist, sizeof(options));
+       if (args != NULL) {
+               args = ggParseOptions((char *)args, options, NUM_OPTS);
+               if (args == NULL) {
+                       fprintf(stderr, "display-x: error in arguments.\n");
+                       return GGI_EARGINVAL;
                }
-       }
+        }
+       term_path = options[OPT_PATH].result;
+       term_type = options[OPT_TERM].result;
+       if ((*term_type) == '\0') term_type = NULL;
 
        GGIDPRINT("display-terminfo: initializing %s on %s.\n", term_type, ( ( 
*term_path == '\0' ) ? "stdin/stdout" : term_path ));
@@ -202,4 +210,11 @@
        if (priv == NULL) return GGI_ENOMEM;
 
+       err = _ggi_parse_physz(options[OPT_PHYSZ].result, 
+                              &(priv->physzflags), &(priv->physz)); 
+       if (err != GGI_OK) {
+         free(priv);
+         return err;
+       }
+
        LIBGGI_GC(vis) = malloc(sizeof(ggi_gc));
        if (LIBGGI_GC(vis) == NULL) {
@@ -213,6 +228,6 @@
 
        if ( *term_path == '\0' ) {
-               priv->f_in = fdopen(fileno(stdin), "r");
-               priv->f_out = fdopen(fileno(stdout), "w");
+               priv->f_in = fdopen(dup(fileno(stdin)), "r");
+               priv->f_out = fdopen(dup(fileno(stdout)), "w");
        } else {
                priv->f_in = priv->f_out = fopen(term_path, "rw");
Index: libggi/display/vcsa/mode.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/vcsa/mode.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 mode.c
--- libggi/display/vcsa/mode.c  2001/05/12 23:02:41     1.1.1.1
+++ libggi/display/vcsa/mode.c  2001/05/28 04:21:21
@@ -143,9 +143,4 @@
        mode->dpp.x = mode->dpp.y = 1;
 
-       if (mode->size.x != GGI_AUTO || mode->size.y != GGI_AUTO) {
-               err = -1;
-       }
-       mode->size.x = mode->size.y = GGI_AUTO;
-
        _GGIhandle_ggiauto(mode, priv->width, priv->height);
 
@@ -187,4 +182,7 @@
                err = -1;
        }
+
+       err = _ggi_figure_physz(mode, priv->physzflags, &(priv->physz),
+                               0, 0, mode->visible.x, mode->visible.y);
                
        GGIDPRINT_MODE("display-vcsa: result %d %dx%d#%dx%dF%d[0x%02x]\n",
Index: libggi/display/vcsa/visual.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/display/vcsa/visual.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 visual.c
--- libggi/display/vcsa/visual.c        2001/05/12 23:02:41     1.1.1.1
+++ libggi/display/vcsa/visual.c        2001/05/28 04:21:21
@@ -50,5 +50,7 @@
        { "nomouse", "no" },
        { "ascii",   "no" },
-       { "shade",   "no" }
+       { "shade",   "no" },
+       { "physz",   "0,0" },
+       { ":file",   "" }
 };
 
@@ -58,4 +60,6 @@
 #define OPT_ASCII      3
 #define OPT_SHADE      4
+#define OPT_PHYSZ      5
+#define OPT_FILE       6
 
 #define NUM_OPTS       (sizeof(optlist)/sizeof(gg_option))
@@ -130,16 +134,7 @@
        }
 
+       strncpy(filename, options[OPT_FILE].result, 79);
+       filename[79] = '\0';
 
-       /* handle args */
-       filename[0] = '\0';
-       while (args && *args && isspace(*args)) {
-               args++;
-       }
-
-       if (args && *args) {
-               filename[79] = '\0';
-               strncpy(filename, args, 79);
-       }
-
        err = GGI_ENODEVICE;
        /* work out which console we're on */
@@ -196,4 +191,7 @@
                priv->flags |= VCSA_FLAG_SHADE;
        }
+       err = _ggi_parse_physz(options[OPT_PHYSZ].result, 
+                               &(priv->physzflags), &(priv->physz)); 
+        if (err != GGI_OK) goto out_closefd;
 
        /* move cursor somewhere relatively out of the way */
Index: libggi/ggi/EXPSYMS
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/ggi/EXPSYMS,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 EXPSYMS
--- libggi/ggi/EXPSYMS  2001/05/12 23:03:16     1.1.1.1
+++ libggi/ggi/EXPSYMS  2001/05/28 04:21:21
@@ -29,4 +29,6 @@
 _ggi_realloc
 _ggi_smart_match_palettes
+_ggi_parse_physz
+_ggi_figure_physz
 ggiCheckGraphMode
 ggiCheckMode
Index: libggi/ggi/internal.c
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/ggi/internal.c,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 internal.c
--- libggi/ggi/internal.c       2001/05/12 23:03:13     1.1.1.1
+++ libggi/ggi/internal.c       2001/05/28 04:21:22
@@ -365,2 +365,133 @@
        }
 }
+
+
+int _ggi_parse_physz(char *optstr, int *physzflag, ggi_coord *physz) {
+
+       /* This function parses a string gotten through the -physz= option,
+        * contained in optstr, and fills out the values physzflag and physz 
+        * based on what is in that string.  The latter two are stored in
+        * the visual's target private area (not all targets use the -physz
+        * option.)
+         *
+        * physz gets the integer values in the option string. physzflag can 
+        * contain two flags, one (GGI_PHYSZ_OVERRIDE) designating that the 
+        * values are not defaults, rather ovverrides for a misconfigured 
+        * display.  The second, GGI_PHYSZ_DPI designates that the sizes
+        * in the string are in dots-per-inch, otherwise the sizes are
+        * assumed to be the full size of the display  in millimeters. 
+        * (which may not be the same as the size of the visual, on targets 
+        * where the visual is a subregion of a display system such as X).
+        */
+
+       char *nptr, *endptr;
+       nptr = optstr;
+
+       *physzflag = 0;
+       physz->x =physz->y = GGI_AUTO;
+
+       /* Check if we should *always* override the X server values */
+       if(*nptr == '=') {
+               nptr++;
+               *physzflag |= GGI_PHYSZ_OVERRIDE;
+       }
+
+       physz->x = strtoul(nptr, &endptr, 0);
+
+       if (*nptr == '\0' || *endptr != ',') {
+               *physzflag = 0;
+               physz->x = physz->y = GGI_AUTO;
+               return GGI_EARGINVAL;
+       }
+
+       nptr = endptr + 1;
+
+       physz->y = strtoul(nptr, &endptr, 0);
+
+       if (*nptr != '\0' && 
+           (*endptr == 'd' || *endptr == 'D') && 
+           (*(endptr + 1) == 'p' || *(endptr + 1) == 'P') && 
+           (*(endptr + 2) == 'i' || *(endptr + 2) == 'I'))  {
+               endptr += 3;
+               *physzflag |= GGI_PHYSZ_DPI;
+       }
+
+       if (*nptr == '\0' || *endptr != '\0') {
+               *physzflag = 0;
+               physz->x =physz->y = GGI_AUTO;
+               return GGI_EARGINVAL;
+       }
+
+       return GGI_OK;
+}
+
+
+int _ggi_figure_physz(ggi_mode *mode, int physzflag, ggi_coord *op_sz, 
+                     int dpix, int dpiy, int dsx, int dsy) {
+
+       /* This function validates/suggests values in mode->size to
+        * designate the physical screen size in millimeters.
+        *
+        * mode->visible and mode->dpp are assumed to already contain 
+        * valid values.
+        *
+        * The physflag and op_sz parameters are from the visual's 
+        * target private area, as set by the above _ggi_parse_physz function.
+        *
+        * The dpix, dpiy parameters contain the dpi of the display.
+        *
+        * The dsx, dsy parameters contain the size in pixels of the
+        * entire display, which on visuals using a subregion of 
+        * a display system, such as X, is the size of the entire screen.
+        */
+
+       long xsize, ysize;
+       int err = GGI_OK;
+
+       xsize = ysize = 0;
+
+       if (physzflag & GGI_PHYSZ_DPI) {
+               xsize = (physzflag & GGI_PHYSZ_OVERRIDE) ? op_sz->x : dpix;
+               ysize = (physzflag & GGI_PHYSZ_OVERRIDE) ? op_sz->y : dpiy;
+               if (xsize <= 0 || ysize <= 0) {
+                       xsize = op_sz->x;
+                       ysize = op_sz->y;
+               }
+               if (xsize <= 0 || ysize <= 0) goto nosize;
+               /* find absolute size in mm */
+               xsize = mode->visible.x * mode->dpp.x * 254 / xsize / 10;
+               ysize = mode->visible.y * mode->dpp.y * 254 / ysize / 10;
+       } else {
+               if (physzflag & GGI_PHYSZ_OVERRIDE) {
+                       xsize = op_sz->x;
+                       ysize = op_sz->y;
+               } 
+               else if (dpix && dpiy) {
+                       xsize = (dsx * mode->dpp.x * 254 / dpix / 10);
+                       ysize = (dsy * mode->dpp.y * 254 / dpiy / 10);
+               }
+               if (xsize <= 0 || ysize <= 0) {
+                       xsize = op_sz->x;
+                       ysize = op_sz->y;
+               }
+               if (xsize <= 0 || ysize <= 0) goto nosize;
+               xsize = xsize * mode->visible.x / dsx;
+               ysize = ysize * mode->visible.y / dsy;
+       }
+
+       if ((mode->size.x != xsize && mode->size.x != GGI_AUTO) ||
+           (mode->size.y != ysize && mode->size.y != GGI_AUTO)) {
+               err = GGI_ENOMATCH;
+       }
+
+       mode->size.x = (int)xsize;
+       mode->size.y = (int)ysize;
+
+       return err;
+
+ nosize:
+       if ((mode->size.x != GGI_AUTO) || (mode->size.y != GGI_AUTO)) 
+               err = GGI_ENOMATCH;
+       return err;
+       
+} 
Index: libggi/include/ggi/display/fbdev.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/include/ggi/display/fbdev.h,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 fbdev.h
--- libggi/include/ggi/display/fbdev.h  2001/05/12 23:03:20     1.1.1.1
+++ libggi/include/ggi/display/fbdev.h  2001/05/28 04:21:22
@@ -124,4 +124,6 @@
        void    *lock;          /* Pointer to the fbdev common lock */
        int     *refcount;      /* Pointer to the refcount */
+       int     physzflags;
+       ggi_coord       physz;
 } ggi_fbdev_priv;
 
Index: libggi/include/ggi/display/svgalib.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/include/ggi/display/svgalib.h,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 svgalib.h
--- libggi/include/ggi/display/svgalib.h        2001/05/12 23:03:22     1.1.1.1
+++ libggi/include/ggi/display/svgalib.h        2001/05/28 04:21:22
@@ -87,4 +87,6 @@
        ggi_linvtsw_func *doswitch;
        int     gfxmode;
+       int     physzflags;
+       ggi_coord       physz;
 } svga_priv;
 
Index: libggi/include/ggi/display/vcsa.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/include/ggi/display/vcsa.h,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 vcsa.h
--- libggi/include/ggi/display/vcsa.h   2001/05/12 23:03:22     1.1.1.1
+++ libggi/include/ggi/display/vcsa.h   2001/05/28 04:21:22
@@ -41,4 +41,7 @@
        int flags;
 
+       int physzflags;
+       ggi_coord physz;
+
 } ggi_vcsa_priv;
 
Index: libggi/include/ggi/display/xcommon.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/include/ggi/display/xcommon.h,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 xcommon.h
--- libggi/include/ggi/display/xcommon.h        2001/05/12 23:03:22     1.1.1.1
+++ libggi/include/ggi/display/xcommon.h        2001/05/28 04:21:22
@@ -47,4 +47,7 @@
        void       *xliblock;
        gii_input  *inp;
+
+       int        physzflags;
+       ggi_coord  physz;
 } ggi_x_common;
 
Index: libggi/include/ggi/internal/internal.h
===================================================================
RCS file: /cvsroot/ggi/ggi-core/libggi/include/ggi/internal/internal.h,v
retrieving revision 1.1.1.1
diff -U2 -r1.1.1.1 internal.h
--- libggi/include/ggi/internal/internal.h      2001/05/12 23:03:23     1.1.1.1
+++ libggi/include/ggi/internal/internal.h      2001/05/28 04:21:22
@@ -83,4 +83,10 @@
 void _ggi_smart_match_palettes(ggi_color *pal, int size,
                                ggi_color *ref_pal, int ref_size);
+#define GGI_PHYSZ_OVERRIDE     1
+#define GGI_PHYSZ_DPI          2
+int _ggi_parse_physz(char *optstr, int *physzflag, ggi_coord *physz);
+int _ggi_figure_physz(ggi_mode *mode, int physzflag, ggi_coord *op_sz, 
+                      int dpix, int dpiy, int dsx, int dsy);
+
 
 /* mode.c */

Reply via email to