home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / ftp.vapor.com / microdot-1 / md1_src_02.lzx / ogre.c < prev    next >
C/C++ Source or Header  |  2014-05-19  |  85KB  |  4,089 lines

  1. #include "microdot.h"
  2.  
  3. #include <proto/graphics.h>
  4. #include <intuition/sghooks.h>
  5. #include <devices/conunit.h>
  6. #include <proto/gadtools.h>
  7. #include <intuition/gadgetclass.h>
  8. #include <intuition/imageclass.h>
  9. #include <dos/dostags.h>
  10. #include <proto/commodities.h>
  11.  
  12. #include <proto/keymap.h>
  13.  
  14. #include "ogre.h"
  15.  
  16. #include <constructor.h>
  17.  
  18. /*#define GetIMsg(p) (struct IntuiMessage*)GetMsg(p)*/
  19.  
  20. /* use lib version */
  21. //#undef memcpy
  22.  
  23. /*void __stdargs sprintf( char *, char *, ... );*/
  24.  
  25. #define getrawkeycode ogregetrawkeycode
  26. #define makebevelborder ogremakebevelborder
  27.  
  28. #include <constructor.h>
  29. static char *undobuffer;
  30.  
  31. ALLOCSTATIC( undobuffer, 8192, 0 )
  32.  
  33. struct ogwin {
  34.     void    *pool;            /* Memory Pool */
  35.     ULONG    flags, idcmp;    /* NewWindow Flags & IDCMP */
  36.     char    *title;            /* Window Title */
  37.     struct     Screen *scr;    /* Screen to open on */
  38.     struct    MinList    groups;    /* Groups */
  39.     struct    TextFont *font;    /* Screen Font */
  40.     struct    TextAttr *fnta;    /* Screen Font as TextAttr */
  41.     struct  TextFont *used_font;
  42.     struct  TextAttr *used_fnta;
  43.     struct  TextAttr *lvfnta;
  44.     struct  TextFont *lvfont;
  45.     ULONG    fontxsize;        /* Maximum fontxsize of current used font */
  46.     UWORD    pens[9];        /* Draw Pens */
  47.     UBYTE    usesgadtools;    /* Set if uses gadtools */
  48.     UBYTE    hascursorlv;    /* Cursor key controllable Listview ID */
  49.     UWORD    screenx, screeny;     /* Size of Screen */
  50.     struct  oggroup *currentg;    /* Current Group */
  51.     struct    Window *w;            /* ptr to Window, if open */
  52.     UWORD    windowx, windowy;    /* Suggested Window Size */
  53.     UWORD    windowxoffs, windowyoffs;
  54.     struct     Gadget *glist;        /* Gadget List */
  55.     char    *string_workbuffer;
  56.     struct  Gadget *gtglist;
  57.     struct    Gadget *gtlastg;
  58.     struct  VisualInfo *vi;
  59.     struct    DrawInfo *dri;
  60.     BOOL    has_down;
  61.     BOOL    windowlocked;
  62.     void     *windowlock;
  63.     struct  ogobj *helpgad;
  64.     struct    TextAttr underline_fnta;    /* Underlined font */
  65.     struct    IntuiMessage cim;    /* Copy of current IntuiMessage */
  66. };
  67.  
  68. struct oggroup {
  69.     struct    MinNode    n;        /* Link Node */
  70.     UWORD    x, y, xs, ys;    /* Coordinates and size */
  71.     UBYTE    py;                /* Virtual Position */
  72.     UBYTE    ycl;            /* Anger Layout ;-) */
  73.     UBYTE   keepsize;
  74.     UBYTE   frame;
  75.     UBYTE    ogp;            /* Special Pos Flags */
  76.     UBYTE    objoffsx, objoffsy;    /* Object Offsets for frame */
  77.     UBYTE    __pad;
  78.     char    *title;
  79.     struct    MinList    obj;    /* List of objects in Group */
  80. };
  81.  
  82. struct ogobj {
  83.     struct    MinNode    n;        /* Link Node */
  84.     UWORD    x, y, xs, ys;
  85.     UBYTE    py;                /* Virtual Position */
  86.     UBYTE    type;            /* Type of Object */
  87.     UBYTE    keepsize;
  88.     UBYTE    shortcut;
  89.     UWORD    rxs, rys;
  90.     UWORD    id;                /* GadgetID */
  91.     char    *title;
  92.     UWORD    maxchars;        /* String/Integer */
  93.     UWORD    xchars, ychars;    /* String/Int/LV */
  94.     UBYTE    isgadtools;        /* Set if from Gadtools */
  95.     UBYTE    flags;
  96.     ULONG    disable;        /* Enable Flag */
  97.     char    *defaultstring;    /* String */
  98.     ULONG    defaultvalue;    /* rest */
  99.     char    **entries;
  100.     struct  IntuiText *it_t; /* Title IText */
  101.     struct    IntuiText *it_c; /* Contents IText */
  102.     struct    Image    *im;
  103.     struct  Gadget *g;        /* Gadget */
  104.     struct     Gadget *img;    /* Image Gadget of ListView */
  105.     struct  Gadget *scroll; /* Scroller of ListView */
  106.     struct  Gadget *bordg;  /* Border of ListView */
  107.     struct  List *l;        /* Listview List */
  108.     WORD    top;
  109.     UWORD    num;
  110.     long    minval, maxval;
  111.     struct    Border *b_f;    /* Framing Border */
  112.     struct  Border *b_b;     /* Box Border */
  113.     UBYTE    on_esc, on_enter;
  114.     LONG    oldxp;
  115. };
  116.  
  117.  
  118. #ifdef MDV20
  119. #define ISV37 1
  120. #define ISV39 2
  121. #else
  122. #define ISV37 isv37
  123. #define ISV39 isv39
  124. #endif
  125.  
  126. #undef GetIMsg
  127.  
  128. static struct IntuiMessage *GetIMsg( struct MsgPort *p )
  129. {
  130.     return( ( ISV37 ) ? GT_GetIMsg( p ) : ( struct IntuiMessage * ) GetMsg( p ) );
  131. }
  132.  
  133. static void ReplyIMsg( struct IntuiMessage *m )
  134. {
  135.     ( ISV37 ) ? GT_ReplyIMsg( m ) : ReplyMsg( m );
  136. }
  137.  
  138. #define OGALLOC(og,size) LibAllocPooled(og->pool,size)
  139.  
  140. static void calcfontxsize( struct ogwin *ogw )
  141. {
  142.     UWORD *fontdata = ogw->used_font->tf_CharSpace;
  143.     int fc = ogw->used_font->tf_HiChar - ogw->used_font->tf_LoChar + 1;
  144.     int maxs = 0;
  145.     int c;
  146.  
  147.     if( ! ( ogw->used_font->tf_Flags & FPF_PROPORTIONAL ) )
  148.     {
  149.         ogw->fontxsize = ogw->used_font->tf_XSize;
  150.         return;
  151.     }
  152.  
  153.     for( c = 0; c < fc; c++ )
  154.     {
  155.         if( fontdata[ c ]á> maxs )
  156.             maxs = fontdata[ác ];
  157.     }
  158.     ogw->fontxsize = ( maxs + ogw->used_font->tf_XSize + ogw->used_font->tf_XSize ) / 3;
  159.  
  160. }
  161.  
  162.  
  163. static int getrawkeycode( char ch )
  164. {
  165.     int c;
  166.     UBYTE cmp[4];
  167.     UBYTE *dead;
  168.     static struct KeyMap conkeymap;
  169.  
  170.     if( ISV37 )
  171.     {
  172.         c = MapANSI( &ch, 1, cmp, 1, NULL );
  173.         if( c > 0 )
  174.         {
  175.             c = cmp[0];
  176.             if( cmp[1] & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT ) )
  177.                 c |= 0x80;
  178.             return( c );
  179.         }
  180.         return( 0 );
  181.     }
  182.  
  183.     if( !conkeymap.km_LoKeyMapTypes )
  184.     {
  185.         struct IOStdReq confakereq;
  186.  
  187.         memset( &confakereq, 0, sizeof( confakereq ) );
  188.         /* Init Console Base */
  189.         confakereq.io_Message.mn_ReplyPort = CreatePort( NULL, NULL );
  190.         OpenDevice( "console.device", CONU_LIBRARY, &confakereq, 0 );
  191.         /*ConsoleDevice = confakereq.io_Device;*/
  192.         confakereq.io_Data = &conkeymap;
  193.         confakereq.io_Length = sizeof( conkeymap );
  194.         confakereq.io_Command = CD_ASKDEFAULTKEYMAP;
  195.         DoIO( &confakereq );
  196.         CloseDevice( &confakereq );
  197.         DeletePort( confakereq.io_Message.mn_ReplyPort );
  198.     }
  199.  
  200.     for( c = 0; c < 64; c++ )
  201.     {
  202.  
  203.         /*if( ( conkeymap.km_LoKeyMapTypes[c] & KC_VANILLA ) != KC_VANILLA )
  204.             continue;*/
  205.         if( conkeymap.km_LoKeyMapTypes[c] & KCF_STRING )
  206.             continue;
  207.  
  208.         if( conkeymap.km_LoKeyMapTypes[c] & KCF_DEAD )
  209.         {
  210.             int pn, d, offs;
  211.             UBYTE *dp;
  212.  
  213.             memcpy( &dead, &conkeymap.km_LoKeyMap[c], 4 );
  214.  
  215.             pn = ( conkeymap.km_LoKeyMapTypes[ác ]á& 7 ) + 1;
  216.             dp = dead;
  217.  
  218.             for( d = 0; d < pn; d++ )
  219.             {
  220.                 switch( *dead++ )
  221.                 {
  222.                     case 0:
  223.                         if( *dead++ == ch )
  224.                             return( d ? ( c | 0x80 ) : c );
  225.                         break;
  226.  
  227.                     case DPF_MOD:
  228.                         offs = *dead++;
  229.                         if( dp[áoffs ]á== ch )
  230.                             return( d ? ( c | 0x80 ) : c );
  231.                         break;
  232.  
  233.                     case DPF_DEAD:
  234.                         dead++;
  235.                         break;
  236.                 }
  237.             }
  238.         
  239.         }
  240.         else
  241.         {
  242.             memcpy( cmp, &conkeymap.km_LoKeyMap[c], 4 );
  243.             if( cmp[3]á== ch )
  244.             {
  245.                 return( c );
  246.             }
  247.             if( cmp[2] == chá)
  248.             {
  249.                 return( c | 0x80 );
  250.             }
  251.         }
  252.     }
  253.  
  254.     return( 0 );
  255. }
  256.  
  257.  
  258. static ULONG textfit( struct ogwin *ogw, char *txt, UWORD space )
  259. {
  260.     struct TextExtent tex;
  261.     struct RastPort rp;
  262.  
  263.     if( !txt || !txt[0] )
  264.         return( 0 );
  265.  
  266.     if( !ISV37 )
  267.     {
  268.         return( (ULONG) min( strlen( txt ), space / ( ogw->used_font->tf_XSize ) ) );
  269.     }
  270.  
  271.     /* Clone Rastport */
  272.     rp = ogw->scr->RastPort;
  273.     if( ISV39 )
  274.         SetABPenDrMd( &rp, 1, 0, JAM1 );
  275.     else
  276.     {
  277.         SetAPen( &rp, 1 );
  278.         SetDrMd( &rp, JAM1 );
  279.     }
  280.     SetFont( &rp, ogw->used_font );
  281.     return( TextFit( &rp, txt, strlen( txt ), &tex, NULL, 1, space, ogw->used_font->tf_YSize + 1 ) );
  282. }
  283.  
  284. int ogreTextFit( struct TextFont *tf, char *txt, UWORD space )
  285. {
  286.     struct TextExtent tex;
  287.     struct RastPort rp;
  288.  
  289.     if( !txt || !txt[0] )
  290.         return( 0 );
  291.  
  292.     if( !ISV37 )
  293.     {
  294.         return( ( int ) min( strlen( txt ), space / ( tf->tf_XSize ) ) );
  295.     }
  296.  
  297.     InitRastPort( &rp );
  298.     SetFont( &rp, tf );
  299.     return( ( int ) TextFit( &rp, txt, strlen( txt ), &tex, NULL, 1, space, tf->tf_YSize ) );
  300. }
  301.  
  302. void ogreExitWindow( struct ogwin *og )
  303. {
  304.     if( !og )
  305.         return;
  306.     if( og->w )
  307.         CloseWindow( og->w );
  308.     if( og->usesgadtools && og->gtglist )
  309.         FreeGadgets( og->gtglist );
  310.     if( og->dri )
  311.         FreeScreenDrawInfo( og->scr, og->dri );
  312.     if( og->vi )
  313.         FreeVisualInfo( og->vi );
  314.     if( og->pool )
  315.         LibDeletePool( og->pool );
  316.     /*FreeMem( og, sizeof( *og ) );*/
  317. }
  318.  
  319. extern struct TextFont *listfont;
  320. extern struct TextAttr realfontta;
  321.  
  322. void * ogreInitWindow(    struct Screen *scr,
  323.                         ULONG flags,
  324.                            ULONG idcmp,
  325.                         char  *title)
  326. {
  327.     struct ogwin *og;
  328.     struct DrawInfo *dri;
  329.     APTR pool;
  330.  
  331.     pool = LibCreatePool( MEMF_CLEAR | MEMF_PUBLIC, 8192, 2048 );
  332.     if( !pool )
  333.         return( NULL );
  334.  
  335.     og = LibAllocPooled( pool, sizeof( *og ) );
  336.     if( !og )
  337.         return( NULL );
  338.     NewList( (struct List *) &og->groups );
  339.     og->pool = pool;
  340.  
  341.     og->flags = flags;
  342.     og->idcmp = idcmp;
  343.     og->title = title;
  344.     og->scr      = scr;
  345.     og->fnta  = og->used_fnta  = scr->Font;
  346.     og->screenx = scr->Width;
  347.     og->screeny = scr->Height;
  348.  
  349.     /* Init Pens, 1.3 Style */
  350.     if( !ISV37 )
  351.     {
  352.         og->font = og->used_font = OpenFont( og->used_fnta );
  353.         if( og->used_font )
  354.             CloseFont( og->used_font );
  355.         /* Font won't go away since OpenScreen() opened it */
  356.  
  357.         og->pens[ DETAILPEN ] = scr->DetailPen;
  358.         og->pens[ BLOCKPEN ]  = scr->BlockPen;
  359.         og->pens[ TEXTPEN ]á  = 1;
  360.         og->pens[ SHINEPEN ]á = 1;
  361.         og->pens[ SHADOWPEN ]á= 2;
  362.         og->pens[ FILLPEN ]      = 3;
  363.         og->pens[ FILLTEXTPEN ] = 2;
  364.         og->pens[ BACKGROUNDPEN ]á= 0;
  365.         og->pens[ HIGHLIGHTTEXTPEN ]á= 3;
  366.  
  367.     }
  368.     /* 2.0, obtain Pens via DrawInfo */
  369.     else
  370.     {
  371.         og->dri = dri = GetScreenDrawInfo( scr );
  372.         if( !dri )
  373.         {
  374.             ogreExitWindow( og );
  375.             return( NULL );
  376.         }
  377.         og->font = og->used_font = dri->dri_Font;
  378.         memcpy( og->pens, dri->dri_Pens, 9 * 2 );
  379.     }
  380.  
  381.     calcfontxsize( og );
  382.  
  383.     /* Init LV fonts */
  384.     if( !( og->used_font->tf_Flags & FPF_PROPORTIONAL ) ) 
  385.     {
  386.         og->lvfont = og->used_font;
  387.         og->lvfnta = og->used_fnta;
  388.     }
  389.     else
  390.     {
  391.         og->lvfont = listfont;
  392.         og->lvfnta = &realfontta;
  393.     }
  394.  
  395.     return( og );
  396. }
  397.  
  398. void ogreAddGroup(    struct ogwin *ogwin,
  399.                     UBYTE py,
  400.                     UBYTE frame,
  401.                     char *title )
  402. {
  403.     struct oggroup *ogg;
  404.  
  405.     ogg = OGALLOC( ogwin, sizeof( *ogg ) );
  406.     if( !ogg )
  407.         return;
  408.  
  409.     ogg->py = ogg->ycl = py & 0x7f;
  410.     ogg->ogp = py & OGGP_EXPANDSTRING;
  411.     ogg->frame = frame;
  412.     ogg->title = title;
  413.  
  414.     NewList( (struct List *) &ogg->obj );
  415.  
  416.     /* Add to Group list */
  417.     AddTail( (struct List*) &ogwin->groups, (struct Node *) ogg );
  418.     ogwin->currentg = ogg;
  419.  
  420. }
  421.  
  422. void ogreAddButton(    struct ogwin *ogwin,
  423.                     UBYTE py,
  424.                     UBYTE shortcut,
  425.                     char *title,
  426.                     UWORD id )
  427. {
  428.     struct ogobj *obj;
  429.  
  430.     if( !ogwin->currentg )
  431.         return;
  432.  
  433.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  434.     if( !obj )
  435.         return;
  436.  
  437.     ogwin->idcmp |= IDCMP_GADGETUP;
  438.  
  439.     obj->type = OGOBJ_BUTTON;
  440.     obj->py    = py & 31;
  441.     obj->on_esc = py & OGB_ONESC;
  442.     obj->on_enter = py & OGB_ONENTER;
  443.     obj->keepsize = py & OGGP_KEEPSIZE;
  444.     obj->shortcut = shortcut;
  445.     obj->title = title;
  446.     obj->id    = id;
  447.  
  448.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  449. }
  450.  
  451. void ogreAddFuelGauge(    struct ogwin *ogwin,
  452.                     UBYTE py,
  453.                     UWORD id,
  454.                     ULONG maxval )
  455. {
  456.     struct ogobj *obj;
  457.  
  458.     if( !ogwin->currentg )
  459.         return;
  460.  
  461.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  462.     if( !obj )
  463.         return;
  464.  
  465.     obj->type = OGOBJ_FUELGAUGE;
  466.     obj->py    = py;
  467.     obj->id    = id;
  468.     obj->maxval = max( 1, maxval );
  469.  
  470.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  471. }
  472.  
  473. void ogreAddCheckbox(    struct ogwin *ogwin,
  474.                     UBYTE py,
  475.                     UBYTE shortcut,
  476.                     char *title,
  477.                     UWORD id,
  478.                     int val )
  479. {
  480.     struct ogobj *obj;
  481.  
  482.     if( !ogwin->currentg )
  483.         return;
  484.  
  485.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  486.     if( !obj )
  487.         return;
  488.  
  489.     ogwin->idcmp |= IDCMP_GADGETDOWN;
  490.  
  491.     obj->type = OGOBJ_CHECKBOX;
  492.     obj->py    = py;
  493.     obj->shortcut = shortcut;
  494.     obj->title = title;
  495.     obj->id    = id;
  496.     obj->defaultvalue = val;
  497.  
  498.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  499. }
  500.  
  501. void ogreAddString(    struct ogwin *ogwin,
  502.                     UBYTE py,
  503.                     UBYTE shortcut,
  504.                     char *title,
  505.                     UWORD id,
  506.                     char *value,
  507.                     UWORD viewx,
  508.                     UWORD maxchars )
  509. {
  510.     struct ogobj *obj;
  511.  
  512.     if( !ogwin->currentg )
  513.         return;
  514.  
  515.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  516.     if( !obj )
  517.         return;
  518.  
  519.     ogwin->idcmp |= IDCMP_GADGETUP;
  520.  
  521.     obj->type = OGOBJ_STRING;
  522.     obj->py    = py;
  523.     obj->shortcut = shortcut;
  524.     obj->title = title;
  525.     obj->id    = id;
  526.     obj->defaultstring = value;
  527.     obj->xchars = viewx;
  528.     obj->maxchars = maxchars & 0x7fff;
  529.  
  530.     obj->top = maxchars & OGSF_NONEXTACT;
  531.  
  532.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  533. }
  534.  
  535. void ogreAddList(    struct ogwin *ogwin,
  536.                     UBYTE py,
  537.                     UBYTE shortcut,
  538.                     char *title,
  539.                     UWORD id,
  540.                     UWORD viewx,
  541.                     UWORD viewy,
  542.                     UWORD flags,
  543.                     struct List *l )
  544. {
  545.     struct ogobj *obj;
  546.  
  547.     if( !ogwin->currentg )
  548.         return;
  549.  
  550.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  551.     if( !obj )
  552.         return;
  553.  
  554.     ogwin->idcmp |= IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_INTUITICKS | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS;
  555.  
  556.     obj->type = OGOBJ_LIST;
  557.     obj->shortcut = shortcut;
  558.     if( obj->shortcut == 0xff )
  559.         ogwin->hascursorlv = id;
  560.     obj->title = title;
  561.     obj->py    = py;
  562.     obj->id    = id;
  563.     obj->xchars = viewx;
  564.     obj->ychars = viewy;
  565.     obj->flags = flags;
  566.     obj->l = l;
  567.     obj->defaultvalue = -1;
  568.  
  569.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  570. }
  571.  
  572. void ogreAddCycle(    struct ogwin *ogwin,
  573.                     UBYTE py,
  574.                     UBYTE shortcut,
  575.                     char *title,
  576.                     UWORD id,
  577.                     char **entries,
  578.                     UWORD viewx,
  579.                     UWORD current )
  580. {
  581.     struct ogobj *obj;
  582.     char **entp;
  583.  
  584.     if( !ogwin->currentg )
  585.         return;
  586.  
  587.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  588.     if( !obj )
  589.         return;
  590.  
  591.     ogwin->idcmp |= IDCMP_GADGETUP;
  592.  
  593.     obj->type = OGOBJ_CYCLE;
  594.     obj->num = py & OGGP_CYCLERIGHT;
  595.     obj->py    = py & 0x7f;
  596.     obj->shortcut = shortcut;
  597.     obj->title = title;
  598.     obj->id    = id;
  599.     obj->entries = entries;
  600.     obj->xchars = viewx;
  601.     obj->defaultvalue = current;
  602.     entp = entries;
  603.     while( *entp++ )
  604.         obj->num++;
  605.  
  606.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  607. }
  608.  
  609. void ogreAddInteger(    struct ogwin *ogwin,
  610.                     UBYTE py,
  611.                     UBYTE shortcut,
  612.                     char *title,
  613.                     UWORD id,
  614.                     LONG value,
  615.                     LONG minval,
  616.                     LONG maxval,
  617.                     UWORD viewx,
  618.                     UWORD maxchars )
  619. {
  620.     struct ogobj *obj;
  621.  
  622.     if( !ogwin->currentg )
  623.         return;
  624.  
  625.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  626.     if( !obj )
  627.         return;
  628.  
  629.     ogwin->idcmp |= IDCMP_GADGETUP;
  630.  
  631.     obj->type = OGOBJ_INTEGER;
  632.     obj->py    = py;
  633.     obj->shortcut = shortcut;
  634.     obj->title = title;
  635.     obj->id    = id;
  636.     obj->defaultvalue = value;
  637.     obj->xchars = viewx;
  638.     obj->maxchars = maxchars & 0x7fff;
  639.     obj->top = maxchars & OGSF_NONEXTACT;
  640.     obj->minval = minval;
  641.     obj->maxval = maxval;
  642.  
  643.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  644. }
  645.  
  646. void ogreAddText(    struct ogwin *ogwin,
  647.                     UBYTE py,
  648.                     char *title,
  649.                     UWORD id,
  650.                     char *value,
  651.                     UWORD viewx,
  652.                     UBYTE frame )
  653. {
  654.     struct ogobj *obj;
  655.  
  656.     if( !ogwin->currentg )
  657.         return;
  658.  
  659.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  660.     if( !obj )
  661.         return;
  662.  
  663.     obj->type = OGOBJ_TEXT;
  664.     obj->py    = py;
  665.     obj->title = title;
  666.     obj->id    = id;
  667.     obj->defaultstring = value;
  668.     obj->xchars = viewx;
  669.     obj->ychars = frame;
  670.  
  671.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  672. }
  673.  
  674. void ogreAddPensel(    struct ogwin *ogwin,
  675.                     UBYTE py,
  676.                     UBYTE shortcut,
  677.                     char *title,
  678.                     UWORD id,
  679.                     ULONG value,
  680.                     UWORD viewx )
  681. {
  682.     struct ogobj *obj;
  683.  
  684.     if( !ogwin->currentg )
  685.         return;
  686.  
  687.     /* Unter 1.3 Integer erzeugen */
  688.     if( !ISV37 )
  689.     {
  690.         ogreAddInteger( ogwin, py, shortcut, title, id, value, 0, ( 1 << ogwin->scr->RastPort.BitMap->Depth ) - 1, viewx, 4 );
  691.         return;
  692.     }
  693.  
  694.     obj = OGALLOC( ogwin, sizeof( *obj ) );
  695.     if( !obj )
  696.         return;
  697.  
  698.     obj->type = OGOBJ_PENSEL;
  699.     obj->py    = py;
  700.     obj->shortcut = shortcut;
  701.     obj->title = title;
  702.     obj->id    = id;
  703.     obj->defaultvalue = value;
  704.     obj->xchars = viewx;
  705.  
  706.     AddTail( (struct List *) &ogwin->currentg->obj, (struct Node *) obj );
  707. }
  708.  
  709.  
  710. /* Attach two Border lists */
  711. static void __inline attachborder( struct Border *from, struct Border *to )
  712. {
  713.     while( to->NextBorder )
  714.         to = to->NextBorder;
  715.  
  716.     to->NextBorder = from;
  717. }
  718.  
  719. /* Attach two IText lists */
  720. static void __inline attachitext( struct IntuiText *from, struct IntuiText *to )
  721. {
  722.     while( to->NextText )
  723.         to = to->NextText;
  724.  
  725.     to->NextText = from;
  726. }
  727.  
  728. static struct ogobj * __inline findobj( struct ogwin *ogw, UWORD id )
  729. {
  730.     struct ogobj *obj;
  731.     struct oggroup *ogg;
  732.  
  733.     for( ogg = (struct oggroup *) ogw->groups.mlh_Head; ogg->n.mln_Succ; ogg = (struct oggroup *) ogg->n.mln_Succ )
  734.     {
  735.         for( obj = (struct ogobj *) ogg->obj.mlh_Head; obj->n.mln_Succ; obj = (struct ogobj *) obj->n.mln_Succ )
  736.         {
  737.             if( obj->id == id )
  738.                 return( obj );
  739.         }
  740.     }
  741.     return( NULL );
  742. }
  743.  
  744.  
  745. /* Return length of Text */
  746. static int textlen( struct ogwin *ogw, char *txt )
  747. {
  748.     char tmp[ 256 ], *p;
  749.     struct IntuiText it;
  750.  
  751.     if( !txt || !txt[0] )
  752.         return( 0 );
  753.  
  754.     strcpy( tmp, txt );
  755.     p = strchr( tmp, '_' );
  756.     if( p )
  757.         strcpy( p, &p[1] );
  758.  
  759.     it.IText = tmp;
  760.     it.ITextFont = ogw->used_fnta;
  761.  
  762.     return( IntuiTextLength( &it ) );
  763. }
  764.  
  765. /* Return static length of Text */
  766. static int stextlen( struct ogwin *ogw, char *txt )
  767. {
  768.     char tmp[ 256 ], *p;
  769.  
  770.     if( !txt || !txt[0] )
  771.         return( 0 );
  772.  
  773.     strcpy( tmp, txt );
  774.     p = strchr( tmp, '_' );
  775.     if( p )
  776.         strcpy( p, &p[1] );
  777.  
  778.     return( ( int ) ( strlen( tmp ) * ogw->fontxsize ) );
  779. }
  780.  
  781. /* Make IText */
  782. static struct IntuiText *makeitext( struct ogwin *ogw, char *txt, int leftedge, int topedge )
  783. {
  784.     struct IntuiText *it = OGALLOC( ogw, sizeof( *it ) );
  785.     struct IntuiText *it2;
  786.     char *p;
  787.     int baroffset, ch;
  788.  
  789.     if( !it )
  790.         return( NULL );
  791.  
  792.     it->ITextFont = ogw->used_fnta;
  793.     it->LeftEdge  = leftedge;
  794.     it->TopEdge   = topedge;
  795.  
  796.     p = strchr( txt, '_'á);
  797.  
  798.     if( p )
  799.     {
  800.         p = OGALLOC( ogw, strlen( txt ) + 1 );
  801.         if( !p )
  802.             return( NULL );
  803.         strcpy( p, txt );
  804.         txt = strchr( p, '_' );
  805.         *txt = 0;
  806.         ch = txt[1];
  807.         it->IText = p;
  808.         baroffset = IntuiTextLength( it );
  809.         strcpy( txt, &txt[1] );
  810.         txt = p;
  811.  
  812.         it2 = OGALLOC( ogw, sizeof( *it2 ) );
  813.         if( !it2 )
  814.             return( NULL );
  815.  
  816.         it2->LeftEdge  = baroffset + leftedge;
  817.         ogw->underline_fnta           = *ogw->used_fnta;
  818.         ogw->underline_fnta.ta_Style |= FSF_UNDERLINED;
  819.         it2->ITextFont = &ogw->underline_fnta;
  820.         it2->IText     = OGALLOC( ogw, 2 );
  821.         *it2->IText    = ch;
  822.         it2->TopEdge   = topedge;
  823.         it2->FrontPen  = ogw->pens[ TEXTPEN ];
  824.         it->NextText   = it2;
  825.     }
  826.     it->IText         = txt;
  827.     it->FrontPen     = ogw->pens[ TEXTPEN ];
  828.     it->DrawMode    = JAM2;
  829.     return( it );
  830. }
  831.  
  832. static struct IntuiText *makeitextnu( struct ogwin *ogw, char *txt, int leftedge, int topedge )
  833. {
  834.     struct IntuiText *it = OGALLOC( ogw, sizeof( *it ) );
  835.  
  836.     if( !it )
  837.         return( NULL );
  838.  
  839.     it->ITextFont = ogw->used_fnta;
  840.     it->LeftEdge  = leftedge;
  841.     it->TopEdge   = topedge;
  842.     it->IText         = txt;
  843.     it->FrontPen     = ogw->pens[ TEXTPEN ];
  844.     it->DrawMode    = JAM2;
  845.     return( it );
  846. }
  847.  
  848. /* Center IText inside Box */
  849. static void centeritext( struct IntuiText *it, int bx )
  850. {
  851.     int txtlen = IntuiTextLength( it );
  852.     int offs = ( bx - txtlen ) / 2;
  853.  
  854.     it->LeftEdge += offs;
  855.  
  856.     if( it->NextText )
  857.         it->NextText->LeftEdge += offs;
  858.  
  859. }
  860.  
  861.  
  862. /* Calculate nominal size of an object */
  863. static void calcobject( struct ogwin *ogw, struct ogobj *obj )
  864. {
  865.     switch( obj->type )
  866.     {
  867.         case OGOBJ_BUTTON:
  868.             obj->xs = obj->rxs = textlen( ogw, obj->title ) + 8;
  869.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  870.             return;
  871.  
  872.         case OGOBJ_FUELGAUGE:
  873.             obj->xs = obj->rxs = textlen( ogw, "00%" ) + 8;
  874.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  875.             return;
  876.  
  877.         case OGOBJ_CHECKBOX:
  878.             obj->xs = obj->rxs = stextlen( ogw, obj->title ) + 44;
  879.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  880.             return;
  881.  
  882.         case OGOBJ_STRING:
  883.         case OGOBJ_INTEGER:
  884.             obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 16;
  885.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  886.             return;
  887.  
  888.         case OGOBJ_TEXT:
  889.             obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 20;
  890.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  891.             return;
  892.  
  893.         case OGOBJ_PENSEL:
  894.             obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 42;
  895.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  896.             return;
  897.  
  898.         case OGOBJ_CYCLE:
  899.             obj->xs = obj->rxs = stextlen( ogw, obj->title ) + ( ogw->used_font->tf_XSize * obj->xchars ) + 32;
  900.             obj->ys = obj->rys = ogw->used_font->tf_YSize + 4;
  901.             return;
  902.  
  903.         case OGOBJ_LIST:
  904.             obj->xs = obj->rxs = textlen( ogw, obj->title ) + ( ogw->lvfont->tf_XSize * obj->xchars ) + 24;
  905.             obj->ys = obj->rys = ( ( ogw->lvfont->tf_YSize + 1 ) * obj->ychars ) + 5;
  906.             if( obj->title )
  907.                 obj->ys += ogw->used_font->tf_YSize + 1;
  908.             return;
  909.  
  910.  
  911.     }
  912.  
  913. }
  914.  
  915. /* Add gadget to end of list */
  916. static void attachgad( struct Gadget *which, struct Gadget *to )
  917. {
  918.     while( to->NextGadget )
  919.         to = to->NextGadget;
  920.  
  921.     to->NextGadget = which;
  922. }
  923.  
  924.  
  925. /* Calculate Size of all Objects in a group */
  926. static void calcgroupobjs( struct ogwin *ogw, struct oggroup *grp )
  927. {
  928.     struct ogobj *obj;
  929.  
  930.     for( obj = (struct ogobj *) grp->obj.mlh_Head;
  931.          obj->n.mln_Succ;
  932.          obj = (struct ogobj *) obj->n.mln_Succ )
  933.     {
  934.         calcobject( ogw, obj );
  935.     }
  936. }
  937.  
  938. /* Extend a list of rects to fill Area */
  939. static void filllist( struct ogwin *ogw, struct MinList *ml,
  940.                       int destx, int desty )
  941. {
  942.     struct ogobj *obj;
  943.     int maxgx, maxobj;
  944.     int maxy = 0;
  945.     int c, d;
  946.     int counter;
  947.     int offs, accuoffs;
  948.     BOOL found, run2;
  949.     UWORD xexarray[64];
  950.     UBYTE xextypearray[64];
  951.     int xexcount = 0;
  952.  
  953.     for( c = 0; ; c++ )
  954.     {
  955.         found = FALSE;
  956.         maxgx = 0;
  957.         maxobj = 0;
  958.         counter = 0;
  959.  
  960.         /* Find all objects of this Y position */
  961.         for( obj = (struct ogobj *) ml->mlh_Head;
  962.              obj->n.mln_Succ;
  963.              obj = (struct ogobj *) obj->n.mln_Succ )
  964.         {
  965.             if( obj->py != c )
  966.                 continue;
  967.             found = TRUE;
  968.  
  969.             counter++;
  970.  
  971.             if( obj->xs > maxobj )
  972.                 maxobj = obj->xs;
  973.  
  974.             if( obj->x + obj->xs > maxgx )
  975.                 maxgx = obj->x + obj->xs;
  976.  
  977.             if( obj->y + obj->ys > maxy )
  978.                 maxy = obj->y + obj->ys;
  979.  
  980.         }
  981.         if( !found )
  982.             break;
  983.  
  984.         /* Maxgx is current maximum X */
  985.         offs = destx - maxgx;
  986.  
  987.         if( counter > xexcount )
  988.             xexcount = 0;
  989.  
  990.         /* got to distribute offs pixels */
  991.         run2 = FALSE;
  992.  
  993.         while( offs > 0 )
  994.         {
  995.             accuoffs = 0;
  996.             counter = 0;
  997.             for( obj = (struct ogobj *) ml->mlh_Head;
  998.                  obj->n.mln_Succ;
  999.                  obj = (struct ogobj *) obj->n.mln_Succ )
  1000.             {
  1001.                 if( obj->py != c )
  1002.                     continue;
  1003.  
  1004.                 obj->x += accuoffs;
  1005.                 if( obj->xs < maxobj && offs > 0 && !obj->keepsize )
  1006.                 {
  1007.                     d = min( maxobj - obj->xs, offs );
  1008.                     if( !run2 && c && xexcount && ( xextypearray[ counter ]á== obj->type ) )
  1009.                         d = min( d, xexarray[ counter ] - obj->xs );
  1010.  
  1011.                     obj->xs     += d;
  1012.                     accuoffs     += d;
  1013.                     offs         -= d;
  1014.                 }
  1015.                 counter++;
  1016.             }
  1017.             if( offs < counter )
  1018.                 break;
  1019.  
  1020.             maxobj += max( 1, offs / counter );
  1021.             run2 = TRUE;
  1022.         }
  1023.  
  1024.         /* Save sizes for vertical cloning */
  1025.         counter = 0;
  1026.         for( obj = (struct ogobj *) ml->mlh_Head;
  1027.              obj->n.mln_Succ;
  1028.              obj = (struct ogobj *) obj->n.mln_Succ )
  1029.         {
  1030.             if( obj->py != c )
  1031.                 continue;
  1032.  
  1033.             xexarray[ counter ] = obj->xs;
  1034.             xextypearray[ counterá]á= obj->type;
  1035.             counter++;
  1036.         }
  1037.         xexcount = counter;
  1038.     }
  1039.  
  1040.     if( !c )
  1041.         return;
  1042.  
  1043.     /* Now for the Y expand */
  1044.     offs = ( desty - maxy ) / c;
  1045.  
  1046.     for( obj = (struct ogobj *) ml->mlh_Head;
  1047.          obj->n.mln_Succ;
  1048.          obj = (struct ogobj *) obj->n.mln_Succ )
  1049.     {
  1050.         obj->y += ( offs * obj->py );
  1051.         obj->ys += offs;
  1052.     }
  1053.  
  1054. }
  1055.  
  1056.  
  1057. /* Layout a list of rects */
  1058. static void layoutlist( struct ogwin *ogw, struct MinList *ml, int *gxp, int *gyp, int objspace )
  1059. {
  1060.     struct ogobj *obj;
  1061.     int maxy, maxx = 0;
  1062.     int x, y = 0;
  1063.     int c;
  1064.     BOOL found;
  1065.  
  1066.     /* First perform best fit layout */
  1067.     for( c = 0; ; c++ )
  1068.     {
  1069.         found = FALSE;
  1070.         x = 0;
  1071.         maxy = 0;
  1072.  
  1073.         /* Find all objects of this Y position */
  1074.  
  1075.         for( obj = (struct ogobj *) ml->mlh_Head;
  1076.              obj->n.mln_Succ;
  1077.              obj = (struct ogobj *) obj->n.mln_Succ )
  1078.         {
  1079.             if( obj->py != c )
  1080.                 continue;
  1081.             found = TRUE;
  1082.  
  1083.             if( obj->ys > maxy )
  1084.                 maxy = obj->ys;
  1085.  
  1086.             obj->x = x;
  1087.             obj->y = y;
  1088.             x += obj->xs;
  1089.             if( x > maxx )
  1090.                 maxx = x;
  1091.             x+= objspace;
  1092.  
  1093.         }
  1094.         y+= maxy + objspace;
  1095.         if( !found )
  1096.             break;
  1097.  
  1098.         /* Now expand all Y objects to maxy */
  1099.         for( obj = (struct ogobj *) ml->mlh_Head;
  1100.              obj->n.mln_Succ;
  1101.              obj = (struct ogobj *) obj->n.mln_Succ )
  1102.         {
  1103.             if( obj->py != c )
  1104.                 continue;
  1105.             obj->ys = maxy;
  1106.         }
  1107.     }
  1108.     y -= objspace + 1;
  1109.     *gxp = maxx;
  1110.     *gyp = y;
  1111.  
  1112. }
  1113.  
  1114. /* Calculate Offset for Frame */
  1115. static void layoutgroupframe( struct ogwin *ogw, struct oggroup *grp )
  1116. {
  1117.     int left = 8, right = 8, top = 4, bottom = 2;
  1118.  
  1119.     if( grp->title )
  1120.     {
  1121.         bottom += 2;
  1122.         top += ogw->used_font->tf_YSize - 2;
  1123.     }
  1124.  
  1125.     grp->objoffsx = left;
  1126.     grp->objoffsy = top;
  1127.     grp->xs += left + right;
  1128.     grp->ys += top + bottom;
  1129. }
  1130.  
  1131. /* Order Groups */
  1132. static void layoutgroups( struct ogwin *ogw )
  1133. {
  1134.     struct oggroup *grp;
  1135.     int x = 0, y = 0;
  1136.     /*int maxpx = ogw->screenx - ogw->scr->WBorLeft - ogw->scr->WBorRight - 4;*/
  1137.  
  1138.     layoutlist( ogw, &ogw->groups, &x, &y, 4 );
  1139.     filllist( ogw, &ogw->groups, x, y );
  1140.  
  1141.     for( grp = (struct oggroup *) ogw->groups.mlh_Head;
  1142.          grp->n.mln_Succ;
  1143.          grp = (struct oggroup *) grp->n.mln_Succ )
  1144.     {
  1145.         filllist( ogw, &grp->obj, grp->xs - grp->objoffsx - 8, grp->ys - grp->objoffsy - 4 );
  1146.     }
  1147.  
  1148.     ogw->windowx = x + 4;
  1149.     ogw->windowy = y;
  1150. }
  1151.  
  1152. /* Create Bevel Border */
  1153. static struct Border *makebevelborder( struct ogwin *ogw, int xs, int ys, BOOL recessed )
  1154. {
  1155.     struct Border *b1, *b2;
  1156.     UWORD  *vec1;
  1157.     UWORD  *vec2;
  1158.  
  1159.     xs--; ys--;
  1160.  
  1161.     /* First Part */
  1162.  
  1163.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1164.     if( !b1 )
  1165.         return( NULL );
  1166.     vec1 = OGALLOC( ogw, 10 * 2 );
  1167.     if( !vec1 )
  1168.         return( NULL );
  1169.     b1->XY = vec1;
  1170.     b1->Count = 5;
  1171.     b1->FrontPen = ogw->pens[ ( recessed ) ? SHADOWPEN : SHINEPEN ];
  1172.     
  1173.     /* Start Upper Right! */
  1174.     vec1[0]á= xs-1;
  1175.     vec1[1] = 0;
  1176.  
  1177.     vec1[2] = 0;
  1178.     vec1[3] = 0;
  1179.  
  1180.     vec1[4] = 0;
  1181.     vec1[5] = ys;
  1182.  
  1183.     vec1[6] = 1;
  1184.     vec1[7] = ys-1;
  1185.  
  1186.     vec1[8] = 1;
  1187.     vec1[9]á= 1;
  1188.  
  1189.     /* Second Part */
  1190.  
  1191.     b2 = OGALLOC( ogw, sizeof( *b2 ) );
  1192.     if( !b1 )
  1193.         return( NULL );
  1194.     vec2 = OGALLOC( ogw, 10 * 2 );
  1195.     if( !vec2 )
  1196.         return( NULL );
  1197.     b2->XY = vec2;
  1198.     b2->Count = 5;
  1199.     b2->FrontPen = ogw->pens[ ( recessed ) ? SHINEPEN : SHADOWPEN ];
  1200.     b1->NextBorder = b2;
  1201.     
  1202.     /* Start Lower Left! */
  1203.     vec2[0]á= 1;
  1204.     vec2[1] = ys;
  1205.  
  1206.     vec2[2] = xs;
  1207.     vec2[3] = ys;
  1208.  
  1209.     vec2[4] = xs;
  1210.     vec2[5] = 0;
  1211.  
  1212.     vec2[6] = xs-1;
  1213.     vec2[7] = 1;
  1214.  
  1215.     vec2[8] = xs-1;
  1216.     vec2[9]á= ys-1;
  1217.  
  1218.     return( b1 );
  1219. }
  1220.  
  1221. /* Create Checkbox Border with Mark */
  1222. static struct Border *makecheckborder( struct ogwin *ogw, int xs, int ys, BOOL active )
  1223. {
  1224.     struct Border *b0, *b1, *b2, *b3;
  1225.     UWORD  *vec1;
  1226.  
  1227.     b3 = makebevelborder( ogw, xs, ys, FALSE );
  1228.     if( !b3 )
  1229.         return( NULL );
  1230.  
  1231.     xs--; ys--;
  1232.  
  1233.     b0 = OGALLOC( ogw, sizeof( *b0 ) );
  1234.     if( !b0 )
  1235.         return( NULL );
  1236.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1237.     if( !b1 )
  1238.         return( NULL );
  1239.     b2 = OGALLOC( ogw, sizeof( *b2 ) );
  1240.     if( !b2 )
  1241.         return( NULL );
  1242.  
  1243.     vec1 = OGALLOC( ogw, 10 * 2 );
  1244.     if( !vec1 )
  1245.         return( NULL );
  1246.  
  1247.     b1->XY = vec1;
  1248.     b1->Count = 5;
  1249.     b1->FrontPen = ogw->pens[ ( active ) ? TEXTPEN : 0 ];
  1250.     
  1251.     vec1[0]á= 7;
  1252.     vec1[1] = ys / 2;
  1253.  
  1254.     vec1[2] = 11;
  1255.     vec1[3] = ys - 2;
  1256.  
  1257.     vec1[4] = 12;
  1258.     vec1[5] = ys - 2;
  1259.  
  1260.     vec1[6] = 19;
  1261.     vec1[7] = 2;
  1262.  
  1263.     vec1[8] = 21;
  1264.     vec1[9] = 2;
  1265.  
  1266.     b1->NextBorder = b2;
  1267.  
  1268.     *b2 = *b1;
  1269.     b2->LeftEdge++;
  1270.     b2->NextBorder = b3;
  1271.  
  1272.     *b0 = *b1;
  1273.     b0->LeftEdge--;
  1274.     b0->NextBorder = b1;
  1275.  
  1276.     return( b0 );
  1277.  
  1278. }
  1279.  
  1280. /* Create Arrow Border */
  1281. static struct Border *makearrowborder( struct ogwin *ogw, int xs, int ys, BOOL up )
  1282. {
  1283.     struct Border *b0, *b1, *b2;
  1284.     UWORD *vec1;
  1285.  
  1286.     b0 = makebevelborder( ogw, xs, ys, FALSE );
  1287.     if( !b0 )
  1288.         return( NULL );
  1289.     xs--; ys--;
  1290.  
  1291.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1292.     if( !b1 )
  1293.         return( NULL );
  1294.  
  1295.     vec1 = OGALLOC( ogw, 6 * 2 );
  1296.     if( !vec1 )
  1297.         return( NULL );
  1298.  
  1299.     b1->XY = vec1;
  1300.     b1->Count = 3;
  1301.     b1->FrontPen = ogw->pens[ TEXTPEN ];
  1302.     
  1303.     if( up )
  1304.     {
  1305.         vec1[0]á= 3;
  1306.         vec1[1] = ys - 2;
  1307.  
  1308.         vec1[2] = xs / 2;
  1309.         vec1[3] = 2;
  1310.  
  1311.         vec1[4] = xs-4;
  1312.         vec1[5] = ys - 2;
  1313.     }
  1314.     else
  1315.     {
  1316.         vec1[0]á= 3;
  1317.         vec1[1] = 2;
  1318.  
  1319.         vec1[2] = xs / 2;
  1320.         vec1[3] = ys - 2;
  1321.  
  1322.         vec1[4] = xs-4;
  1323.         vec1[5] = 2;
  1324.     }
  1325.  
  1326.     b1->NextBorder = b0;
  1327.  
  1328.     b2 = OGALLOC( ogw, sizeof( *b2 ) );
  1329.     if( !b2 )
  1330.         return( NULL );
  1331.     *b2 = *b1;
  1332.     b2->LeftEdge++;
  1333.     b2->NextBorder = b1;
  1334.  
  1335.     return( b2 );
  1336. }
  1337.  
  1338. /* Create Cycle Border */
  1339. static struct Border *makecycleborder( struct ogwin *ogw, int xs, int ys )
  1340. {
  1341.     struct Border *b0, *b1;
  1342.     UWORD  *vec1;
  1343.     int offs = max( 0, ( ys - 14 ) / 2 );
  1344.  
  1345.     b0 = makebevelborder( ogw, xs, ys, FALSE );
  1346.     if( !b0 )
  1347.         return( NULL );
  1348.     xs--; ys--;
  1349.  
  1350.     /* First Line */
  1351.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1352.     if( !b1 )
  1353.         return( NULL );
  1354.     vec1 = OGALLOC( ogw, 4 * 2 );
  1355.     if( !vec1 )
  1356.         return( NULL );
  1357.     b1->XY = vec1;
  1358.     b1->Count = 2;
  1359.     b1->FrontPen = ogw->pens[ SHADOWPEN ];
  1360.     
  1361.     /* Start Upper Right! */
  1362.     vec1[0]á= 20;
  1363.     vec1[1] = 2;
  1364.  
  1365.     vec1[2] = 20;
  1366.     vec1[3] = ys-2;
  1367.  
  1368.     b1->NextBorder = b0;
  1369.     b0 = b1;
  1370.  
  1371.     /* Second Line */
  1372.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1373.     if( !b1 )
  1374.         return( NULL );
  1375.     *b1 = *b0;
  1376.     b1->Count = 2;
  1377.     b1->FrontPen = ogw->pens[ SHINEPEN ];
  1378.     b1->LeftEdge++;
  1379.     
  1380.     b1->NextBorder = b0;
  1381.     b0 = b1;
  1382.  
  1383.     /* Pfeil */
  1384.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1385.     if( !b1 )
  1386.         return( NULL );
  1387.     vec1 = OGALLOC( ogw, 20 * 2 );
  1388.     if( !vec1 )
  1389.         return( NULL );
  1390.     b1->XY = vec1;
  1391.     b1->Count = 10;
  1392.     b1->FrontPen = ogw->pens[ TEXTPEN ];
  1393.     
  1394.     /* Start Upper Right! */
  1395.     vec1[0]á= 13;
  1396.     vec1[1] = 2;
  1397.  
  1398.     vec1[2] = 7;
  1399.     vec1[3] = 2;
  1400.  
  1401.     vec1[4] = 6;
  1402.     vec1[5] = 3;
  1403.  
  1404.     vec1[6] = 6;
  1405.     vec1[7] = ys-3;
  1406.  
  1407.     vec1[8] = 7;
  1408.     vec1[9] = 3;
  1409.  
  1410.     vec1[10] = 7;
  1411.     vec1[11] = ys-2;
  1412.  
  1413.     vec1[12] = 13;
  1414.     vec1[13] = ys-2;
  1415.  
  1416.     vec1[14] = 13;
  1417.     vec1[15] = ys-3-offs;
  1418.  
  1419.     vec1[16] = 14;
  1420.     vec1[17] = ys-3-offs;
  1421.  
  1422.     vec1[18] = 14;
  1423.     vec1[19] = ys-3;
  1424.  
  1425.     b1->NextBorder = b0;
  1426.     b0 = b1;
  1427.  
  1428.     /* Pfeil 2 */
  1429.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1430.     if( !b1 )
  1431.         return( NULL );
  1432.     vec1 = OGALLOC( ogw, 16 * 2 );
  1433.     if( !vec1 )
  1434.         return( NULL );
  1435.     b1->XY = vec1;
  1436.     b1->Count = 8;
  1437.     b1->FrontPen = ogw->pens[ TEXTPEN ];
  1438.     
  1439.     vec1[0]á= 13;
  1440.     vec1[1] = 3;
  1441.  
  1442.     vec1[2] = 13;
  1443.     vec1[3] = 6 + offs;
  1444.  
  1445.     vec1[4] = 11;
  1446.     vec1[5] = 4 + offs;
  1447.  
  1448.     vec1[6] = 16;
  1449.     vec1[7] = 4 + offs;
  1450.  
  1451.     vec1[8] = 15;
  1452.     vec1[9] = 5 + offs;
  1453.  
  1454.     vec1[10] = 13;
  1455.     vec1[11] = 5 + offs;
  1456.  
  1457.     vec1[12] = 14;
  1458.     vec1[13] = 6 + offs;
  1459.  
  1460.     vec1[14] = 14;
  1461.     vec1[15] = 3;
  1462.  
  1463.     b1->NextBorder = b0;
  1464.     /*b0 = b1;*/
  1465.  
  1466.     return( b1 );
  1467. }
  1468.  
  1469. /* Create String Border */
  1470. static struct Border *makestringborder( struct ogwin *ogw, int xs, int ys, BOOL recessed )
  1471. {
  1472.     struct Border *b1, *b2;
  1473.     UWORD  *vec1;
  1474.     UWORD  *vec2;
  1475.  
  1476.     xs--;
  1477.     ys--;
  1478.  
  1479.     /* First Part */
  1480.  
  1481.     b1 = OGALLOC( ogw, sizeof( *b1 ) );
  1482.     if( !b1 )
  1483.         return( NULL );
  1484.     vec1 = OGALLOC( ogw, 20 * 2 );
  1485.     if( !vec1 )
  1486.         return( NULL );
  1487.     b1->XY = vec1;
  1488.     b1->Count = 10;
  1489.     b1->FrontPen = ogw->pens[ ( recessed ) ? SHADOWPEN : SHINEPEN ];
  1490.     
  1491.     /* Start Lower Left */
  1492.     vec1[0]á= 3;
  1493.     vec1[1] = ys-1;
  1494.  
  1495.     vec1[2] = xs-2;
  1496.     vec1[3] = ys-1;
  1497.  
  1498.     vec1[4] = xs-2;
  1499.     vec1[5] = 2;
  1500.  
  1501.     vec1[6] = xs-3;
  1502.     vec1[7] = ys-1;
  1503.  
  1504.     vec1[8] = xs-3;
  1505.     vec1[9]á= 2;
  1506.  
  1507.     vec1[10] = xs-1;    
  1508.     /*vec1[11] = 0;
  1509.  
  1510.     vec1[12] = 0;
  1511.     vec1[13] = 0;
  1512.  
  1513.     vec1[14] = 0;*/
  1514.     vec1[15] = ys;
  1515.  
  1516.     vec1[16] = 1;
  1517.     vec1[17] = ys-1;
  1518.  
  1519.     vec1[18] = 1;
  1520.     vec1[19] = 1;
  1521.  
  1522.     /* Second Part */
  1523.  
  1524.     b2 = OGALLOC( ogw, sizeof( *b2 ) );
  1525.     if( !b1 )
  1526.         return( NULL );
  1527.     vec2 = OGALLOC( ogw, 20 * 2 );
  1528.     if( !vec2 )
  1529.         return( NULL );
  1530.     b2->XY = vec2;
  1531.     b2->Count = 10;
  1532.     b2->FrontPen = ogw->pens[ ( recessed ) ? SHINEPEN : SHADOWPEN ];
  1533.     b1->NextBorder = b2;
  1534.     
  1535.     /* Start Upper Right! */
  1536.     vec2[0]á= xs;
  1537.     /*vec2[1] = 0;*/
  1538.  
  1539.     vec2[2] = xs;
  1540.     vec2[3] = ys;
  1541.  
  1542.     vec2[4] = xs-1;
  1543.     vec2[5] = 1;
  1544.  
  1545.     vec2[6] = xs-1;
  1546.     vec2[7] = ys;
  1547.  
  1548.     vec2[8] = 1;
  1549.     vec2[9]á= ys;
  1550.  
  1551.     vec2[10] = 2;
  1552.     vec2[11]á= ys-1;
  1553.  
  1554.     vec2[12] = 2;
  1555.     vec2[13]á= 1;
  1556.  
  1557.     vec2[14] = 3;
  1558.     vec2[15]á= ys-2;
  1559.  
  1560.     vec2[16] = 3;
  1561.     vec2[17]á= 1;
  1562.  
  1563.     vec2[18] = xs-3;
  1564.     vec2[19]á= 1;
  1565.  
  1566.     return( b1 );
  1567. }
  1568.  
  1569.  
  1570. /* Create Frame Border */
  1571. static struct Border *makeframeborder( struct ogwin *ogw, struct oggroup *ogg )
  1572. {
  1573.     struct Border *b;
  1574.     int offs;
  1575.  
  1576.     if( ogg->frame == OGFRAME_BEVEL)
  1577.     {
  1578.         b = makebevelborder( ogw, ogg->xs, ogg->ys, TRUE );
  1579.         return( b );
  1580.     }
  1581.     else
  1582.     {    
  1583.         if( ogg->title )
  1584.             offs = ogw->used_font->tf_YSize / 2;
  1585.         else
  1586.             offs = 0;
  1587.         b = makestringborder( ogw, ogg->xs, ogg->ys - offs, TRUE );
  1588.         b->TopEdge += offs;
  1589.         b->NextBorder->TopEdge += offs;
  1590.         return( b );
  1591.     }
  1592. }
  1593.  
  1594. static void posgad( struct Gadget *g, struct ogwin *ogw, struct oggroup *ogg, struct ogobj *obj, int justify )
  1595. {
  1596.     g->LeftEdge = ogg->x + obj->x + ogw->windowxoffs + ogg->objoffsx;
  1597.     g->TopEdge    = ogg->y + obj->y + ogw->windowyoffs + ogg->objoffsy;
  1598.  
  1599.     switch( justify )
  1600.     {
  1601.         case OGPOS_EXPAND:
  1602.             g->Width     = obj->xs;
  1603.             g->Height     = obj->ys;
  1604.             break;
  1605.  
  1606.         case OGPOS_EXPAND_X:
  1607.             g->Width     = obj->xs;
  1608.             g->Height     = obj->rys;
  1609.             g->TopEdge += ( obj->ys - obj->rys ) / 2;
  1610.             break;
  1611.  
  1612.         case OGPOS_CENTER:
  1613.             g->Width    = obj->rxs;
  1614.             g->Height    = obj->rys;
  1615.             g->LeftEdge += ( obj->xs - obj->rxs ) / 2;
  1616.             break;
  1617.  
  1618.         case OGPOS_LEFT:
  1619.             g->Width    = obj->rxs;
  1620.             g->Height    = obj->rys;
  1621.             g->TopEdge += ( obj->ys - obj->rys ) / 2;
  1622.             break;
  1623.  
  1624.         case OGPOS_RIGHT:
  1625.             g->Width    = obj->rxs;
  1626.             g->Height    = obj->rys;
  1627.             g->LeftEdge += ( obj->xs - obj->rxs );
  1628.             g->TopEdge += ( obj->ys - obj->rys ) / 2;
  1629.             break;
  1630.     }
  1631. }
  1632.  
  1633. static void posnewgad( struct NewGadget *ng, struct ogwin *ogw, struct oggroup *ogg, struct ogobj *obj, int justify )
  1634. {
  1635.     memset( ng, 0, sizeof( *ng ) );
  1636.     ng->ng_VisualInfo = ogw->vi;
  1637.     ng->ng_TextAttr = ogw->used_fnta;
  1638.     posgad( (struct Gadget *)(((LONG)ng)-4), ogw, ogg, obj, justify );
  1639. }
  1640.  
  1641.  
  1642. static void makecycletext( struct ogwin *ogw, struct ogobj *obj )
  1643. {
  1644.     int current = obj->defaultvalue;
  1645.     int l;
  1646.  
  1647.     if( !obj->defaultstring )
  1648.         obj->defaultstring = OGALLOC( ogw, 128 );
  1649.  
  1650.     if( !obj->it_c )
  1651.         return;
  1652.  
  1653.     obj->it_c->NextText = NULL;
  1654.     obj->it_c->IText = obj->defaultstring;
  1655.     memset( obj->defaultstring, 'á', 127 );
  1656.  
  1657.     if( current < 0 )
  1658.         current = obj->defaultvalue = obj->num - 1;
  1659.     if( current >= obj->num )
  1660.         current = obj->defaultvalue = 0;
  1661.  
  1662.     memcpy( obj->defaultstring, obj->entries[ obj->defaultvalue ], min( 128, strlen( obj->entries[ obj->defaultvalue ] ) ) );
  1663.     l = textfit( ogw, obj->defaultstring, obj->g->Width - 32 );
  1664.     obj->defaultstring[ál ] = 0;
  1665.  
  1666.     obj->g->GadgetText = obj->it_c;
  1667.  
  1668.     if( obj->it_t )
  1669.     {
  1670.         obj->it_c->NextText = obj->it_t;
  1671.     }
  1672.  
  1673. }
  1674.  
  1675. static struct Process *clipproc;
  1676.  
  1677. static void __saveds clipprochandler( void )
  1678. {
  1679.     struct IFFHandle *ifh;
  1680.     struct StoredProperty *sp;
  1681.     struct Library *IFFParseBase;
  1682.     struct Library *CxBase;
  1683.  
  1684.     IFFParseBase = OldOpenLibrary( "iffparse.library" );
  1685.     if( !IFFParseBase )
  1686.     {
  1687.         clipproc = NULL;
  1688.         return;
  1689.     }
  1690.     CxBase = OldOpenLibrary( "commodities.library" );
  1691.     if( !CxBase )
  1692.     {
  1693.         CloseLibrary( IFFParseBase );
  1694.         clipproc = NULL;
  1695.         return;
  1696.     }
  1697.     
  1698.     for(;;)
  1699.     {
  1700.         ULONG sig = Wait( SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D );
  1701.  
  1702.         if( sig & SIGBREAKF_CTRL_C )
  1703.             break;
  1704.  
  1705.         ifh = AllocIFF();
  1706.         if( !ifh )
  1707.         {
  1708.             continue;
  1709.         }
  1710.  
  1711.         ifh->iff_Stream = OpenClipboard( 0 );
  1712.         if( !ifh->iff_Stream )
  1713.         {
  1714.             FreeIFF( ifh );
  1715.             continue;
  1716.         }
  1717.  
  1718.         InitIFFasClip( ifh );
  1719.         OpenIFF( ifh, IFFF_READ );
  1720.  
  1721.         PropChunk( ifh, MAKE_ID('F','T','X','T'), MAKE_ID('C','H','R','S') );
  1722.         StopOnExit( ifh, MAKE_ID('F','T','X','T'), MAKE_ID('C','H','R','S') );
  1723.         ParseIFF( ifh, IFFPARSE_SCAN );
  1724.  
  1725.         sp = FindProp( ifh, MAKE_ID('F','T','X','T'), MAKE_ID('C','H','R','S') );
  1726.  
  1727.         if( sp && sp->sp_Size )
  1728.         {
  1729.             char *p;
  1730.             char line[á256 ];
  1731.             struct InputEvent *ie;
  1732.  
  1733.             memset( line, 0, 256 );
  1734.             memcpy( line, sp->sp_Data, min( sp->sp_Size, 255 ) );
  1735.  
  1736.             p = strchr( line, '\n' );
  1737.             if( p )
  1738.                 *p = 0;
  1739.  
  1740.             while( ( p = strchr( line, '\t' ) ) )
  1741.                 *p = 32;
  1742.  
  1743.             strrev( line );
  1744.             ie = InvertString( line, NULL );
  1745.             AddIEvents( ie );
  1746.             FreeIEvents( ie );
  1747.         }
  1748.  
  1749.         CloseIFF( ifh );
  1750.         CloseClipboard( ifh->iff_Stream );
  1751.         FreeIFF( ifh );
  1752.  
  1753.     }
  1754.     CloseLibrary( IFFParseBase );
  1755.     CloseLibrary( CxBase );
  1756.     clipproc = NULL;
  1757. }
  1758.  
  1759. CONSTRUCTOR_P(initclipproc,31000)
  1760. {
  1761.     if( SysBase->LibNode.lib_Version < 36 )
  1762.         return( 0 );
  1763.  
  1764.     clipproc = CreateNewProcTags(
  1765.         NP_Entry, clipprochandler,
  1766.         NP_Name, "MicroDot Ogre Clipboard Server",
  1767.         NP_StackSize, 3000,
  1768.         NP_Priority, 5,
  1769.         NP_CopyVars, FALSE,
  1770.         NP_WindowPtr, -1,
  1771.         TAG_DONE
  1772.     );
  1773.     return( 0 );
  1774. }
  1775.  
  1776. DESTRUCTOR_P(delclipbproc,31000)
  1777. {
  1778.     while( clipproc )
  1779.     {
  1780.         Signal( clipproc, SIGBREAKF_CTRL_C );
  1781.         Delay( 10 );
  1782.     }
  1783. }
  1784.  
  1785. static ULONG __asm __saveds stringhookfunc(
  1786.     register __a1 ULONG *cmd,
  1787.     register __a2 struct SGWork *sgw )
  1788. {
  1789.     if( *cmd != SGH_KEY )
  1790.         return( 0 );
  1791.  
  1792.     if( ( sgw->IEvent->ie_Class == IECLASS_RAWKEY ) &&
  1793.         ( sgw->IEvent->ie_Qualifier & IEQUALIFIER_LCOMMAND ) )
  1794.     {
  1795.         sgw->Actions = SGA_END | SGA_REUSE;
  1796.         sgw->Code = 0x70;
  1797.     }
  1798.     else if( ( sgw->IEvent->ie_Class == IECLASS_RAWKEY ) &&
  1799.         ( sgw->IEvent->ie_Code == 0x34 ) &&
  1800.         ( sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND ) )
  1801.     {
  1802.         if( clipproc )
  1803.         {
  1804.             Signal( clipproc, SIGBREAKF_CTRL_D );
  1805.             sgw->Actions &= ~SGA_USE;
  1806.         }
  1807.     }
  1808.     return( -1 );
  1809. }
  1810.  
  1811. static struct Hook stringhook = { 0,0, stringhookfunc };
  1812.  
  1813. static struct ogrevn *getentry( struct ogobj *obj, int num )
  1814. {
  1815.     struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
  1816.  
  1817.     while( vn->n.mln_Succ )
  1818.     {
  1819.         if( !num-- )
  1820.             return( vn );
  1821.         vn = (struct ogrevn * ) vn->n.mln_Succ;
  1822.     }
  1823.     return( NULL );
  1824. }
  1825.  
  1826. static int getnumentries( struct ogobj *obj )
  1827. {
  1828.     struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
  1829.     int num = 0;
  1830.  
  1831.     while( vn->n.mln_Succ )
  1832.     {
  1833.         num++;
  1834.         vn = (struct ogrevn * ) vn->n.mln_Succ;
  1835.     }
  1836.     return( num );
  1837. }
  1838.  
  1839. static int getfirstselentry( struct ogobj *obj )
  1840. {
  1841.     struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
  1842.     int num = 0;
  1843.  
  1844.     while( vn->n.mln_Succ )
  1845.     {
  1846.         if( vn->sel )
  1847.             return( num );
  1848.         num++;
  1849.         vn = (struct ogrevn * ) vn->n.mln_Succ;
  1850.     }
  1851.     return( -1 );
  1852. }
  1853.  
  1854. void FindScrollerValues( UWORD total, UWORD displayable, UWORD top, WORD overlap, UWORD *body, UWORD *pot )
  1855. {
  1856.     UWORD hidden;
  1857.  
  1858.     hidden = max( total-displayable, 0 );
  1859.  
  1860.     if( top > hidden )
  1861.         top = hidden;
  1862.     
  1863.     *body = ( hidden > 0 ) ? ( UWORD ) ( ( ( ULONG ) ( displayable - overlap ) * MAXBODY ) / ( total - overlap ) ) : MAXBODY;
  1864.     *pot  = ( hidden > 0 ) ? ( UWORD ) ( ( ( ULONG ) top * MAXPOT ) / hidden ) : 0;
  1865.  
  1866. }
  1867.  
  1868. UWORD FindScrollerTop( UWORD total, UWORD displayable, UWORD pot )
  1869. {
  1870.     UWORD top, hidden;
  1871.  
  1872.     hidden = max( total - displayable, 0 );
  1873.     top = ( ( ( ULONG ) hidden * pot ) + ( MAXPOT / 2 ) ) >> 16;
  1874.     return( top );
  1875.  
  1876. }
  1877.  
  1878.  
  1879.  
  1880. /* Make List of IntuiTexts for Listview */
  1881. static void makelisttexts( struct ogwin *ogw, struct ogobj *obj )
  1882. {
  1883.     int c;
  1884.     int y = 3;
  1885.     struct ogrevn *vn;
  1886.     struct IntuiText *it, *it2 = obj->it_t;
  1887.     struct Image *im, *im2 = NULL;
  1888.     char *p;
  1889.     struct Border *bf = NULL;
  1890.  
  1891.     if( !obj->it_c )
  1892.     {
  1893.         obj->defaultstring = OGALLOC( ogw, ( obj->xchars * 5 ) * obj->ychars );
  1894.         if( !obj->defaultstring )
  1895.             return;
  1896.  
  1897.         for( c = 0; c < obj->ychars; c++ )
  1898.         {
  1899.             it = OGALLOC( ogw, sizeof( *it ) );
  1900.             if( !it )
  1901.                 return;
  1902.             it->LeftEdge = 4;
  1903.             it->TopEdge = y;
  1904.             it->DrawMode = JAM1;
  1905.             it->FrontPen = ogw->pens[ TEXTPEN ];
  1906.             it->ITextFont = ogw->lvfnta;
  1907.             it->IText    = &obj->defaultstring[ c * ( obj->xchars * 5 ) ];
  1908.             it->NextText = it2;
  1909.             it2 = it;
  1910.  
  1911.             im = OGALLOC( ogw, sizeof( *im ) );
  1912.             if( !im )
  1913.                 return;
  1914.             im->LeftEdge = 2;
  1915.             im->TopEdge = y - 1;
  1916.             im->Width = obj->xs - 20;
  1917.             im->Height = ogw->lvfont->tf_YSize + 2;
  1918.             im->PlaneOnOff = 0;
  1919.             im->Depth = ogw->scr->RastPort.BitMap->Depth;
  1920.             im->NextImage = im2;
  1921.             im2 = im;
  1922.  
  1923.             y += ogw->lvfont->tf_YSize + 1;
  1924.  
  1925.         }
  1926.         obj->it_c = it;
  1927.         obj->im = im;
  1928.     }
  1929.  
  1930.     for( it = obj->it_c, im = obj->im, c = obj->ychars - 1; c >= 0 && it && im; it = it->NextText, im = im->NextImage, c-- )
  1931.     {
  1932.             vn = getentry( obj, c + obj->top );
  1933.             if( !vn )
  1934.             {
  1935.                 p = "";
  1936.                 y = 0;
  1937.             }
  1938.             else
  1939.             {
  1940.                 p = vn->txt;
  1941.                 y = ( obj->xs - 24 ) / ogw->lvfont->tf_XSize;
  1942.                 memcpy( it->IText, p, y );
  1943.             }
  1944.  
  1945.             if( c + obj->top == obj->defaultvalue )
  1946.             {
  1947.                 bf = obj->b_f;
  1948.  
  1949.                 if( bf )
  1950.                 {
  1951.                     bf->TopEdge = it->TopEdge - 1;
  1952.                     bf->NextBorder->TopEdge = it->TopEdge - 1;
  1953.                 }
  1954.  
  1955.             }
  1956.         
  1957.             it->IText[ y ] = 0;
  1958.  
  1959.             if( vn && vn->sel )
  1960.                 im->PlaneOnOff = ogw->pens[ FILLPEN ];
  1961.             else
  1962.                 im->PlaneOnOff = 0;
  1963.  
  1964.     }
  1965.  
  1966.     /*if( obj->it_t )
  1967.         attachitext( obj->it_t, obj->it_c );*/
  1968.     obj->g->GadgetText = obj->it_c;
  1969.     obj->g->GadgetRender = obj->im;
  1970.  
  1971.     /* Build Border */
  1972.     if( bf )
  1973.     {
  1974.         bf->NextBorder->NextBorder= obj->b_b;
  1975.         obj->bordg->GadgetRender = bf;
  1976.     }
  1977.     else
  1978.         obj->bordg->GadgetRender = obj->b_b;
  1979.  
  1980. }
  1981.  
  1982. static void setlistscroller( struct ogwin *ogw, struct ogobj *obj )
  1983. {
  1984.     UWORD pot, body;
  1985.     struct PropInfo *pi;
  1986.  
  1987.     obj->num = getnumentries( obj );
  1988.     FindScrollerValues( obj->num, obj->ychars, obj->top, 0, &body, &pot );
  1989.     if( obj->scroll )
  1990.     {
  1991.         pi = obj->scroll->SpecialInfo;
  1992.         if( ogw->w )
  1993.         {
  1994.             if( pi->VertBody != body || pi->VertPot != pot )
  1995.                 NewModifyProp( obj->scroll, ogw->w, NULL, pi->Flags, 
  1996.                     0, pot, 0, body, 1 );
  1997.         }
  1998.         else
  1999.         {
  2000.             pi->VertBody = body;
  2001.             pi->VertPot  = pot;
  2002.         }
  2003.     }
  2004.  
  2005. }
  2006.  
  2007.  
  2008. /* Calc Fuel Image size */
  2009. static int makefuelimage( struct ogwin *ogw, struct ogobj *obj )
  2010. {
  2011.     ULONG xp, perc;
  2012.     LONG v1, v2;
  2013.  
  2014.     if( obj->defaultvalue > obj->maxval )
  2015.         obj->defaultvalue = obj->maxval;
  2016.  
  2017.     v1 = obj->defaultvalue;
  2018.     v2 = obj->maxval;
  2019.  
  2020.     if( v2 > 1000000 )
  2021.     {
  2022.         v1 = ( v1 + 9 ) / 10;
  2023.         v2 = ( v2 + 9 ) / 10;
  2024.     }
  2025.  
  2026.     perc = ( obj->defaultvalue * 100 ) / obj->maxval;
  2027.     xp = ( v1 * ( ( ULONG ) obj->xchars ) ) / v2;
  2028.  
  2029.     /* Size & Position Images */
  2030.     obj->im->Width = xp;
  2031.     obj->im->NextImage->Width = obj->xchars - xp;
  2032.     obj->im->NextImage->LeftEdge = obj->im->LeftEdge + xp;
  2033.  
  2034.     sprintf( obj->defaultstring, "%ld%%", perc );
  2035.     obj->it_c->LeftEdge = 0;
  2036.     centeritext(  obj->it_c, obj->xs );
  2037.  
  2038.     if( xp != obj->oldxp )
  2039.     {
  2040.         obj->oldxp = xp;
  2041.         return( -1 );
  2042.     }
  2043.     return( 0 );
  2044. }
  2045.  
  2046. /* Init Gadtools */
  2047. static void initgt( struct ogwin *ogw )
  2048. {
  2049.     if( ogw->gtlastg )
  2050.         return;
  2051.  
  2052.     ogw->vi = GetVisualInfo( ogw->scr, TAG_DONE );
  2053.     ogw->gtlastg = CreateContext( &ogw->gtglist );
  2054. }
  2055.  
  2056.  
  2057. static struct Gadget *makeobj( struct ogwin *ogw,
  2058.                                struct oggroup *ogg,
  2059.                                struct ogobj *obj )
  2060. {
  2061.     struct Gadget *g, *g2;
  2062.     struct IntuiText *it;
  2063.     int xs, ys;
  2064.     struct StringInfo *si;
  2065.     struct Border *b;
  2066.     struct StringExtend *sex;
  2067.     struct Image *autoknobimage;
  2068.     struct PropInfo *pi;
  2069.     struct Image *im;
  2070.     struct NewGadget ng;
  2071.     char *p;
  2072.     int c;
  2073.  
  2074.     g = OGALLOC( ogw, sizeof( *g ) );
  2075.     if( !g )
  2076.         return( NULL );
  2077.  
  2078.     obj->g = g;
  2079.     g->UserData = obj;
  2080.  
  2081.     if( obj->shortcut && obj->shortcut != 0xff && obj->shortcut != 0x5f )
  2082.         obj->shortcut = getrawkeycode( obj->shortcut );
  2083.  
  2084.     switch( obj->type )
  2085.     {
  2086.         case OGOBJ_BUTTON:
  2087.             if( obj->shortcut == 0x5f )
  2088.                 ogw->helpgad = obj;
  2089.             /* Let Gadtools create the Gadget */
  2090.             if( ISV37 )
  2091.             {
  2092.                 initgt( ogw );
  2093.                 posnewgad( &ng, ogw, ogg, obj, OGPOS_EXPAND_X );
  2094.                 ng.ng_GadgetID = obj->id;
  2095.                 ng.ng_UserData = obj;
  2096.                 ng.ng_Flags       = PLACETEXT_IN;
  2097.                 if( obj->title )
  2098.                     ng.ng_GadgetText = obj->title;
  2099.  
  2100.                 obj->g = ogw->gtlastg = CreateGadget( BUTTON_KIND, ogw->gtlastg, &ng, GT_Underscore, '_', GA_Disabled, obj->disable, TAG_DONE );
  2101.                 obj->isgadtools = ogw->usesgadtools = 1;
  2102.  
  2103.                 return( NULL );
  2104.             }
  2105.  
  2106.             posgad( g, ogw, ogg, obj, OGPOS_EXPAND_X );
  2107.             g->Flags        = GFLG_GADGHCOMP;
  2108.             if( obj->disable )
  2109.                 g->Flags |= GFLG_DISABLED;
  2110.             g->Activation    = GACT_RELVERIFY;
  2111.             g->GadgetType     = BOOLGADGET;
  2112.             g->GadgetID     = obj->id;
  2113.             g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, FALSE );
  2114.             if( obj->title )
  2115.             {
  2116.                 it = makeitext( ogw, obj->title, 0, 2 );
  2117.                 centeritext( it, obj->xs );
  2118.                 g->GadgetText = it;
  2119.             }
  2120.             break;
  2121.  
  2122.         case OGOBJ_CHECKBOX:
  2123.             /* Let Gadtools create the Gadget */
  2124.             if( ISV39 )
  2125.             {
  2126.                 initgt( ogw );
  2127.                 xs = stextlen( ogw, obj->title );
  2128.                 posnewgad( &ng, ogw, ogg, obj, OGPOS_RIGHT );
  2129.                 ng.ng_LeftEdge += ( ng.ng_Width - 26 );
  2130.                 ng.ng_Width        = 26;
  2131.                 /*ng.ng_Width -= xs + 8;
  2132.                 ng.ng_LeftEdge += xs + 8;
  2133.                 ng.ng_Width       = min( 26, ng.ng_Width );*/
  2134.                 ng.ng_GadgetID = obj->id;
  2135.                 ng.ng_UserData = obj;
  2136.                 ng.ng_Flags       = PLACETEXT_LEFT;
  2137.                 if( obj->title )
  2138.                     ng.ng_GadgetText = obj->title;
  2139.  
  2140.                 obj->g = ogw->gtlastg = CreateGadget( CHECKBOX_KIND, ogw->gtlastg, &ng, GT_Underscore, '_', GTCB_Checked, obj->defaultvalue, GTCB_Scaled, TRUE, GA_Disabled, obj->disable, TAG_DONE );
  2141.                 obj->isgadtools = ogw->usesgadtools = 1;
  2142.  
  2143.                 return( NULL );
  2144.             }
  2145.             ys = ogw->used_font->tf_YSize + 4;
  2146.             xs = stextlen( ogw, obj->title );
  2147.             posgad( g, ogw, ogg, obj, OGPOS_RIGHT );
  2148.             g->LeftEdge += g->Width - 30;
  2149.             g->Width     = 30;
  2150.             /*g->Height        = ys;*/
  2151.             g->Flags        = GFLG_GADGHIMAGE;
  2152.             if( obj->disable )
  2153.                 g->Flags |= GFLG_DISABLED;
  2154.             g->Activation    = GACT_IMMEDIATE | GACT_TOGGLESELECT;
  2155.             g->GadgetType     = GTYP_BOOLGADGET;
  2156.             g->GadgetID     = obj->id;
  2157.             g->GadgetRender = makecheckborder( ogw, 30, ys, FALSE );
  2158.             g->SelectRender = makecheckborder( ogw, 30, ys, TRUE );
  2159.             if( obj->title )
  2160.             {
  2161.                 it = makeitext( ogw, obj->title, - textlen( ogw, obj->title ) - 10 , 2 );
  2162.                 g->GadgetText = it;
  2163.             }
  2164.             if( obj->defaultvalue )
  2165.                 g->Flags |= GFLG_SELECTED;
  2166.             break;
  2167.  
  2168.         case OGOBJ_TEXT:
  2169.             xs = stextlen( ogw, obj->title );
  2170.             posgad( g, ogw, ogg, obj, OGPOS_RIGHT );
  2171.             g->Width    -= xs + 8;
  2172.             g->LeftEdge += xs + 8;
  2173.             g->Flags     = GFLG_GADGHNONE;
  2174.             if( obj->disable )
  2175.                 g->Flags |= GFLG_DISABLED;
  2176.             g->GadgetType = GTYP_BOOLGADGET;
  2177.             g->GadgetID   = obj->id;
  2178.             if( obj->ychars )
  2179.             {
  2180.                 b = g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, TRUE );
  2181.                 /*b->TopEdge = b->NextBorder->TopEdge = -2;
  2182.                 b->LeftEdge= b->NextBorder->LeftEdge = -4;*/
  2183.             }
  2184.             if( obj->title )
  2185.             {
  2186.                 obj->it_t = it = makeitext( ogw, obj->title, - textlen( ogw, obj->title ) - 8, 2 );
  2187.                 g->GadgetText = it;
  2188.             }
  2189.             p = obj->defaultstring;
  2190.             obj->defaultstring = OGALLOC( ogw, 256 );
  2191.             if( p )
  2192.                 strcpy( obj->defaultstring, p );
  2193.             obj->it_c = it = makeitextnu( ogw, obj->defaultstring, 8, 2 );
  2194.             /*obj->it_c->DrawMode = JAM2;*/
  2195.             attachitext( it, g->GadgetText );
  2196.  
  2197.             break;
  2198.  
  2199.         case OGOBJ_CYCLE:
  2200.             xs = stextlen( ogw, obj->title );
  2201.             /* Let Gadtools create the Gadget */
  2202.             if( ISV37 )
  2203.             {
  2204.                 initgt( ogw );
  2205.                 posnewgad( &ng, ogw, ogg, obj, obj->num ? OGPOS_EXPAND_X : OGPOS_RIGHT );
  2206.                 ng.ng_Width -= xs + 8;
  2207.                 ng.ng_LeftEdge += xs + 8;
  2208.                 ng.ng_GadgetID = obj->id;
  2209.                 ng.ng_UserData = obj;
  2210.                 ng.ng_Flags       = PLACETEXT_LEFT;
  2211.                 if( obj->title )
  2212.                     ng.ng_GadgetText = obj->title;
  2213.  
  2214.                 obj->g = ogw->gtlastg = CreateGadget( CYCLE_KIND, ogw->gtlastg, &ng,
  2215.                     GT_Underscore, '_', 
  2216.                     GTCY_Labels, obj->entries,
  2217.                     GTCY_Active, obj->defaultvalue,
  2218.                     GA_Disabled, obj->disable,
  2219.                     TAG_DONE
  2220.                 );
  2221.                 obj->isgadtools = ogw->usesgadtools = 1;
  2222.  
  2223.                 return( NULL );
  2224.             }
  2225.             posgad( g, ogw, ogg, obj, obj->num ? OGPOS_EXPAND_X : OGPOS_RIGHT );
  2226.             g->Width -= xs + 8;
  2227.             g->LeftEdge += xs + 8;
  2228.             g->Activation    = GACT_RELVERIFY;
  2229.             g->Flags        = GFLG_GADGHCOMP;
  2230.             if( obj->disable )
  2231.                 g->Flags |= GFLG_DISABLED;
  2232.             g->GadgetType     = GTYP_BOOLGADGET;
  2233.             g->GadgetID     = obj->id;
  2234.             b = g->GadgetRender = makecycleborder( ogw, g->Width, g->Height );
  2235.             if( obj->title )
  2236.             {
  2237.                 obj->it_t = makeitext( ogw, obj->title, -xs - 8, 2 );
  2238.             }
  2239.             obj->it_c = makeitext( ogw, "", 28, 2 );
  2240.             makecycletext( ogw, obj );
  2241.             break;
  2242.  
  2243.         case OGOBJ_LIST:
  2244.             posgad( g, ogw, ogg, obj, OGPOS_EXPAND );
  2245.             g->Width        -= 16;
  2246.             if( obj->title )
  2247.             {
  2248.                 c = ogw->used_font->tf_YSize + 1;
  2249.                 obj->it_t = makeitext( ogw, obj->title, 0, -c );
  2250.                 centeritext( obj->it_t, g->Width );
  2251.                 g->Height -= c;
  2252.                 g->TopEdge += c;
  2253.             }
  2254.             g->Flags        = GFLG_GADGHNONE | GFLG_GADGIMAGE;
  2255.             g->Activation    = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_FOLLOWMOUSE;
  2256.             g->GadgetType     = GTYP_BOOLGADGET;
  2257.             g->GadgetID     = obj->id;
  2258.  
  2259.             obj->xchars = ( g->Width - 8 ) / ogw->lvfont->tf_XSize;
  2260.             obj->ychars = ( g->Height - 5 ) / ( ogw->lvfont->tf_YSize + 1 );
  2261.  
  2262.             g2 = g;
  2263.  
  2264.             b = makebevelborder( ogw, g->Width, g->Height, FALSE );
  2265.             b->LeftEdge -= g->Width;
  2266.             b->NextBorder->LeftEdge -= g->Width;
  2267.  
  2268.             if( obj->shortcut == 0xff )
  2269.             {
  2270.                 obj->b_f = makebevelborder( ogw, g->Width - 4, ogw->lvfont->tf_YSize + 2, TRUE );
  2271.                 if( obj->b_f )
  2272.                 {
  2273.                     obj->b_f->LeftEdge = -g->Width + 2;
  2274.                     obj->b_f->NextBorder->LeftEdge = -g->Width + 2;
  2275.                 }
  2276.             }
  2277.  
  2278.  
  2279.             /* Scroller-BorderGadget */
  2280.             obj->bordg = g = OGALLOC( ogw, sizeof( *g ) );
  2281.             if( !g )
  2282.                 return( NULL );
  2283.             g->LeftEdge = g2->LeftEdge + g2->Width;
  2284.             g->TopEdge  = g2->TopEdge;
  2285.             g->Width    = 16;
  2286.             g->Height    = g2->Height - 24;
  2287.             g->Flags    = GFLG_GADGHNONE;
  2288.             g->GadgetType = GTYP_BOOLGADGET;
  2289.             g->GadgetID      = 0x8000 | obj->id;
  2290.             g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, FALSE );
  2291.             attachborder( b, g->GadgetRender );
  2292.             obj->b_b = g->GadgetRender;
  2293.  
  2294.             g->NextGadget = g2;
  2295.             g2 = g;
  2296.  
  2297.             /* Scroller-Scroller */
  2298.             autoknobimage = OGALLOC( ogw, sizeof( *autoknobimage ) );
  2299.             if( !autoknobimage )
  2300.                 return( NULL );
  2301.             pi = OGALLOC( ogw, sizeof( *pi ) );
  2302.             if( !pi )
  2303.                 return( NULL );
  2304.             obj->scroll = g = OGALLOC( ogw, sizeof( *g ) );
  2305.             if( !g )
  2306.                 return( NULL );
  2307.             pi->Flags = PROPBORDERLESS | AUTOKNOB | FREEVERT;
  2308.             pi->VertBody = MAXBODY;
  2309.             *g = *g2;
  2310.             g->Width -= 8;
  2311.             g->LeftEdge += 4;
  2312.             g->Height -= 4;
  2313.             g->TopEdge += 2;
  2314.             g->Flags    = GFLG_GADGHCOMP;
  2315.             g->Activation = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_FOLLOWMOUSE;
  2316.             g->GadgetType = GTYP_PROPGADGET;
  2317.             g->GadgetID      = 0x9000 | obj->id;
  2318.             g->GadgetRender = autoknobimage;
  2319.             g->SpecialInfo = pi;
  2320.             g->UserData = obj;
  2321.  
  2322.             g->NextGadget = g2;
  2323.             g2 = g;
  2324.  
  2325.             /* Button-Up */
  2326.             g = OGALLOC( ogw, sizeof( *g ) );
  2327.             if( !g )
  2328.                 return( NULL );
  2329.             *g = *g2;
  2330.             g->Width = 16;
  2331.             g->LeftEdge -= 4;
  2332.             g->TopEdge += g->Height + 2;
  2333.             g->Height = 12;
  2334.             g->Flags    = GFLG_GADGHCOMP;
  2335.             g->Activation = GACT_RELVERIFY | GACT_IMMEDIATE;
  2336.             g->GadgetType = GTYP_BOOLGADGET;
  2337.             g->GadgetID      = 0xa000 | obj->id;
  2338.             g->GadgetRender = makearrowborder( ogw, g->Width, g->Height, TRUE );
  2339.             g->UserData = obj;
  2340.  
  2341.             g->NextGadget = g2;
  2342.             g2 = g;
  2343.  
  2344.             /* Button-Down  */
  2345.             g = OGALLOC( ogw, sizeof( *g ) );
  2346.             if( !g )
  2347.                 return( NULL );
  2348.             *g = *g2;
  2349.             g->TopEdge += 12;
  2350.             g->GadgetID      = 0xb000 | obj->id;
  2351.             g->GadgetRender = makearrowborder( ogw, g->Width, g->Height, FALSE );
  2352.             g->UserData = obj;
  2353.  
  2354.             g->NextGadget = g2;
  2355.             g2 = g;
  2356.  
  2357.             makelisttexts( ogw, obj );
  2358.             setlistscroller( ogw, obj );
  2359.  
  2360.             /*obj->g = g;*/
  2361.  
  2362.             break;
  2363.  
  2364.         case OGOBJ_STRING:
  2365.         case OGOBJ_INTEGER:
  2366.             xs = stextlen( ogw, obj->title );
  2367.             if( !xs )
  2368.                 xs = -4;
  2369.             posgad( g, ogw, ogg, obj, ogg->ogp ? OGPOS_EXPAND_X : OGPOS_RIGHT );
  2370.             g->TopEdge += 2;
  2371.             g->Height = ogw->used_font->tf_YSize;
  2372.             g->Width -= xs + 12;
  2373.             g->LeftEdge += xs + 8;
  2374.             g->Flags        = GFLG_GADGHCOMP | GFLG_TABCYCLE;
  2375.             if( obj->disable )
  2376.                 g->Flags |= GFLG_DISABLED;
  2377.             g->Activation    = GACT_RELVERIFY;
  2378.             if( obj->type == OGOBJ_INTEGER )
  2379.                 g->Activation |= GACT_LONGINT;
  2380.             g->GadgetType     = GTYP_STRGADGET;
  2381.             g->GadgetID     = obj->id;
  2382.             b = g->GadgetRender = makestringborder( ogw, g->Width + 8, g->Height + 4, FALSE );
  2383.             b->TopEdge = b->NextBorder->TopEdge = -2;
  2384.             b->LeftEdge= b->NextBorder->LeftEdge = -4;
  2385.             if( obj->title )
  2386.             {
  2387.                 it = makeitext( ogw, obj->title, - textlen( ogw, obj->title ) - 8, 0 );
  2388.                 g->GadgetText = it;
  2389.             }
  2390.             si = OGALLOC( ogw, sizeof( *si ) );
  2391.             if( !si )
  2392.                 return( NULL );
  2393.             g->SpecialInfo = si;
  2394.  
  2395.             si->Buffer = OGALLOC( ogw, obj->maxchars );
  2396.             if( !si->Buffer )
  2397.                 return( NULL );
  2398.             si->UndoBuffer = undobuffer;
  2399.             si->MaxChars = obj->maxchars;
  2400.             if( obj->type == OGOBJ_INTEGER )
  2401.             {
  2402.                 sprintf( si->Buffer, "%ld", obj->defaultvalue );
  2403.                 si->LongInt = obj->defaultvalue;
  2404.             }
  2405.             else
  2406.             {
  2407.                 if( obj->defaultstring )
  2408.                     stccpy( si->Buffer, obj->defaultstring, obj->maxchars );
  2409.             }
  2410.  
  2411.             /* On V37++, add StringExtend & EditHook */
  2412.             if( ISV37 )
  2413.             {
  2414.                 sex = OGALLOC( ogw, sizeof( *sex ) );
  2415.                 if( !sex )
  2416.                     return( NULL );
  2417.                 sex->Pens[0] = ogw->pens[ TEXTPEN ];
  2418.                 sex->Pens[2] = ogw->pens[ FILLTEXTPEN ];
  2419.                 sex->Pens[3] = ogw->pens[ FILLPEN ];
  2420.                 sex->InitialModes = SGM_EXITHELP;
  2421.                 if( !ogw->string_workbuffer )
  2422.                     ogw->string_workbuffer = OGALLOC( ogw, 8192 );
  2423.                 sex->WorkBuffer = ogw->string_workbuffer;
  2424.                 sex->EditHook = &stringhook;
  2425.  
  2426.                 si->Extension = sex;
  2427.                 g->Flags |= GFLG_STRINGEXTEND;
  2428.             }
  2429.             break;
  2430.  
  2431.         case OGOBJ_FUELGAUGE:
  2432.             obj->defaultstring = OGALLOC( ogw, 16 );
  2433.             if( !obj->defaultstring )
  2434.                 return( NULL );
  2435.             strcpy( obj->defaultstring, "0%" );
  2436.  
  2437.             posgad( g, ogw, ogg, obj, OGPOS_EXPAND );
  2438.             g->Flags        = GFLG_GADGHNONE;
  2439.             if( obj->disable )
  2440.                 g->Flags |= GFLG_DISABLED;
  2441.             g->GadgetType     = GTYP_BOOLGADGET;
  2442.             g->GadgetID     = obj->id;
  2443.             g->GadgetRender = makebevelborder( ogw, g->Width, g->Height, TRUE );
  2444.             g2 = g;
  2445.  
  2446.             /* Text/Image-Gadget */
  2447.             obj->im = OGALLOC( ogw, sizeof( *im ) );
  2448.             if( !obj->im )
  2449.                 return( NULL );
  2450.  
  2451.             im = OGALLOC( ogw, sizeof( *im ) );
  2452.             if( !im )
  2453.                 return( NULL );
  2454.  
  2455.             g = OGALLOC( ogw, sizeof( *g ) );
  2456.             if( !g )
  2457.                 return( NULL );
  2458.             *g = *g2;
  2459.             g->GadgetID      = 0x9000 | obj->id;
  2460.             g->Flags     |= GFLG_GADGIMAGE;
  2461.             g->GadgetRender = obj->im;
  2462.             obj->im->PlaneOnOff = ogw->pens[áFILLPEN ];
  2463.             obj->im->LeftEdge = 2;
  2464.             obj->im->TopEdge = 1;
  2465.             obj->im->Width = g->Width - 4;
  2466.             obj->im->Height = g->Height - 2;
  2467.             obj->im->Depth = ogw->scr->RastPort.BitMap->Depth;
  2468.             *im = *obj->im;
  2469.             obj->im->NextImage = im;
  2470.             im->PlaneOnOff = 0;
  2471.             obj->it_c = g->GadgetText = makeitext( ogw, obj->defaultstring, 0, 2 );
  2472.             obj->it_c->DrawMode = JAM1;
  2473.             obj->xchars = obj->im->Width;
  2474.  
  2475.             makefuelimage( ogw, obj );
  2476.  
  2477.             g->NextGadget = g2;
  2478.             obj->g = g;
  2479.  
  2480.             break;
  2481.  
  2482.         case OGOBJ_PENSEL:
  2483.             xs = stextlen( ogw, obj->title );
  2484.             /* Let Gadtools create the Gadget */
  2485.             if( ISV37 )
  2486.             {
  2487.                 initgt( ogw );
  2488.                 posnewgad( &ng, ogw, ogg, obj, OGPOS_EXPAND_X );
  2489.                 ng.ng_Width -= xs + 12 + ( ( ISV39 ) ? 0 :  24 );
  2490.                 ng.ng_LeftEdge += xs + 12 + ( ( ISV39 ) ? 0 :  24 );
  2491.                 ng.ng_GadgetID = obj->id;
  2492.                 ng.ng_UserData = obj;
  2493.                 ng.ng_Flags       = PLACETEXT_LEFT;
  2494.                 if( obj->title )
  2495.                     ng.ng_GadgetText = obj->title;
  2496.  
  2497.                 obj->num = 1 << ogw->scr->RastPort.BitMap->Depth;
  2498.  
  2499.                 obj->g = ogw->gtlastg = CreateGadget( PALETTE_KIND, ogw->gtlastg, &ng,
  2500.                     GT_Underscore, '_', 
  2501.                     GTPA_IndicatorWidth, 24, 
  2502.                     GTPA_Color, obj->defaultvalue,
  2503.                     GTPA_Depth, ogw->scr->RastPort.BitMap->Depth,
  2504.                     GA_Disabled, obj->disable,
  2505.                     TAG_DONE
  2506.                 );
  2507.                 obj->isgadtools = ogw->usesgadtools = 1;
  2508.  
  2509.                 return( NULL );
  2510.             }
  2511.             break;
  2512.     }
  2513.  
  2514.     return( g );
  2515. }
  2516.  
  2517.  
  2518. /* Create Gadget */
  2519. static void creategads( struct ogwin *ogw, struct oggroup *ogg )
  2520. {
  2521.     struct Gadget *g;
  2522.     struct ogobj *obj;
  2523.     struct IntuiText *it;
  2524.  
  2525.     /* Create Frame Gadget */
  2526.     g = OGALLOC( ogw, sizeof( *g ) );
  2527.     if( !g )
  2528.         return;
  2529.     g->LeftEdge = ogg->x + ogw->windowxoffs;
  2530.     g->TopEdge    = ogg->y + ogw->windowyoffs;
  2531.     g->Width    = g->Height = 1;
  2532.     g->Flags        = GFLG_GADGHNONE;
  2533.     g->GadgetType    = BOOLGADGET;
  2534.     g->GadgetID     = (USHORT)~0;
  2535.     if( ogg->frame )
  2536.         g->GadgetRender = makeframeborder( ogw, ogg );
  2537.  
  2538.     if( ogg->title )
  2539.     {
  2540.         it = makeitext( ogw, ogg->title, 0, 1 );
  2541.         centeritext( it, ogg->xs );
  2542.         g->GadgetText = it;
  2543.         it->DrawMode = JAM2;
  2544.     }
  2545.  
  2546.     g->NextGadget = ogw->glist;
  2547.     ogw->glist = g;
  2548.  
  2549.     /* Create Object Gadgets */
  2550.     for( obj = (struct ogobj *) ogg->obj.mlh_Head;
  2551.          obj->n.mln_Succ;
  2552.          obj = (struct ogobj *) obj->n.mln_Succ )
  2553.     {
  2554.         g = makeobj( ogw, ogg, obj );
  2555.  
  2556.         if( g )
  2557.             attachgad( g, ogw->glist );
  2558.     }
  2559.  
  2560. }
  2561.  
  2562. static void mysetreqpos( UBYTE reqpos, struct NewWindow *nw )
  2563. {
  2564.     struct Screen *scr = nw->Screen;
  2565.  
  2566.     switch( reqpos )
  2567.     {
  2568.         case 0:
  2569.         default:    // REQPOS_POINTER
  2570.             nw->LeftEdge = scr->MouseX - 10;
  2571.             nw->TopEdge = scr->MouseY - 10;
  2572.             break;
  2573.  
  2574.         case 1:        // REQPOS_CENTERWIN
  2575.             nw->LeftEdge = w->LeftEdge + ( w->Width - nw->Width ) / 2;
  2576.             nw->TopEdge = w->TopEdge + ( w->Height - nw->Height ) / 2;
  2577.             break;
  2578.  
  2579.         case 2:        // REQPOS_CENTERSCR
  2580.             nw->LeftEdge = ( scr->Width - nw->Width ) / 2;
  2581.             nw->TopEdge = ( scr->Height - nw->Height ) / 2;
  2582.             break;
  2583.  
  2584.         case 3:        // REQPOS_TOPLEFTWIN
  2585.             nw->LeftEdge = w->LeftEdge;
  2586.             nw->TopEdge = w->TopEdge;
  2587.             break;
  2588.  
  2589.         case 4:        // REQPOS_TOPLEFTSCR
  2590.             nw->LeftEdge = nw->TopEdge = 0;
  2591.             break;
  2592.     }
  2593.  
  2594.     if( nw->LeftEdge < 0 )
  2595.         nw->LeftEdge = 0;
  2596.     if( nw->TopEdge < 0 )
  2597.         nw->TopEdge = 0;
  2598.  
  2599.     if( nw->TopEdge + nw->Height >= scr->Height )
  2600.         nw->TopEdge = scr->Height - nw->Height - 1;
  2601.  
  2602.     if( nw->LeftEdge + nw->Width >= scr->Width )
  2603.         nw->LeftEdge = scr->Width - nw->Width - 1;
  2604.  
  2605.     if( nw->LeftEdge < 0 )
  2606.         nw->LeftEdge = 0;
  2607.     if( nw->TopEdge < 0 )
  2608.         nw->TopEdge = 0;
  2609.  
  2610. }
  2611.  
  2612. struct Window * ogreOpenWindow( struct ogwin *ogwin )
  2613. {
  2614.     struct oggroup *grp;
  2615.     struct NewWindow nw;
  2616.     int gx, gy;
  2617.     int doing_relayout = FALSE;
  2618.     static struct TextAttr top80 = { "topaz.font", 8, 0, 0 };
  2619.  
  2620. redo:
  2621.  
  2622.     ogwin->currentg = NULL;
  2623.     ogwin->windowxoffs = ogwin->scr->WBorLeft + 4;
  2624.     ogwin->windowyoffs = ogwin->scr->WBorTop + ogwin->font->tf_YSize + 3;
  2625.  
  2626.     /* Calculate Object Sizes */
  2627.     for( grp = (struct oggroup *) ogwin->groups.mlh_Head;
  2628.          grp->n.mln_Succ;
  2629.          grp = (struct oggroup *) grp->n.mln_Succ )
  2630.     {
  2631.         calcgroupobjs( ogwin, grp );
  2632.         layoutlist( ogwin, &grp->obj, &gx, &gy, 2 );
  2633.         grp->xs = gx;
  2634.         grp->ys = gy;
  2635.         layoutgroupframe( ogwin, grp );
  2636.     }
  2637.  
  2638.     /* We now have groups of properly formated Rectangeles */
  2639.     /* We now must perform Group ordering */
  2640.     layoutgroups( ogwin );
  2641.  
  2642.     /* Check Widths */
  2643.     nw.Width = ogwin->windowx + ogwin->scr->WBorLeft + ogwin->scr->WBorRight + 4;
  2644.     nw.Height = ogwin->windowy + ogwin->scr->WBorTop + ogwin->scr->WBorBottom + ogwin->font->tf_YSize + 4;
  2645.     nw.LeftEdge = ( ogwin->screenx - nw.Width ) / 2;
  2646.     nw.TopEdge  = ( ogwin->screeny - nw.Height ) / 2;
  2647.  
  2648.     if( nw.LeftEdge < 0 || nw.TopEdge < 0 )
  2649.     {
  2650.         if( !doing_relayout )
  2651.         {
  2652.             doing_relayout = TRUE;
  2653.             ogwin->lvfont = ogwin->used_font = OpenFont( &top80 );
  2654.             ogwin->lvfnta = ogwin->used_fnta = &top80;
  2655.             ogwin->fontxsize = 8;
  2656.             CloseFont( ogwin->used_font );
  2657.             goto redo;
  2658.         }
  2659.  
  2660.         displaybeep();
  2661.         askreq( "Fenster\n%s\nkonnte nicht ge÷ffnet werden:\nzu wenig Platz auf dem Bildschirm!", "Abbruch", ogwin->title );
  2662.         ogreExitWindow( ogwin );
  2663.         return( NULL );
  2664.     }
  2665.  
  2666.     /* Create Object Gadgets */
  2667.     for( grp = (struct oggroup *) ogwin->groups.mlh_Head;
  2668.          grp->n.mln_Succ;
  2669.          grp = (struct oggroup *) grp->n.mln_Succ )
  2670.     {
  2671.         creategads( ogwin, grp );
  2672.     }
  2673.  
  2674.     /* Attach Gadtools */
  2675.     if( ogwin->gtglist )
  2676.         attachgad( ogwin->gtglist, ogwin->glist );
  2677.  
  2678.     /* Open Window */
  2679.     memset( &nw, 0, sizeof( nw ) );
  2680.     nw.Width = ogwin->windowx + ogwin->scr->WBorLeft + ogwin->scr->WBorRight + 4;
  2681.     nw.Height = ogwin->windowy + ogwin->scr->WBorTop + ogwin->scr->WBorBottom + ogwin->font->tf_YSize + 4;
  2682.  
  2683. /*
  2684.     nw.LeftEdge = ( ogwin->screenx - nw.Width ) / 2;
  2685.     nw.TopEdge  = ( ogwin->screeny - nw.Height ) / 2;
  2686. */
  2687.  
  2688.     nw.DetailPen = ogwin->pens[ DETAILPEN ];
  2689.     nw.BlockPen = ogwin->pens[ BLOCKPENá];
  2690.     nw.Flags = ogwin->flags | WFLG_DRAGBAR | WFLG_ACTIVATE | WFLG_RMBTRAP;
  2691.     if( ogwin->flags & WFLG_ACTIVATE )
  2692.         nw.Flags &= ~WFLG_ACTIVATE;
  2693.     if( ogwin->flags & WFLG_RMBTRAP )
  2694.         nw.Flags &= ~WFLG_RMBTRAP;
  2695.  
  2696.     if( wbwindow )
  2697.         nw.Flags |= WFLG_DEPTHGADGET;
  2698.  
  2699.     nw.FirstGadget = ogwin->glist;
  2700.     nw.IDCMPFlags = ogwin->idcmp | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW;
  2701.     nw.Title = ogwin->title;
  2702.     nw.Screen = ogwin->scr;
  2703.     nw.MinWidth = 0;
  2704.     nw.MinHeight = 0;
  2705.     nw.MaxWidth    = (UWORD)~0;
  2706.     nw.MaxHeight = (UWORD)~0;
  2707.     nw.Type = CUSTOMSCREEN;
  2708.  
  2709.     mysetreqpos( prefs.reqpos, &nw );
  2710.  
  2711.     ogwin->w = OpenWindow( &nw );
  2712.  
  2713.     if( ogwin->usesgadtools )
  2714.         GT_RefreshWindow( ogwin->w, NULL );
  2715.     return( ogwin->w );
  2716. }
  2717.  
  2718. void ogreLVInit( struct ogwin *ogw, UWORD id )
  2719. {
  2720.     struct List *l = OGALLOC( ogw, sizeof( struct MinList ) );
  2721.     struct ogobj *obj = findobj( ogw, id );
  2722.  
  2723.     if( !l || !obj )
  2724.         return;
  2725.     NewList( l );
  2726.     obj->l = l;
  2727. }
  2728.  
  2729. /* Adjust top so that Item is visible */
  2730. static void adjustlv( struct ogobj *obj, int item )
  2731. {
  2732.     /* Is already visible ? */
  2733.     if( item < 0 || ( item >= obj->top && item < obj->top + obj->ychars ) )
  2734.         return;
  2735.  
  2736.     /* Zu hoch */
  2737.     if( item < obj->top )
  2738.     {
  2739.         obj->top = item;
  2740.         return;
  2741.     }
  2742.     /* Zu tief */
  2743.     obj->top = item - obj->ychars + 1;
  2744.     if( obj->top < 0 )
  2745.         obj->top = 0;
  2746.  
  2747. }
  2748.  
  2749. int ogreLVAddEntry( struct ogwin *ogw, UWORD id, char *txt, UWORD flags, void *userdata )
  2750. {
  2751.     struct ogrevn *vn;
  2752.     struct ogobj *obj;
  2753.     char *p;
  2754.     int c;
  2755.  
  2756.     obj = findobj( ogw, id );
  2757.     if( !obj )
  2758.         return( -1 );
  2759.  
  2760.     if( !obj->l )
  2761.         ogreLVInit( ogw, obj->id );
  2762.     if( !obj->l )
  2763.         return( -1 );
  2764.  
  2765.     vn = OGALLOC( ogw, sizeof( *vn ) );
  2766.     if( !vn )
  2767.         return( -1 );
  2768.  
  2769.     if( flags & 2 )
  2770.     {
  2771.         p = OGALLOC( ogw, strlen( txt ) +1 );
  2772.         if( !p )
  2773.             return( -1 );
  2774.         strcpy( p, txt );
  2775.         txt = p;
  2776.     }
  2777.  
  2778.     vn->sel = flags & 1;
  2779.     vn->txt = txt;
  2780.     vn->userdata = userdata;
  2781.  
  2782.     AddTail( obj->l, (struct Node *) vn );
  2783.  
  2784.     vn = (struct ogrevn *) vn->n.mln_Pred;
  2785.  
  2786.     c = 0;
  2787.     while( vn->n.mln_Pred )
  2788.     {
  2789.         if( !obj->flags && ( flags & 1 ) )
  2790.             vn->sel = 0;
  2791.         c++;
  2792.         vn = (struct ogrevn *) vn->n.mln_Pred;
  2793.     }
  2794.  
  2795.     if( ogw->w )
  2796.         adjustlv( obj, c );
  2797.  
  2798.     return( c );
  2799. }
  2800.  
  2801. #define isShift(im) ((im)->Qualifier&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  2802.  
  2803. static void activatenextstring( struct ogwin *ogw, struct ogobj *obj )
  2804. {
  2805.     struct Gadget *g = obj->g->NextGadget;
  2806.     int m;
  2807.  
  2808.     if( obj->top )
  2809.         return;
  2810.  
  2811.     for( ;; )
  2812.     {
  2813.         if( !g )
  2814.             g = ogw->w->FirstGadget;
  2815.  
  2816.         m = g->GadgetType & GTYP_GTYPEMASK;
  2817.         if( m == GTYP_STRGADGET && !( g->Flags & GFLG_DISABLED ) )
  2818.         {
  2819.             if( g == obj->g )
  2820.                 return;
  2821.             ActivateGadget( g, ogw->w, NULL );
  2822.             return;
  2823.         }
  2824.         g = g->NextGadget;
  2825.     }
  2826. }
  2827.  
  2828. static void lvdeselectall( struct ogobj *obj )
  2829. {
  2830.     struct ogrevn *vn = ( struct ogrevn *) obj->l->lh_Head;
  2831.  
  2832.     while( vn->n.mln_Succ )
  2833.     {
  2834.         if( vn->sel )
  2835.         {
  2836.             vn->sel = 0;
  2837.             vn->changed = 0;
  2838.         }
  2839.         vn = (struct ogrevn *) vn->n.mln_Succ;
  2840.     }
  2841. }
  2842.  
  2843. /* Draw Listview Entries */
  2844. static void drawlistviewentries( struct ogwin *ogw, struct ogobj *obj )
  2845. {
  2846.     DrawImage( ogw->w->RPort, ( struct Image *) obj->g->GadgetRender, obj->g->LeftEdge, obj->g->TopEdge );
  2847.     PrintIText( ogw->w->RPort, ( struct IntuiText *) obj->g->GadgetText, obj->g->LeftEdge, obj->g->TopEdge );
  2848. }
  2849.  
  2850. /* Draw one listview entry */
  2851. static void drawlistviewentry( struct ogwin *ogw, struct ogobj *obj, int n )
  2852. {
  2853.     struct IntuiText *it, *oldit;
  2854.     struct Image *im, *oldim;
  2855.  
  2856.     if( n < 0 || n >= obj->ychars )
  2857.         return;
  2858.     n = obj->ychars - n - 1;
  2859.  
  2860.     /* Pointer auf entsprechende Objekte holen */
  2861.     for( it = obj->it_c, im = obj->im; n && it && im; it = it->NextText, im = im->NextImage, n-- );
  2862.     if( !im || !it )
  2863.         return;
  2864.  
  2865.     /* Alte Next speichern */
  2866.     oldit = it->NextText;
  2867.     oldim = im->NextImage;
  2868.  
  2869.     it->NextText = NULL;
  2870.     im->NextImage = NULL;
  2871.  
  2872.     DrawImage( ogw->w->RPort, im, obj->g->LeftEdge, obj->g->TopEdge );
  2873.     PrintIText( ogw->w->RPort, it, obj->g->LeftEdge, obj->g->TopEdge );
  2874.  
  2875.     it->NextText = oldit;
  2876.     im->NextImage = oldim;
  2877.  
  2878. }
  2879.  
  2880. /* Optimized Redraw */
  2881. static void drawlistviewchanged( struct ogwin *ogw, struct ogobj *obj )
  2882. {
  2883.     int c;
  2884.     struct ogrevn *vn;
  2885.  
  2886.     for( c = 0; c < obj->ychars; c++ )
  2887.     {
  2888.         vn = getentry( obj, c + obj->top );
  2889.         if( vn )
  2890.         {
  2891.             if( !vn->changed )
  2892.             {
  2893.                 drawlistviewentry( ogw, obj, c );
  2894.                 vn->changed = 1;
  2895.             }
  2896.         }
  2897.     }
  2898. }
  2899.  
  2900.  
  2901. /* Einen hoch */
  2902. static void lvup( struct ogwin *ogw, struct ogobj *obj )
  2903. {
  2904.     if( !obj->top )
  2905.         return;
  2906.  
  2907.     obj->top--;
  2908.     makelisttexts( ogw, obj );
  2909.  
  2910.     ScrollRaster( ogw->w->RPort,
  2911.         0, - ( ogw->lvfont->tf_YSize + 1 ),
  2912.         obj->g->LeftEdge + 2,
  2913.         obj->g->TopEdge + 2,
  2914.         obj->g->LeftEdge + obj->xs - 19,
  2915.         obj->g->TopEdge + 2 + ( obj->ychars * ( ogw->lvfont->tf_YSize + 1 ) )
  2916.     );
  2917.  
  2918.     drawlistviewentry( ogw, obj, 0 );
  2919. }
  2920.  
  2921. /* Einen runter */
  2922. static void lvdown( struct ogwin *ogw, struct ogobj *obj )
  2923. {
  2924.     if( obj->top >= obj->num - obj->ychars )
  2925.         return;
  2926.  
  2927.     obj->top++;
  2928.     makelisttexts( ogw, obj );
  2929.  
  2930.     ScrollRaster( ogw->w->RPort,
  2931.         0, ogw->lvfont->tf_YSize + 1,
  2932.         obj->g->LeftEdge + 2,
  2933.         obj->g->TopEdge + 2,
  2934.         obj->g->LeftEdge + obj->xs - 19,
  2935.         obj->g->TopEdge + 2 + ( obj->ychars * ( ogw->lvfont->tf_YSize + 1 ) )
  2936.     );
  2937.  
  2938.     drawlistviewentry( ogw, obj, obj->ychars - 1 );
  2939. }
  2940.  
  2941. static void lvmakevisible( struct ogwin *ogw, struct ogobj *obj, int newtop )
  2942. {
  2943.     int dir, delta;
  2944.  
  2945.     delta = abs( newtop - obj->top );
  2946.     dir = obj->top > newtop;
  2947.  
  2948.     if( !delta )
  2949.         return;
  2950.  
  2951.     if( delta >= ( obj->ychars - 2 ) )
  2952.     {
  2953.         obj->top = newtop;
  2954.         makelisttexts( ogw, obj );
  2955.         RefreshGList( obj->g, ogw->w, NULL, 1 );
  2956.         return;
  2957.     }
  2958.  
  2959.     while( delta-- )
  2960.     {
  2961.         if( dir )
  2962.             lvup( ogw, obj );
  2963.         else
  2964.             lvdown( ogw, obj );
  2965.     }
  2966.  
  2967. }
  2968.  
  2969.  
  2970. /* Process ListView events */
  2971. static void dolistview( struct ogwin *ogw, struct ogobj *obj )
  2972. {
  2973.     struct Gadget *g = ogw->cim.IAddress;
  2974.     int id = g->GadgetID >> 12;
  2975.     struct PropInfo *pi = obj->scroll->SpecialInfo;
  2976.     struct IntuiMessage *im;
  2977.     int newtop, ticker, oldticker = -1;
  2978.     struct ogrevn *vn;
  2979.  
  2980.     switch( id )
  2981.     {
  2982.         /* Scroller Event */
  2983.         case 0x9:
  2984.             if( ogw->cim.Class == IDCMP_GADGETUP )
  2985.             {
  2986.                 newtop = FindScrollerTop( obj->num, obj->ychars, pi->VertPot );
  2987.                 lvmakevisible( ogw, obj, newtop );
  2988.  
  2989.             }
  2990.             /* Down or Mousemove */
  2991.             for( ;; )
  2992.             {
  2993.                 while( !( im = GetIMsg( ogw->w->UserPort ) ) )
  2994.                     mWaitPort( ogw->w->UserPort );
  2995.  
  2996.                 if( im->Class != IDCMP_MOUSEMOVE && im->Class != IDCMP_INTUITICKS )
  2997.                     break;
  2998.  
  2999.                 newtop = FindScrollerTop( obj->num, obj->ychars, pi->VertPot );
  3000.                 lvmakevisible( ogw, obj, newtop );
  3001.                 ReplyIMsg( im );
  3002.             }
  3003.             ReplyIMsg( im );
  3004.             newtop = FindScrollerTop( obj->num, obj->ychars, pi->VertPot );
  3005.             lvmakevisible( ogw, obj, newtop );
  3006.             break;
  3007.  
  3008.         /* Button Up */
  3009.         case 0xa:
  3010.             ticker = -1;
  3011.             for( ;; )
  3012.             {
  3013.                 if( ( ticker-- ) <= 0 )
  3014.                 {
  3015.                     lvup( ogw, obj );
  3016.                     setlistscroller( ogw, obj );
  3017.                     ticker = ( ticker < -1 ) ? 3 : 0;
  3018.                 }
  3019.  
  3020.                 while( !( im = GetIMsg( ogw->w->UserPort ) ) )
  3021.                     mWaitPort( ogw->w->UserPort );
  3022.  
  3023.                 if( im->Class != IDCMP_INTUITICKS )
  3024.                     break;
  3025.  
  3026.                 ReplyIMsg( im );
  3027.             } 
  3028.             ReplyIMsg( im );
  3029.             break;
  3030.  
  3031.         /* Button Up */
  3032.         case 0xb:
  3033.             ticker = -1;
  3034.             for( ;; )
  3035.             {
  3036.                 if( ( ticker-- ) <= 0 )
  3037.                 {
  3038.                     lvdown( ogw, obj );
  3039.                     setlistscroller( ogw, obj );
  3040.                     ticker = ( ticker < -1 ) ? 3 : 0;
  3041.                 }
  3042.  
  3043.                 while( !( im = GetIMsg( ogw->w->UserPort ) ) )
  3044.                     mWaitPort( ogw->w->UserPort );
  3045.  
  3046.                 if( im->Class != IDCMP_INTUITICKS )
  3047.                     break;
  3048.  
  3049.                 ReplyIMsg( im );
  3050.             } 
  3051.             ReplyIMsg( im );
  3052.             break;
  3053.  
  3054.         /* Select */
  3055.         case 0x0:
  3056.             if( ogw->cim.Class != IDCMP_GADGETDOWN )
  3057.                 break;
  3058.  
  3059.             while( ogw->cim.Class != IDCMP_GADGETUP && ogw->cim.Class != IDCMP_MOUSEBUTTONS )
  3060.             {
  3061.                 if( ogw->cim.MouseX <= g->LeftEdge + 4 ||
  3062.                     ogw->cim.MouseY <= g->TopEdge + 2 ||
  3063.                     ogw->cim.MouseX >= g->LeftEdge + g->Width - 8 ||
  3064.                     ogw->cim.MouseY >= g->TopEdge + g->Height - 4 )
  3065.                         goto redo;
  3066.                 ticker = ( ogw->cim.MouseY - g->TopEdge - 2 ) / ( ogw->lvfont->tf_YSize + 1 );
  3067.                 if( ticker != oldticker )
  3068.                 {
  3069.                     oldticker = ticker;
  3070.                     vn = getentry( obj, obj->top + ticker );
  3071.                     if( vn )
  3072.                     {
  3073.                         obj->defaultvalue = obj->top + ticker;
  3074.                         obj->minval = obj->top + ticker;
  3075.                         /* Do Multi Select */
  3076.                         if( obj->flags && isShift( ( &ogw->cim ) ) )
  3077.                         {
  3078.                             vn->sel ^= 1;
  3079.                             makelisttexts( ogw, obj );
  3080.                             drawlistviewentry( ogw, obj, ticker );
  3081.                             /*RefreshGList( obj->g, ogw->w, NULL, 1 );*/
  3082.                         }
  3083.                         else
  3084.                         {
  3085.                             if( !vn->sel || obj->flags )
  3086.                             {
  3087.                                 lvdeselectall( obj );
  3088.                                 vn->sel = 1;
  3089.                                 vn->changed = 0;
  3090.                                 makelisttexts( ogw, obj );
  3091.                                 drawlistviewchanged( ogw, obj );
  3092.                                 /*RefreshGList( obj->g, ogw->w, NULL, 1 );*/
  3093.                             }
  3094.                         }
  3095.                     }
  3096.                 }
  3097. redo:
  3098.                 ogw->cim.Class = 0;
  3099.                 while( ogw->cim.Class != IDCMP_MOUSEBUTTONS && ogw->cim.Class != IDCMP_MOUSEMOVE && ogw->cim.Class != IDCMP_GADGETUP )
  3100.                 {
  3101.                     while( ! ( im = GetIMsg( ogw->w->UserPort ) ) )
  3102.                         mWaitPort( ogw->w->UserPort );
  3103.                     ogw->cim = *im;
  3104.                     ReplyIMsg( im );
  3105.                 }
  3106.             }
  3107.             ogw->cim.Class = IDCMP_GADGETUP;
  3108.             ogw->cim.Qualifier = 2;
  3109.             return;
  3110.  
  3111.     }
  3112.  
  3113.     ogw->cim.Class = 0;
  3114. }
  3115.  
  3116.  
  3117. /* Process LV shortcut */
  3118. static void dolvshortcut( struct ogwin *ogw, struct ogobj *obj )
  3119. {
  3120.     int c, n;
  3121.     struct ogrevn *vn;
  3122.  
  3123.     /* Standard select next/last */
  3124.     if( obj->shortcut != 0xff )
  3125.     {
  3126.         c = getfirstselentry( obj );
  3127.         n = getnumentries( obj );
  3128.  
  3129.         if( isShift( &ogw->cim ) )
  3130.             c--;
  3131.         else
  3132.             c++;
  3133.  
  3134.         if( c < 0 )
  3135.             c = n - 1;
  3136.         if( c >= n )
  3137.             c = 0;
  3138.  
  3139.         if( c >= 0)
  3140.         {
  3141.             lvdeselectall( obj );
  3142.             vn = getentry( obj, c );
  3143.             obj->minval = c;
  3144.             if( vn )
  3145.             {
  3146.                 if( !vn->sel )
  3147.                 {
  3148.                     vn->sel = 1;
  3149.                     vn->changed = 0;
  3150.                 }
  3151.             }
  3152.             adjustlv( obj, c );
  3153.             makelisttexts( ogw, obj );
  3154.             drawlistviewchanged( ogw, obj );
  3155.             setlistscroller( ogw, obj );
  3156.         }
  3157.  
  3158.     }
  3159.  
  3160. }
  3161.  
  3162. /* Process Cursor LV */
  3163. static int dolvcursorshortcut( struct ogwin *ogw, struct ogobj *obj )
  3164. {
  3165.     int c, d, e, n, rc = 0;
  3166.     struct ogrevn *vn = NULL;
  3167.     BOOL isshift = ogw->cim.Qualifier & ( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT );
  3168.     BOOL isctrl  = ogw->cim.Qualifier & IEQUALIFIER_CONTROL;
  3169.  
  3170.     /* Standard select next/last */
  3171.     n = getnumentries( obj );
  3172.     c = e = obj->defaultvalue;
  3173.  
  3174.     switch( ogw->cim.Code )
  3175.     {
  3176.  
  3177.         case 0x3d:    /* Home */
  3178.             isctrl = TRUE;
  3179.  
  3180.         case 0x3f:    /* Seitenweise */
  3181.             isshift = TRUE;
  3182.  
  3183.         case 0x3e:
  3184.         case 0x4c:
  3185.             if( isshift )
  3186.                 c -= obj->ychars;
  3187.             if( isctrl )
  3188.                 c = 0;
  3189.             else
  3190.                 c--;
  3191.             break;
  3192.  
  3193.         case 0x1d:    /* Home */
  3194.             isctrl = TRUE;
  3195.  
  3196.         case 0x1f:    /* Seitenweise */
  3197.             isshift = TRUE;
  3198.  
  3199.         case 0x1e:
  3200.         case 0x4d:
  3201.             if( isshift )
  3202.                 c += obj->ychars;
  3203.             if( isctrl )
  3204.                 c = MAXINT;
  3205.             else
  3206.                 c++;
  3207.             break;
  3208.  
  3209.         case 0x44:
  3210.         case 0x43: 
  3211.             if( obj->flags && ( getfirstselentry( obj ) != -1 ) )
  3212.             {
  3213.                 rc = 2;
  3214.                 break;
  3215.             }
  3216.             rc = 1;
  3217.         case 0x40:
  3218.             rc++;
  3219.             vn = getentry( obj, c );
  3220.             obj->minval = c;
  3221.             if( !obj->flags )
  3222.                 lvdeselectall( obj );
  3223.             if( vn )
  3224.             {
  3225.                 vn->sel ^= 1;
  3226.                 vn->changed = 0;
  3227.             }
  3228.             break;
  3229.  
  3230.         default:
  3231.             return( rc );
  3232.     }
  3233.  
  3234.     if( c < 0 )
  3235.         c = 0;
  3236.     if( c >= n )
  3237.         c = n - 1;
  3238.  
  3239.     if( c >= 0)
  3240.     {
  3241.         d = obj->top;
  3242.         obj->defaultvalue = c;
  3243.         adjustlv( obj, c );
  3244.         /* Kein Scrolling */
  3245.         if( ( obj->top ) == d && !vn )
  3246.         {
  3247.             makelisttexts( ogw, obj );
  3248.             drawlistviewentry( ogw, obj, e - obj->top );
  3249.         }
  3250.         else
  3251.         {
  3252.             if( !vn )
  3253.             {
  3254.                 c = obj->top;
  3255.                 obj->top = d;
  3256.                 drawlistviewentry( ogw, obj, e - obj->top );
  3257.                 lvmakevisible( ogw, obj, c );
  3258.             }
  3259.             else
  3260.             {
  3261.                 makelisttexts( ogw, obj );
  3262.                 drawlistviewentries( ogw, obj );
  3263.             }
  3264.         }
  3265.         setlistscroller( ogw, obj );
  3266.         DrawBorder( ogw->w->RPort, obj->bordg->GadgetRender, obj->bordg->LeftEdge, obj->bordg->TopEdge );
  3267.     }
  3268.     return( rc );
  3269. }
  3270.  
  3271. static void replyimsg( struct ogwin *ogw, struct IntuiMessage *im )
  3272. {
  3273.     if( im && im != &ogw->cim )
  3274.         ReplyIMsg( im );
  3275. }
  3276.  
  3277. struct ogobj *findobjbyshortcut( struct ogwin *ogw, int rks )
  3278. {
  3279.     struct Gadget *g;
  3280.     struct ogobj *obj, *obj_onesc = NULL, *obj_onenter = NULL;
  3281.  
  3282.     /* Zuerst nach 1:1-Uebereinstimmung suchen */
  3283.     g = ogw->w->FirstGadget;
  3284.     /* Alle Gadgets durchgehen */
  3285.     while( g )
  3286.     {
  3287.         obj = g->UserData;
  3288.         if( obj )
  3289.         {
  3290.             if( obj->shortcut == rks )
  3291.                 return( obj );
  3292.  
  3293.             if( obj->on_esc )
  3294.                 obj_onesc = obj;
  3295.             if( obj->on_enter )
  3296.                 obj_onenter = obj;
  3297.  
  3298.         }
  3299.         g = g->NextGadget;
  3300.     }
  3301.     /* Dann ungeshiftet suchen */
  3302.     if( ! ( rks & 0x80 ) )
  3303.         goto shubbi;
  3304.     rks &= 0x7f;
  3305.     g = ogw->w->FirstGadget;
  3306.     while( g )
  3307.     {
  3308.         obj = g->UserData;
  3309.         if( obj )
  3310.         {
  3311.             if( obj->shortcut == rks )
  3312.                 return( obj );
  3313.         }
  3314.         g = g->NextGadget;
  3315.     }
  3316.  
  3317. shubbi:
  3318.  
  3319.     /* Keine ▄bereinstimmung, Enter/ESC? */
  3320.     if( ( rks == 0x45 ) || ( rks == 0x5d ) || ( rks == 0x0f ) )
  3321.         return( obj_onesc );
  3322.     else if( rks == 0x43 )
  3323.         return( obj_onenter );
  3324. /*    else if( rks == 0x5f )
  3325.         return( ogw->helpgad );*/
  3326.  
  3327.     return( NULL );
  3328. }
  3329.  
  3330. static void drawimage( struct ogwin *ogw, struct ogobj *obj, BOOL sel )
  3331. {
  3332.     struct Gadget *g = obj->g;
  3333.  
  3334.     /* unter V37 einfach nur invertieren */
  3335.     if( ! ( obj->isgadtools ) )
  3336.     {
  3337.         ClipBlit( ogw->w->RPort, g->LeftEdge, g->TopEdge,
  3338.                   ogw->w->RPort, g->LeftEdge, g->TopEdge,
  3339.                   g->Width, g->Height, 0x50 );
  3340.         return;
  3341.     }
  3342.  
  3343.     DrawImageState( ogw->w->RPort, g->GadgetRender, g->LeftEdge, g->TopEdge, sel ? IDS_SELECTED : IDS_NORMAL, ogw->dri );
  3344. }
  3345.  
  3346.  
  3347. struct IntuiMessage *ogreIM( struct ogwin *ogw )
  3348. {
  3349.     struct IntuiMessage *im;
  3350.     struct ogobj *obj;
  3351.     struct Gadget *g;
  3352.     long val;
  3353.     int c;
  3354.     int rks;
  3355.  
  3356.     if( ogw->usesgadtools )
  3357.         im = GT_GetIMsg( ogw->w->UserPort );
  3358.     else
  3359.         im = GetIMsg( ogw->w->UserPort );
  3360.     if( !im )
  3361.         return( NULL );
  3362.  
  3363.     if( im->IDCMPWindow != ogw->w )
  3364.         return( im );
  3365.  
  3366.     if( im->Class == IDCMP_REFRESHWINDOW )
  3367.     {
  3368.         if( ogw->usesgadtools )
  3369.         {
  3370.             GT_BeginRefresh( ogw->w );
  3371.             GT_EndRefresh( ogw->w, TRUE );
  3372.         }
  3373.         else
  3374.         {
  3375.             BeginRefresh( ogw->w );
  3376.             EndRefresh( ogw->w, TRUE );
  3377.         }
  3378.     }
  3379.  
  3380.     if( im->Class == IDCMP_INTUITICKS )
  3381.     {
  3382.         replyimsg( ogw, im );
  3383.         return( NULL );
  3384.     }
  3385.  
  3386.     /* Rawkey-Event */
  3387.     if( im->Class == IDCMP_RAWKEY )
  3388.     {
  3389.         rks = im->Code;
  3390.  
  3391.         /* Down */
  3392.         if( ( rks != 0x5f ) && ( ! ( rks & 0x80 ) ) )
  3393.         {
  3394.             /* Eventuell Cursor-Listview ? */
  3395.             if( ogw->hascursorlv &&
  3396.                 ( im->Code == 0x4c || im->Code == 0x4d || im->Code == 0x40 || im->Code == 0x43 || im->Code == 0x44 ||
  3397.                 ( im->Code >= 0x1d && im->Code <= 0x1f ) ||
  3398.                 ( im->Code >= 0x3d && im->Code <= 0x3f ) ) )
  3399.             {
  3400.                 ogw->cim = *im;
  3401.                 replyimsg( ogw, im );
  3402.                 im = &ogw->cim;
  3403.                 obj = findobj( ogw, ogw->hascursorlv );
  3404.                 c = dolvcursorshortcut( ogw, obj );
  3405.                 if( c )
  3406.                 {
  3407.                     im->Qualifier = ( c == 2 ) ? 1 : 0;
  3408.                     im->Class = GADGETUP;
  3409.                     im->Code = obj->id;
  3410.                     return( im );
  3411.                 }
  3412.                 return( NULL );
  3413.             }
  3414.  
  3415.             if( isShift( im ) )    rks |= 0x80;
  3416.             ogw->cim = *im;
  3417.             replyimsg( ogw, im );
  3418.             im = &ogw->cim;
  3419.             obj = findobjbyshortcut( ogw, rks );
  3420.             if( !obj || obj->disable || ( obj->type != OGOBJ_BUTTON && obj->type != OGOBJ_CYCLE && obj->type != OGOBJ_CHECKBOX && obj->type != OGOBJ_LIST && obj->type != OGOBJ_PENSEL ) )
  3421.                 return( im );
  3422.  
  3423.             ogw->has_down = TRUE;
  3424.  
  3425.             rks &= 0x7f;
  3426.  
  3427.             drawimage( ogw, obj, TRUE );
  3428.  
  3429.             c = TRUE;
  3430.  
  3431.             /* Weiterwarten... */
  3432.             for(;;)
  3433.             {
  3434.                 while( ! ( im = GetIMsg( ogw->w->UserPort ) ) )
  3435.                     mWaitPort( ogw->w->UserPort );
  3436.                 if( im->Class == RAWKEY )
  3437.                 {
  3438.                     /* Aborted? */
  3439.                     if( im->Code < 0x80 && im->Code != rks && c )
  3440.                     {
  3441.                         drawimage( ogw, obj, FALSE );
  3442.                         c = FALSE;
  3443.                         ogw->has_down = FALSE;
  3444.                     }
  3445.                     if( im->Code == ( rks | 0x80 ) )
  3446.                         break;
  3447.                 }
  3448.                 ReplyIMsg( im );
  3449.             }
  3450.  
  3451.             ogw->cim = *im;
  3452.             ReplyIMsg( im );
  3453.             im = &ogw->cim;
  3454.  
  3455.             if( c )
  3456.             {
  3457.                 drawimage( ogw, obj, FALSE );
  3458.                 goto processkey;
  3459.             }
  3460.             
  3461.             return( NULL );
  3462.         }
  3463.         /* Gadget-Help */
  3464.         if( rks == 0x5f )
  3465.         {
  3466.             g = ogw->w->FirstGadget;
  3467.  
  3468.             while( g )
  3469.             {
  3470.                 if( ( obj = g->UserData ) &&
  3471.                     im->MouseX >= g->LeftEdge &&
  3472.                     im->MouseY >= g->TopEdge &&
  3473.                     im->MouseX < g->LeftEdge + g->Width &&
  3474.                     im->MouseY < g->TopEdge + g->Height )
  3475.                 {
  3476. redo:
  3477.                     ogw->cim = *im;
  3478.                     replyimsg( ogw, im );
  3479.                     im = &ogw->cim;
  3480.                     im->Class = IDCMP_GADGETHELP;
  3481.                     if( obj->id == OGID_HELP )
  3482.                         im->Code = (USHORT) -1;
  3483.                     else
  3484.                         im->Code = obj->id;
  3485.                     return( im );
  3486.                 }
  3487.                 g = g->NextGadget;
  3488.             }
  3489.  
  3490.             ogw->cim = *im;
  3491.             replyimsg( ogw, im );
  3492.             im = &ogw->cim;
  3493.             im->Class = IDCMP_GADGETHELP;
  3494.             im->Code = ( USHORT ) -1;
  3495.             return( im );
  3496.         }
  3497.         rks &= 0x7f;
  3498.  
  3499. processkey:
  3500.         if( isShift( im ) )    rks |= 0x80;
  3501.         obj = findobjbyshortcut( ogw, rks );
  3502.         if( obj )
  3503.         {
  3504.             ogw->cim = *im;
  3505.             replyimsg( ogw, im );
  3506.             im = &ogw->cim;
  3507.             im->IAddress = obj->g;
  3508.             g = obj->g;
  3509.             if( obj->disable )
  3510.                 return( NULL );
  3511.             if( ( g->GadgetType & GTYP_GTYPEMASK ) == GTYP_STRGADGET )
  3512.             {
  3513.                 ActivateGadget( obj->g, ogw->w, NULL );
  3514.                 return( NULL );
  3515.             }
  3516.             else
  3517.             {
  3518.                 if( !ogw->has_down )
  3519.                     return( NULL );
  3520.                 ogw->has_down = FALSE;
  3521.                 if( obj->type == OGOBJ_CHECKBOX )
  3522.                 {
  3523.                     if( obj->isgadtools )
  3524.                     {
  3525.                         obj->defaultvalue = !obj->defaultvalue;
  3526.                         GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCB_Checked, obj->defaultvalue, TAG_DONE );
  3527.                     }
  3528.                     else
  3529.                     {
  3530.                         g->Flags ^= GFLG_SELECTED;
  3531.                         RefreshGList( obj->g, ogw->w, NULL, 1 );
  3532.                     }
  3533.                 }
  3534.                 else if( obj->type == OGOBJ_LIST )
  3535.                 {
  3536.                     dolvshortcut( ogw, obj );
  3537.                 }
  3538.                 else if( obj->type == OGOBJ_CYCLE && obj->isgadtools )
  3539.                 {
  3540.                     c = obj->defaultvalue;
  3541.                     if( isShift( im ) )
  3542.                         c--;
  3543.                     else
  3544.                         c++;
  3545.                     if( c < 0 )
  3546.                         c = obj->num -1;
  3547.                     if( c >= obj->num )
  3548.                         c = 0;
  3549.                     obj->defaultvalue = c;
  3550.                     GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCY_Active, c, TAG_DONE );
  3551.                     im->Class = IDCMP_GADGETUP;
  3552.                     im->Code  = obj->id;
  3553.                     return( im );
  3554.                 }
  3555.                 else if( obj->type == OGOBJ_PENSEL && obj->isgadtools )
  3556.                 {
  3557.                     c = obj->defaultvalue;
  3558.                     if( isShift( im ) )
  3559.                         c--;
  3560.                     else
  3561.                         c++;
  3562.                     if( c < 0 )
  3563.                         c = obj->num -1;
  3564.                     if( c >= obj->num )
  3565.                         c = 0;
  3566.                     obj->defaultvalue = c;
  3567.                     GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTPA_Color, c, TAG_DONE );
  3568.                     im->Class = IDCMP_GADGETUP;
  3569.                     im->Code  = obj->id;
  3570.                     return( im );
  3571.                 }
  3572.                 im->Class = GADGETUP;
  3573.                 goto doevent;
  3574.             }
  3575.         }
  3576.     }
  3577.  
  3578.  
  3579.     if ( ! ( im->Class & ( IDCMP_GADGETUP | IDCMP_GADGETDOWN ) ) )
  3580.         return( im );
  3581.  
  3582.     g = (struct Gadget *) im->IAddress;
  3583.     obj = g->UserData;
  3584.  
  3585.     if( !obj )
  3586.         return( im );
  3587.  
  3588.     /* Event kopieren */
  3589.     ogw->cim = *im;
  3590.     replyimsg( ogw, im );
  3591.     im = &ogw->cim;
  3592.  
  3593. doevent:
  3594.     switch( obj->type )
  3595.     {
  3596.         case OGOBJ_BUTTON:
  3597.             if( obj->shortcut == 0x5f )
  3598.             {
  3599.                 im->Class = IDCMP_GADGETHELP;
  3600.                 im->Code = ( USHORT ) -1;
  3601.                 return( im );
  3602.             }
  3603.             break;
  3604.  
  3605.         case OGOBJ_PENSEL:
  3606.             obj->defaultvalue = im->Code;
  3607.             break;
  3608.  
  3609.         case OGOBJ_CHECKBOX:
  3610.             obj->defaultvalue = ( obj->g->Flags & GFLG_SELECTED );
  3611.             im->Class = IDCMP_GADGETUP;
  3612.             break;
  3613.  
  3614.         case OGOBJ_CYCLE:
  3615.             if( obj->isgadtools )
  3616.             {
  3617.                 obj->defaultvalue = im->Code;
  3618.                 break;
  3619.             }
  3620.             if( isShift( im ) )
  3621.                 obj->defaultvalue--;
  3622.             else
  3623.                 obj->defaultvalue++;
  3624.             makecycletext( ogw, obj );
  3625.             RefreshGList( obj->g, ogw->w, NULL, 1 );
  3626.             break;
  3627.  
  3628.         case OGOBJ_STRING:
  3629.         case OGOBJ_INTEGER:
  3630.             /* Exit-Help */
  3631.             if( im->Class == IDCMP_GADGETUP && im->Code == 0x5f )
  3632.             {
  3633.                 im->Class = IDCMP_GADGETHELP;
  3634.                 im->Code = obj->id;
  3635.                 break;
  3636.             }
  3637.             if( im->Class == IDCMP_GADGETUP && im->Code == 0x70 )
  3638.             {
  3639.                 break;
  3640.             }
  3641.             /* Minval/Maxval prⁿfen */
  3642.             if( obj->type == OGOBJ_INTEGER )
  3643.             {
  3644.                 val = ( ( struct StringInfo *) obj->g->SpecialInfo ) -> LongInt;
  3645.                 if( val < obj->minval || val > obj->maxval )
  3646.                 {
  3647.                     DisplayBeep( ogw->scr );
  3648.                     if( val < obj->minval )
  3649.                         val = obj->minval;
  3650.                     else
  3651.                         val = obj->maxval;
  3652.                     sprintf( ( ( struct StringInfo *) obj->g->SpecialInfo )->Buffer, "%ld", val );
  3653.                     ( ( struct StringInfo *) obj->g->SpecialInfo )->LongInt = val;
  3654.                     RefreshGList( obj->g, ogw->w, NULL, 1 );
  3655.                     ActivateGadget( obj->g, ogw->w, NULL );
  3656.                     break;
  3657.                 }
  3658.  
  3659.             }
  3660.  
  3661.             if( isShift( im ) )
  3662.             {
  3663.                 break;
  3664.             }
  3665.  
  3666.             /* NΣchstes aktivieren */
  3667.             activatenextstring( ogw, obj );
  3668.             break;
  3669.  
  3670.         case OGOBJ_LIST:
  3671.             dolistview( ogw, obj );
  3672.             break;
  3673.  
  3674.     }
  3675.     im->Code = obj->id;
  3676.     return( im->Class ? im : NULL );
  3677. }
  3678.  
  3679. void ogreIMReply( struct ogwin *ogw, struct IntuiMessage *im )
  3680. {
  3681.     replyimsg( ogw, im );
  3682. }
  3683.  
  3684. void __stdargs ogreEnable( struct ogwin *ogw, BOOL set, ULONG id1, ...)
  3685. {
  3686.     struct ogobj *obj;
  3687.     ULONG *p = &id1;
  3688.  
  3689.     set = !set;
  3690.     if( ogw->w )
  3691.     {
  3692.         while( *p )
  3693.         {
  3694.             obj = findobj( ogw, *p++ );
  3695.             if( !obj )
  3696.                 continue;
  3697.             if( ( obj->disable && set ) || ( !obj->disable && !set ) )
  3698.                 continue;
  3699.             obj->disable = set;
  3700.             if( obj->isgadtools )
  3701.             {
  3702.                 GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GA_Disabled, set, TAG_DONE );
  3703.             }
  3704.             else
  3705.             {
  3706.                 if( !set )
  3707.                 {
  3708.                     obj->g->Flags &= ~GFLG_DISABLED;
  3709.                     SetAPen( ogw->w->RPort, 0 );
  3710.                     RectFill( ogw->w->RPort, obj->g->LeftEdge, obj->g->TopEdge, obj->g->LeftEdge + obj->g->Width - 1, obj->g->TopEdge + obj->g->Height - 1 );
  3711.                     RefreshGList( obj->g, ogw->w, NULL, 1 );
  3712.                     /*OnGadget( obj->g, ogw->w, NULL );*/
  3713.                 }
  3714.                 else
  3715.                 {
  3716.                     obj->g->Flags |= GFLG_DISABLED;
  3717.                     RefreshGList( obj->g, ogw->w, NULL, 1 );
  3718.                 }
  3719.             }
  3720.         }
  3721.     }
  3722.     else
  3723.     {
  3724.         while( *p )
  3725.         {
  3726.             obj = findobj( ogw, *p++ );
  3727.             if( !obj )
  3728.                 continue;
  3729.             obj->disable = set;
  3730.         }
  3731.  
  3732.     }
  3733.     return;
  3734. }
  3735.  
  3736. LONG ogreValue( struct ogwin *ogw, UWORD id )
  3737. {
  3738.     struct ogobj *obj = findobj( ogw, id );
  3739.  
  3740.     if( !obj )
  3741.         return( 0 );
  3742.  
  3743.     switch( obj->type )
  3744.     {
  3745.         case OGOBJ_CHECKBOX:
  3746.             obj->defaultvalue = obj->g->Flags & GFLG_SELECTED;
  3747.             return( ( LONG ) obj->defaultvalue );
  3748.     
  3749.         case OGOBJ_CYCLE:
  3750.         case OGOBJ_PENSEL:
  3751.             return( ( LONG ) obj->defaultvalue );
  3752.  
  3753.         case OGOBJ_LIST:
  3754.             return( getfirstselentry( obj ) );
  3755.  
  3756.         case OGOBJ_INTEGER:
  3757.             return( ( ( struct StringInfo *) obj->g->SpecialInfo ) -> LongInt );
  3758.  
  3759.         case OGOBJ_STRING:
  3760.             return( ( LONG ) ( ( struct StringInfo *) obj->g->SpecialInfo ) -> Buffer );
  3761.  
  3762.     }
  3763.     return( 0 );
  3764. }
  3765.  
  3766. void ogreSetValue( struct ogwin *ogw, UWORD id, LONG val )
  3767. {
  3768.     struct ogobj *obj = findobj( ogw, id );
  3769.     int c, d;
  3770.  
  3771.     if( !obj )
  3772.         return;
  3773.  
  3774.     switch( obj->type )
  3775.     {
  3776.         case OGOBJ_CHECKBOX:
  3777.             obj->defaultvalue = val;
  3778.             if( obj->isgadtools )
  3779.             {
  3780.                 GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCB_Checked, val, TAG_DONE );
  3781.             }
  3782.             else
  3783.             {
  3784.                 if( val )
  3785.                     obj->g->Flags |= GFLG_SELECTED;
  3786.                 else
  3787.                     obj->g->Flags &= ~GFLG_SELECTED;
  3788.                 RefreshGList( obj->g, ogw->w, NULL, 1 );
  3789.             }
  3790.             return;
  3791.     
  3792.         case OGOBJ_CYCLE:
  3793.             obj->defaultvalue = val;
  3794.             if( obj->isgadtools )
  3795.             {
  3796.                 GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTCY_Active, val, TAG_DONE );
  3797.             }
  3798.             else
  3799.             {
  3800.                 makecycletext( ogw, obj );
  3801.                 RefreshGList( obj->g, ogw->w, NULL, 1 );
  3802.             }
  3803.             return;
  3804.  
  3805.         case OGOBJ_LIST:
  3806.             adjustlv( obj, val );
  3807.             makelisttexts( ogw, obj );
  3808.             drawlistviewentries( ogw, obj );
  3809.             setlistscroller( ogw, obj );
  3810.             return;
  3811.  
  3812.         case OGOBJ_INTEGER:
  3813.             sprintf( ( ( struct StringInfo *) obj->g->SpecialInfo )->Buffer, "%ld", val );
  3814.             ( ( struct StringInfo *) obj->g->SpecialInfo )->LongInt = val;
  3815.             RefreshGList( obj->g, ogw->w, NULL, 1 );
  3816.             return;
  3817.  
  3818.         case OGOBJ_STRING:
  3819.             stccpy( ( ( struct StringInfo *) obj->g->SpecialInfo )->Buffer, (char *) val, obj->maxchars );
  3820.             RefreshGList( obj->g, ogw->w, NULL, 1 );
  3821.             return;
  3822.  
  3823.         case OGOBJ_TEXT:
  3824.             if( !strcmp( obj->defaultstring, (char *) val ) )
  3825.                 break;
  3826.             c = IntuiTextLength( obj->it_c );
  3827.             d = textfit( ogw, (char *) val, obj->g->Width - 16 );
  3828.             d = min( d, 255 );
  3829.             memcpy( obj->defaultstring, (char *) val, d );
  3830.             obj->defaultstring[ d ] = 0;
  3831.             d = IntuiTextLength( obj->it_c );
  3832.  
  3833.             if( c >= d )
  3834.             {
  3835.                 SetAPen( ogw->w->RPort, 0 );
  3836.                 SetDrMd( ogw->w->RPort, JAM1 );
  3837.                 RectFill( ogw->w->RPort, obj->g->LeftEdge + obj->it_c->LeftEdge + d - 1, obj->g->TopEdge + 2, obj->g->LeftEdge + obj->g->Width - 3, obj->g->TopEdge + obj->g->Height - 2 );
  3838.             }
  3839.             /*RefreshGList( obj->g, ogw->w, NULL, 1 );*/
  3840.             PrintIText( ogw->w->RPort, obj->it_c, obj->g->LeftEdge, obj->g->TopEdge);
  3841.             break;
  3842.  
  3843.         case OGOBJ_PENSEL:
  3844.             if( obj->defaultvalue == val )
  3845.                 break;
  3846.             obj->defaultvalue = val;
  3847.             if( ISV37 )
  3848.             {
  3849.                 GT_SetGadgetAttrs( obj->g, ogw->w, NULL, GTPA_Color, obj->defaultvalue, TAG_DONE );
  3850.             }
  3851.             break;
  3852.  
  3853.         case OGOBJ_FUELGAUGE:
  3854.             if( obj->defaultvalue != val )
  3855.             {
  3856.                 obj->defaultvalue = val;
  3857.                 if( makefuelimage( ogw, obj ) )
  3858.                     RefreshGList( obj->g, ogw->w, NULL, 1 );
  3859.             }
  3860.             break;
  3861.     }
  3862. }
  3863.  
  3864. void ogreActivate( struct ogwin *ogw, UWORD id )
  3865. {
  3866.     struct ogobj *obj = findobj( ogw, id );
  3867.  
  3868.     if( !obj )
  3869.         return;
  3870.  
  3871.     if( obj->type != OGOBJ_STRING && obj->type != OGOBJ_INTEGER )
  3872.         return;
  3873.  
  3874.     ActivateGadget( obj->g, ogw->w, NULL );
  3875.  
  3876. }
  3877.  
  3878. struct ogrevn * ogreLVGetEntry( struct ogwin *ogw, UWORD id, int num )
  3879. {
  3880.     struct ogobj *obj = findobj( ogw, id );
  3881.     struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
  3882.  
  3883.     while( vn->n.mln_Succ )
  3884.     {
  3885.         if( !num-- )
  3886.             return( vn );
  3887.         vn = (struct ogrevn *) vn->n.mln_Succ;
  3888.     }
  3889.     return( NULL );
  3890. }
  3891.  
  3892. void ogreLVRefresh( struct ogwin *ogw, UWORD id )
  3893. {
  3894.     struct ogobj *obj = findobj( ogw, id );
  3895.  
  3896.     if( obj && obj->type == OGOBJ_LIST )
  3897.     {
  3898.         makelisttexts( ogw, obj );
  3899.         drawlistviewentries( ogw, obj );
  3900.         setlistscroller( ogw, obj );
  3901.     }
  3902. }
  3903.  
  3904. void ogreLVRemEntry( struct ogwin *ogw, UWORD id, int num )
  3905. {
  3906. /*    struct ogobj *obj = findobj( ogw, id );*/
  3907.     struct ogrevn *vn = ogreLVGetEntry( ogw, id, num );
  3908.  
  3909.     if( vn )
  3910.     {
  3911.         Remove( (struct Node *) vn );
  3912.     }
  3913. }
  3914.  
  3915. void ogreLVSetEntry( struct ogwin *ogw, UWORD id, int num, char *txt, UWORD flags )
  3916. {
  3917.     struct ogobj *obj = findobj( ogw, id );
  3918.     char *p;    
  3919.     struct ogrevn *vn = ogreLVGetEntry( ogw, id, num );
  3920.  
  3921.     if( ( flags & 1 ) && ! ( obj->flags ) )
  3922.         lvdeselectall( obj );
  3923.  
  3924.     if( vn )
  3925.     {
  3926.         vn->sel = flags & 1;
  3927.         vn->changed = 0;
  3928.         if( flags & 2 )
  3929.         {
  3930.             if( strlen( txt ) < strlen( vn->txt ) )
  3931.             {
  3932.                 strcpy( vn->txt, txt );
  3933.             }
  3934.             else
  3935.             {
  3936.                 p = OGALLOC( ogw, strlen( txt ) + 1 );
  3937.                 if( !p )
  3938.                     return;
  3939.                 strcpy( p, txt );
  3940.                 vn->txt = p;
  3941.             }
  3942.         }
  3943.         else
  3944.             vn->txt = txt;
  3945.     }
  3946. }
  3947.  
  3948. void ogreLVSetActive( struct ogwin *ogw, UWORD id, int num )
  3949. {
  3950.     struct ogobj *obj = findobj( ogw, id );
  3951.  
  3952.     if( obj )
  3953.     {
  3954.         obj->defaultvalue = num;
  3955.         adjustlv( obj, num );
  3956.         makelisttexts( ogw, obj );
  3957.         drawlistviewentries( ogw, obj );
  3958.         setlistscroller( ogw, obj );
  3959.         DrawBorder( ogw->w->RPort, obj->bordg->GadgetRender, obj->bordg->LeftEdge, obj->bordg->TopEdge );
  3960.     }
  3961. }
  3962.  
  3963. void ogreLVSelect( struct ogwin *ogw, UWORD id, int num )
  3964. {
  3965.     struct ogobj *obj = findobj( ogw, id );
  3966.     struct ogrevn *vn = ogreLVGetEntry( ogw, id, num );
  3967.  
  3968.     if( !obj )
  3969.         return;
  3970.     if( ! ( obj->flags ) )
  3971.         lvdeselectall( obj );
  3972.  
  3973.     if( vn )
  3974.     {
  3975.         adjustlv( obj, num );
  3976.         vn->sel = 1;
  3977.         vn->changed = 0;
  3978.         obj->defaultvalue = num;
  3979.     }
  3980. }
  3981.  
  3982. void ogreSetMaxVal( struct ogwin *ogw, UWORD id, int maxval )
  3983. {
  3984.     struct ogobj *obj = findobj( ogw, id );
  3985.  
  3986.     if( obj )
  3987.         obj->maxval = maxval;
  3988. }
  3989.  
  3990. int ogreLVGetNumEntries( struct ogwin *ogw, UWORD id )
  3991. {
  3992.     struct ogobj *obj = findobj( ogw, id );
  3993.  
  3994.     if( obj )
  3995.         return( getnumentries( obj ) );
  3996.     else
  3997.         return( NULL );
  3998. }
  3999.  
  4000. void ogreCopyStringValue( struct ogwin *ogw, UWORD id, char *to )
  4001. {
  4002.     char *p;
  4003.  
  4004.     p = ogreStringValue( ogw, id );
  4005.     if( p )
  4006.         strcpy( to, p );
  4007.     else
  4008.         *to = 0;
  4009.  
  4010. }
  4011.  
  4012. void ogreLockWindow( struct ogwin *ogw )
  4013. {
  4014.     if( !ogw->windowlocked )
  4015.     {
  4016.         ogw->windowlocked = TRUE;
  4017.         ogw->windowlock = rtLockWindow( ogw->w );
  4018.     }
  4019. }
  4020.  
  4021. void ogreUnlockWindow( struct ogwin *ogw )
  4022. {
  4023.     if( ogw->windowlocked )
  4024.     {
  4025.         ogw->windowlocked = FALSE;
  4026.         rtUnlockWindow( ogw->w, ogw->windowlock );
  4027.     }
  4028. }
  4029.  
  4030. struct IntuiMessage * ogreWaitIM( struct ogwin *ogw )
  4031. {
  4032.     struct IntuiMessage *im;
  4033.  
  4034.     while( ! ( im = ogreIM( ogw ) ) )
  4035.         mWaitPort( ogw->w->UserPort );
  4036.  
  4037.     return( im );
  4038. }
  4039.  
  4040. void ogreAddHelp( struct ogwin *ogw, UBYTE py )
  4041. {
  4042.     ogreAddButton( ogw, py, 0x5f, "Hilfe", OGID_HELP );
  4043. }
  4044.  
  4045. void ogreSetFlags16( struct ogwin *ogw, UWORD id, UWORD flag, UWORD *to )
  4046. {
  4047.     if( ogreValue( ogw, id ) )
  4048.         *to |= flag;
  4049.     else
  4050.         *to &= ~flag;
  4051. }
  4052.  
  4053. void ogreSetFlags32( struct ogwin *ogw, UWORD id, ULONG flag, ULONG *to )
  4054. {
  4055.     if( ogreValue( ogw, id ) )
  4056.         *to |= flag;
  4057.     else
  4058.         *to &= ~flag;
  4059. }
  4060.  
  4061. int ogreLVGetLastActive( struct ogwin *ogw, UWORD id )
  4062. {
  4063.     struct ogobj *obj = findobj( ogw, id );
  4064.  
  4065.     return( obj->minval );
  4066.  
  4067. }
  4068.  
  4069. int ogreLVGetActive( struct ogwin *ogw, UWORD id )
  4070. {
  4071.     struct ogobj *obj = findobj( ogw, id );
  4072.  
  4073.     return( ( int ) obj->defaultvalue );
  4074. }
  4075.  
  4076. int ogreLVFindEntry( struct ogwin *ogw, UWORD id, char *name )
  4077. {
  4078.     struct ogobj *obj = findobj( ogw, id );
  4079.     struct ogrevn *vn = (struct ogrevn *) obj->l->lh_Head;
  4080.  
  4081.     while( vn->n.mln_Succ )
  4082.     {
  4083.         if( !stricmp( name, vn->txt ) )
  4084.             return( TRUE );
  4085.         vn = (struct ogrevn *) vn->n.mln_Succ;
  4086.     }
  4087.     return( FALSE );
  4088. }
  4089.