Annotation of researchv9/jtools/src/sunlib/mhit.c, revision 1.1.1.1

1.1       root        1: #include       "jerq.h"
                      2: #include       "menu.h"
                      3: #define                disp Jfscreen
                      4: 
                      5: #ifdef SUNTOOLS
                      6: #undef F_STORE
                      7: #define        F_STORE (PIX_DONTCLIP|PIX_SRC)
                      8: #define        F_NCXOR (PIX_DONTCLIP|(PIX_SRC ^ PIX_DST))
                      9: #else
                     10: #define        F_NCXOR F_XOR
                     11: #endif SUNTOOLS
                     12: 
                     13: static screenswap (bp, rect, screenrect)
                     14: register Bitmap *bp;
                     15: Rectangle rect;
                     16: Rectangle screenrect;
                     17: {
                     18:        bitblt(&disp, screenrect, bp, rect.origin, F_NCXOR);
                     19:        bitblt(bp, rect, &disp, screenrect.origin, F_NCXOR);
                     20:        bitblt(&disp, screenrect, bp, rect.origin, F_NCXOR);
                     21: }
                     22: 
                     23: #define scale(x, inmin, inmax, outmin, outmax)\
                     24:        (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin))
                     25: 
                     26: #define bound(x, low, high) min(high, max( low, x ))
                     27: 
                     28: Font *font = &defont;
                     29: #define SPACING                (1+fontheight(font))
                     30: #define CHARWIDTH      fontwidth(font)
                     31: #define DISPLAY                16
                     32: #define DELTA          6
                     33: #define BARWIDTH       18
                     34: #define        MAXDEPTH        16      /* don't use too much stack */
                     35: #define ARROWIDTH      20
                     36: 
                     37: static short tarrow_bits[] =
                     38: {
                     39:        0x0000, 0x0000, 0x0080, 0x00C0, 0x00C0, 0x00E0, 0x00F8, 0xFFFE,
                     40:        0xFFFE, 0x00F8, 0x00E0, 0x00C0, 0x00C0, 0x0080, 0x0000, 0x0000,
                     41: };
                     42: static Texture tarrow;
                     43: static int firstime = 1;
                     44: 
                     45: static NMitem *
                     46: tablegen(i, table)
                     47: NMitem *table;
                     48: {
                     49:        return &table[i];
                     50: }
                     51: 
                     52: static char fill[64];
                     53: 
                     54: NMitem *
                     55: mhit(m, but, depth)
                     56: register NMenu *m;
                     57: {
                     58:        register int width, mwidth, i, j, top, newtop, hit, newhit;
                     59:        register int items, lines, length, w, x;
                     60:        Point p, q, savep, baro, barc;
                     61:        Rectangle sr, tr, mr;   /* scroll, text, menu */
                     62:        Rectangle rside, rhit;
                     63:        register Bitmap *b;
                     64:        register char *from, *to;
                     65:        Bitmap *bhelp = 0, *arrow;
                     66:        NMitem *(*generator)(), *mi, *table, *ret = 0;
                     67:        int dohfn;
                     68: 
                     69: #define sro sr.origin
                     70: #define src sr.corner
                     71: #define tro tr.origin
                     72: #define trc tr.corner
                     73: #define mro mr.origin
                     74: #define mrc mr.corner
                     75: 
                     76:        if (firstime) {
                     77:                firstime = 0;
                     78:                tarrow = ToTexture(tarrow_bits);
                     79:        }
                     80:        generator = (table=m->item) ? tablegen : m->generator;
                     81:        arrow = balloc(Rect(0, 0, 16, 16));
                     82:        texture(arrow, arrow->rect, &tarrow, F_STORE);
                     83:        w = x = length = 0;
                     84:        for(items = 0; (mi=(*generator)(items, table))->text; ++items) {
                     85:                register int s = strlen (mi->text);
                     86:                length = max(length, s);
                     87:                if (mi->next) {
                     88:                        w = max (w, s);
                     89:                } else
                     90:                        x = max (x, s);
                     91:        }
                     92:        if(items == 0)
                     93:                return(ret);
                     94:        Jscreengrab();
                     95:        width = length*CHARWIDTH+10;
                     96:        w *= CHARWIDTH;
                     97:        x *= CHARWIDTH;
                     98:        if (x <= w)
                     99:                mwidth = w + ARROWIDTH;
                    100:        else if (x >= w + 2*ARROWIDTH)
                    101:                mwidth = x;
                    102:        else
                    103:                mwidth = w + ARROWIDTH + (x - w) / 2;
                    104:        mwidth += 10;
                    105:        sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0;
                    106:        if(items <= DISPLAY)
                    107:                lines = items;
                    108:        else{
                    109:                lines = DISPLAY;
                    110:                tro.x = src.x = BARWIDTH;
                    111:                sro.x = sro.y = 1;
                    112:        }
                    113: #define ASCEND 2
                    114:        tro.y = ASCEND;
                    115:        mrc = trc = add(tro, Pt(mwidth, min(items, lines)*SPACING));
                    116:        src.y = mrc.y-1;
                    117:        newtop = bound(m->prevtop, 0, items-lines);
                    118:        p = add(mouse.xy, Joffset);
                    119:        p.y -= bound(m->prevhit, 0, lines-1)*SPACING+SPACING/2;
                    120:        p.x = bound(p.x-(src.x+mwidth/2), Jfscreen.rect.origin.x,
                    121:                Jfscreen.rect.corner.x-mrc.x);
                    122:        p.y = bound(p.y, Jfscreen.rect.origin.y, Jfscreen.rect.corner.y-mrc.y);
                    123:        sr = raddp(sr, p);
                    124:        tr = raddp(tr, p);
                    125:        mr = raddp(mr, p);
                    126:        rside = mr;
                    127:        rside.origin.x = rside.corner.x-20;
                    128:        b = balloc(mr);
                    129:        cursinhibit();
                    130:        if(b)
                    131:                bitblt(&disp, mr, b, mro, F_STORE);
                    132:        rectf(&disp, mr, F_OR);
                    133:        cursallow();
                    134: PaintMenu:
                    135:        cursinhibit();
                    136:        rectf(&disp, inset(mr, 1), F_CLR);
                    137:        cursallow();
                    138:        top = newtop;
                    139:        if(items > DISPLAY){
                    140:                baro.y = scale(top, 0, items, sro.y, src.y);
                    141:                baro.x = sr.origin.x;
                    142:                barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y);
                    143:                barc.x = sr.corner.x;
                    144:                rectf(&disp, Rpt(baro,barc), F_XOR);
                    145:        }
                    146:        for(p=tro, i=top; i < min(top+lines, items); ++i){
                    147:                q = p;
                    148:                mi = generator(i, table);
                    149:                from = mi->text;
                    150:                for(to = &fill[0]; *from; ++from)
                    151:                        if(*from & 0x80)
                    152:                                for(j=length-(strlen(from+1)+(to-&fill[0])); j-->0;)
                    153:                                        *to++ = *from & 0x7F;
                    154:                        else
                    155:                                *to++ = *from;
                    156:                *to = '\0';
                    157:                q.x += (width-strwidth(font,fill))/2;
                    158:                string(&defont, fill, &disp, q, F_XOR);
                    159:                if(mi->next)
                    160:                        bitblt(arrow, arrow->rect, &disp, Pt(trc.x-18, p.y-2), F_OR);
                    161:                p.y += SPACING;
                    162:        }
                    163:        savep = add(mouse.xy, Joffset);
                    164:        mi = 0;
                    165:        for(newhit = hit = -1; button(but); ){
                    166:                p = add(mouse.xy, Joffset);
                    167:                if(depth && ((p.x < mro.x) || button(5-but)))
                    168:                {
                    169:                        ret = 0;
                    170:                        break;
                    171:                }
                    172:                if(ptinrect(p, sr)){
                    173:                        if(ptinrect(savep,tr)){
                    174:                                p.y = (baro.y+barc.y)/2;
                    175:                                cursset(sub(p,Joffset));
                    176:                        }
                    177:                        newtop = scale(p.y, sro.y, src.y, 0, items);
                    178:                        newtop = bound(newtop-DISPLAY/2, 0, items-DISPLAY);
                    179:                        if(newtop != top)
                    180: /* ->->-> */                   goto PaintMenu;
                    181:                }else if(ptinrect(savep,sr)){
                    182:                        register dx, dy;
                    183:                        if(abs(dx = p.x-savep.x) < DELTA)
                    184:                                dx = 0;
                    185:                        if(abs(dy = p.y-savep.y) < DELTA)
                    186:                                dy = 0;
                    187:                        if(abs(dy) >= abs(dx))
                    188:                                dx = 0;
                    189:                        else
                    190:                                dy = 0;
                    191:                        p = add(savep, Pt(dx,dy));
                    192:                        cursset(sub(p,Joffset));
                    193:                }
                    194:                savep = p;
                    195:                newhit = -1;
                    196:                if(ptinrect(p, tr)){
                    197:                        newhit = bound((p.y-tro.y)/SPACING, 0, lines-1);
                    198:                        if(newhit!=hit && hit>=0
                    199:                         && abs(tro.y+SPACING*newhit+SPACING/2-p.y) > SPACING/3)
                    200:                                newhit = hit;
                    201:                        rhit = tr;
                    202:                        rhit.origin.y += newhit*SPACING-ASCEND/2;
                    203:                        rhit.corner.y = rhit.origin.y + SPACING;
                    204:                }
                    205:                if(newhit == -1)
                    206:                        ret = 0, dohfn = 0;
                    207:                else
                    208:                        ret = mi = (*generator)(top+newhit, table), dohfn = 1;
                    209:                if(newhit == hit)
                    210:                {
                    211:                        if((newhit != -1) && (bhelp == 0) && button1() && mi->help)
                    212:                                helpon(mi->help, rhit, &bhelp);
                    213:                        else if(bhelp && !button1())
                    214:                                helpoff(&bhelp);
                    215:                }
                    216:                else
                    217:                {
                    218:                        flip(tr, hit);
                    219:                        helpoff(&bhelp);
                    220:                        flip(tr, newhit);
                    221:                        hit = newhit;
                    222:                        if((newhit != -1) && button1() && mi->help)
                    223:                                helpon(mi->help, rhit, &bhelp);
                    224:                }
                    225:                if((newhit != -1) && ptinrect(p, rside))
                    226:                {
                    227:                        if(mi->dfn) (*mi->dfn)(mi);
                    228:                        if(mi->next && (depth <= MAXDEPTH))
                    229:                                ret = mhit(mi->next, but, depth+1), dohfn = 0;
                    230:                        if(mi->bfn) (*mi->bfn)(mi);
                    231:                }
                    232:                if(newhit==0 && top>0){
                    233:                        newtop = top-1;
                    234:                        p.y += SPACING;
                    235:                        cursset(sub(p,Joffset));
                    236: /* ->->-> */           goto PaintMenu;
                    237:                }
                    238:                if(newhit==DISPLAY-1 && top<items-lines){
                    239:                        newtop = top+1;
                    240:                        p.y -= SPACING;
                    241:                        cursset(sub(p,Joffset));
                    242: /* ->->-> */           goto PaintMenu;
                    243:                }
                    244:                if (button(but))
                    245:                        nap(2);
                    246:        }
                    247:        if(bhelp)
                    248:                helpoff(&bhelp);
                    249:        if(b){
                    250:                cursinhibit();
                    251:                screenswap(b, b->rect, b->rect);
                    252:                cursallow();
                    253:                bfree(b);
                    254:        }
                    255:        if(hit>=0){
                    256:                m->prevhit = hit;
                    257:                m->prevtop = top;
                    258:                if(ret && ret->hfn && dohfn) (*ret->hfn)(mi);
                    259:        }
                    260:        Jscreenrelease();
                    261:        return(ret);
                    262: }
                    263: 
                    264: static
                    265: flip(r,n)
                    266:        Rectangle r;
                    267: {
                    268:        if(n<0)
                    269:                return;
                    270:        ++r.origin.x;
                    271:        r.corner.y = (r.origin.y += SPACING*n-1) + SPACING;
                    272:        --r.corner.x;
                    273:        rectf(&disp, r, F_XOR);
                    274: }
                    275: 
                    276: static
                    277: helpon(msg, r, bhelp)
                    278:        char *msg;
                    279:        Rectangle r;
                    280:        Bitmap **bhelp;
                    281: {
                    282:        register Bitmap *b;
                    283:        register w;
                    284: 
                    285:        w = strwidth(&defont, msg)+10;
                    286:        if(r.corner.x+w < disp.rect.corner.x){
                    287:                r.origin.x = r.corner.x;
                    288:                r.corner.x += w;
                    289:        }
                    290:        else{
                    291:                r.corner.x = r.origin.x;
                    292:                r.origin.x -= w;
                    293:        }
                    294:        if(*bhelp = b = balloc(r = inset(r, -1))){
                    295:                rectf(b, r, F_OR);
                    296:                rectf(b, inset(r, 1), F_XOR);
                    297:                string(&defont, msg, b, add(b->rect.origin, Pt(5, 1)),F_XOR);
                    298:                screenswap(b, b->rect, b->rect);
                    299:        }
                    300: }
                    301: 
                    302: static
                    303: helpoff (bhelp)
                    304: Bitmap **bhelp;
                    305: {
                    306:        Bitmap *bh;
                    307: 
                    308:        if(bh = *bhelp){
                    309:                screenswap(bh, bh->rect, bh->rect);
                    310:                bfree(bh);
                    311:                *bhelp = 0;
                    312:        }
                    313: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.