|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 17369 (0x43d9) Types: TextFile Names: »scrollbar.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/X/Xmille/control/scrollbar.c«
/* * scrollbar.c */ #if 0 # include <X11/Xlib.h> # include <X11/Xutil.h> # include "control.h" struct scrollbar { Scrollbar scrollbar; int forecolor, backcolor; int orientation; int borderwidth; Pixmap border; Pixmap background; }; struct perwindow { int length; Window parent; int locatorpos; int locatormille; int locatormax; int locatormaxmille; int state; struct scrollbar *class; int (*notify)(); int (*onetrip)(); }; /* * possible values of ->state */ # define GENERAL 0 # define DRAGGING_LOCATOR 1 # define DOWN 2 # define DOWN_IN_DOWN_BOX 3 # define DOWN_IN_UP_BOX 4 static XContext perwindowContext; static XContext assocContext; static int nextScrollbar; extern Display *dpy; # define minpos(p) (0) # define maxpos(p) ((p)->length - 2 * ARROWWIDTH) # define milletopos(m,p) ((m) * maxpos(p) / 1000) # define postomille(l,p) ((l) * 1000 / maxpos (p)) # define postoloc(l) ((l) + ARROWWIDTH) # define loctopos(l) ((l) - ARROWWIDTH) # define ARROWHEIGHT SCROLLWIDTH # define ARROWWIDTH SCROLLWIDTH # define LOCATORWIDTH SCROLLWIDTH / 3 static short arrowDownOff[50] = { 0xffff, 0x01ff, 0x0000, 0x0000, 0x0000, 0x0000, 0xff80, 0x0003, 0x0080, 0x0002, 0x0080, 0x0002, 0x0080, 0x0002, 0x0080, 0x0002, 0x0080, 0x0002, 0x0080, 0x0002, 0x0080, 0x0002, 0x00f8, 0x003e, 0x0010, 0x0010, 0x0020, 0x0008, 0x0040, 0x0004, 0x0080, 0x0002, 0x0100, 0x0001, 0x8200, 0x0000, 0x4400, 0x0000, 0x2800, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; static short arrowDownOn[50] = { 0xffff, 0x01ff, 0x0000, 0x0000, 0x0000, 0x0000, 0xff80, 0x0003, 0xff80, 0x0003, 0xff80, 0x0003, 0xff80, 0x0003, 0xff80, 0x0003, 0xff80, 0x0003, 0xff80, 0x0003, 0xff80, 0x0003, 0xfff8, 0x003f, 0xfff0, 0x001f, 0xffe0, 0x000f, 0xffc0, 0x0007, 0xff80, 0x0003, 0xff00, 0x0001, 0xfe00, 0x0000, 0x7c00, 0x0000, 0x3800, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, }; static short arrowUpOff [50], arrowRightOff [50], arrowLeftOff [50]; static short arrowUpOn [50], arrowRightOn [50], arrowLeftOn [50]; static Cursor dragCursor; static short dragBits[16]; static int arrowsSet; Scrollbar CcreateScrollbar (orientation, forecolor, backcolor, borderwidth, border, background) int orientation; int forecolor, backcolor; int borderwidth; Pixmap border; Pixmap background; { char *malloc (); struct scrollbar *s; if (!assocContext) assocContext = XUniqueContext(); if (!arrowsSet) { setArrows(); arrowsSet = 1; } s = (struct scrollbar *) malloc (sizeof (struct scrollbar)); nextScrollbar++; s->scrollbar = nextScrollbar; XSaveContext (dpy, assocContext, nextScrollbar, (char *) s); s->forecolor = forecolor; s->backcolor = backcolor; s->orientation = orientation; s->borderwidth = borderwidth; s->border = border; s->background = background; return s->scrollbar; } Window CmapScrollbar (parent, scrollbar, notify, onetrip) Window parent; Scrollbar scrollbar; int (*notify)(), (*onetrip)(); { struct scrollbar *s; struct perwindow *p; Window w; int x, y, width, height; Window grandParent; Window *siblings; int nsiblings; if( XFindContext (dpy, assocContext, scrollbar, &s) ) { printf ("scroll bar %d doesn't exist\n", scrollbar); return 0; } if( !XQueryTree (parent, &grandParent, &nsiblings, &siblings)) { printf ("can't get tree\n"); return 0; } if (siblings) free (siblings); if (!computePosition (parent, s, &x, &y, &width, &height)) return 0; w = XCreateWindow (grandParent, x, y, width, height, s->borderwidth, s->border, s->background); XMapWindow (w); if (!perwindowContext) perwindowContext = XUniqueContext(); p = (struct perwindow *) malloc (sizeof (struct perwindow)); switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: p->length = width; break; case SCROLL_RIGHT: case SCROLL_LEFT: p->length = height; break; } p->state = GENERAL; p->parent = parent; p->class = s; p->locatorpos = -1; p->notify = notify; p->onetrip = onetrip; XSaveContext (dpy, perwindowContext, w, p); drawArrows (w, s, p); return w; } CunmapScrollbar (w) Window w; { struct perwindow *p; if( XFindContext (dpy, perwindowContext, w, &p) ) return 0; XDeleteContext (dpy, perwindowContext, w); free (p); XDestroyWindow (w); return 1; } CresizeScrollbar (w) Window w; { struct perwindow *p; struct scrollbar *s; int x, y, width, height; if( XFindContext (dpy, perwindowContext, w, &p) ) return 0; s = p->class; if (!computePosition (p->parent, s, &x, &y, &width, &height)) return 0; XConfigureWindow (w, x, y, width, height); switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: p->length = width; break; case SCROLL_RIGHT: case SCROLL_LEFT: p->length = height; break; } if (p->locatorpos >= 0) p->locatorpos = milletopos (p->locatormille, p); if (p->locatormax >= 0) p->locatormax = milletopos (p->locatormaxmille, p); return 1; } Window CgetScrollbarParent (w) Scrollbar w; { struct perwindow *p; if( XFindContext (dpy, perwindowContext, w, &p) ) return 0; return p->parent; } CredrawScrollbar (w) Window w; { struct scrollbar *s; struct perwindow *p; if( XFindContext (dpy, perwindowContext, w, &p) ) return 0; s = p->class; drawArrows (w, s, p); moveLocator (w, s, p, p->locatorpos, p->locatormax); return 1; } CsetScrollbarLocator (w, permillemin, permillemax) Window w; int permillemin, permillemax; { struct perwindow *p; struct scrollbar *s; if( XFindContext (dpy, perwindowContext, w, &p) ) return 0; s = p->class; if (permillemin < 0) permillemin = 0; if (permillemax > 1000) permillemax = 1000; moveLocator (w, s, p, milletopos (permillemin, p), milletopos (permillemax, p)); return 1; } # define NOWHERE 0 # define IN_UP_BOX 1 # define IN_DOWN_BOX 2 # define IN_UP_AREA 3 # define IN_DOWN_AREA 4 # define IN_LOCATOR 5 /* * used for dragging the locator around */ static int downmouse; /* mouse position at down click */ static int downloc; /* locator position at down click */ CmanageScrollbar (rep) XEvent *rep; { struct perwindow *p; struct scrollbar *s; int inwindow; int region; XButtonEvent *bevent; XMouseMovedEvent *mevent; int permille; Window w; w = rep->window; if( XFindContext (dpy, perwindowContext, w, &p) ) return 0; s = p->class; switch (rep->type) { case ExposeWindow: CredrawScrollbar (w); break; case ButtonPressed: switch (p->state) { case GENERAL: bevent = (XButtonEvent *) rep; region = findRegion (s, p, bevent->x, bevent->y); switch (region) { case IN_LOCATOR: p->state = DRAGGING_LOCATOR; downloc = p->locatorpos; switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: downmouse = bevent->x; break; case SCROLL_LEFT: case SCROLL_RIGHT: downmouse = bevent->y; break; } break; case IN_UP_BOX: p->state = DOWN_IN_UP_BOX; highlightBox (w, s, p, p->state); spinbutton (w, s, p, IN_UP_BOX); break; case IN_DOWN_BOX: p->state = DOWN_IN_DOWN_BOX; highlightBox (w, s, p, p->state); spinbutton (w, s, p, IN_DOWN_BOX); break; case IN_DOWN_AREA: case IN_UP_AREA: p->state = DOWN; switch (region) { case IN_DOWN_AREA: p->notify (p->parent, SCROLL_DOWN_AREA); break; case IN_UP_AREA: p->notify (p->parent, SCROLL_UP_AREA); break; } } } break; case ButtonReleased: switch (p->state) { case DRAGGING_LOCATOR: p->state = GENERAL; break; case DOWN_IN_DOWN_BOX: case DOWN_IN_UP_BOX: unhighlightBox (w, s, p, p->state); case DOWN: p->state = GENERAL; break; } case MouseMoved: switch (p->state) { case DRAGGING_LOCATOR: p->notify (p->parent, updateLocator (w, s, p)); p->onetrip (p->parent); break; } break; } } static spinbutton (w, s, p, region) Window w; struct scrollbar *s; struct perwindow *p; int region; { int r; r = region; for (;;) { switch (p->state) { case DOWN_IN_UP_BOX: case DOWN_IN_DOWN_BOX: if (r != region) { unhighlightBox (w, s, p, p->state); p->state = GENERAL; return; } switch (region) { case IN_UP_BOX: p->notify (p->parent, SCROLL_UP_BUTTON); p->onetrip (p->parent); break; case IN_DOWN_BOX: p->notify (p->parent, SCROLL_DOWN_BUTTON); p->onetrip (p->parent); break; } break; default: return; } r = checkMouseRegion (w, s, p); } } static findRegion (s, p, x, y) struct scrollbar *s; struct perwindow *p; int x,y; { int loc; switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: if (y < 0 || SCROLLWIDTH <= y) return NOWHERE; loc = x; break; case SCROLL_LEFT: case SCROLL_RIGHT: if (x < 0 || SCROLLWIDTH <= x) return NOWHERE; loc = y; break; } if (loc < 0 || loc >= p->length) return NOWHERE; if (loc <= ARROWWIDTH) return IN_UP_BOX; if (loc >= p->length - ARROWWIDTH) return IN_DOWN_BOX; if (loc < postoloc (p->locatorpos)) return IN_UP_AREA; if (loc > postoloc (p->locatormax)) return IN_DOWN_AREA; return IN_LOCATOR; } static updateLocator (w, s, p) Window w; struct scrollbar *s; struct perwindow *p; { int pos, loc; int subw, x, y; int len; XUpdateMouse (w, &x, &y, &subw); switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: loc = x; break; case SCROLL_LEFT: case SCROLL_RIGHT: loc = y; break; } pos = loctopos (postoloc (downloc) + loc - downmouse); if (pos < minpos(p)) pos = minpos(p); if (pos > maxpos(p)) pos = maxpos (p); return postomille (pos, p); } static checkMouseRegion (w, s, p) Window w; struct scrollbar *s; struct perwindow *p; { int x, y, subw, state; int region; XQueryMouseButtons (w, &x, &y, &subw, &state); /* * Note that if we are playing back a recording then the button * state will not be as it was during the recording (pressed), * so we short circuit it. */ region = findRegion (s, p, x, y); if (region == IN_UP_BOX && p->state == DOWN_IN_UP_BOX) return IN_UP_BOX; if (region == IN_DOWN_BOX && p->state == DOWN_IN_DOWN_BOX) return IN_DOWN_BOX; return NOWHERE; } static computePosition (parent, s, xp, yp, wp, hp) Window parent; struct scrollbar *s; int *xp, *yp, *wp, *hp; { WindowInfo parentInfo; /* make sure the server has the most recent parent info */ XSync (0); if (!XQueryWindow (parent, &parentInfo)) { printf ("can't get window info for %d\n", parent); return 0; } switch (s->orientation) { case SCROLL_TOP: *xp = 0; *yp = -SCROLLWIDTH - parentInfo.bdrwidth; *wp = parentInfo.width; *hp = SCROLLWIDTH; break; case SCROLL_BOTTOM: *xp = 0; *yp = parentInfo.height + parentInfo.bdrwidth; *wp = parentInfo.width; *hp = SCROLLWIDTH; break; case SCROLL_LEFT: *xp = -SCROLLWIDTH - parentInfo.bdrwidth; *yp = 0; *wp = SCROLLWIDTH; *hp = parentInfo.height; break; case SCROLL_RIGHT: *xp = parentInfo.width + parentInfo.bdrwidth; *yp = 0; *wp = SCROLLWIDTH; *hp = parentInfo.height; break; } *xp += parentInfo.x; *yp += parentInfo.y; return 1; } static drawArrows (w, s, p) Window w; struct scrollbar *s; struct perwindow *p; { int x, y; short *up, *down; switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: up = arrowLeftOff; down = arrowRightOff; x = p->length - ARROWWIDTH; y = 0; switch (p->state) { case DOWN_IN_DOWN_BOX: down = arrowRightOn; break; case DOWN_IN_UP_BOX: up = arrowLeftOn; break; } break; case SCROLL_LEFT: case SCROLL_RIGHT: up = arrowUpOff; down = arrowDownOff; x = 0; y = p->length - ARROWWIDTH; switch (p->state) { case DOWN_IN_DOWN_BOX: down = arrowDownOn; break; case DOWN_IN_UP_BOX: up = arrowUpOn; break; } break; } XBitmapBitsPut (w, 0, 0, ARROWWIDTH, ARROWHEIGHT, up, s->forecolor, s->backcolor, 0, GXcopy, AllPlanes); XBitmapBitsPut (w, x, y, ARROWWIDTH, ARROWHEIGHT, down, s->forecolor, s->backcolor, 0, GXcopy, AllPlanes); } static highlightBox (w, s, p, state) Window w; struct scrollbar *s; struct perwindow *p; int state; { drawoneArrow (w, s, p, state, 1); } static unhighlightBox (w, s, p, state) Window w; struct scrollbar *s; struct perwindow *p; int state; { drawoneArrow (w, s, p, state, 0); } static drawoneArrow (w, s, p, state, on) Window w; struct scrollbar *s; struct perwindow *p; int state; int on; { int x, y; short *bitsup, *bitsdown, *bits; switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: x = p->length - ARROWWIDTH; y = 0; if (on) { bitsup = arrowLeftOn; bitsdown = arrowRightOn; } else { bitsup = arrowLeftOff; bitsdown = arrowRightOff; } break; case SCROLL_LEFT: case SCROLL_RIGHT: x = 0; y = p->length - ARROWWIDTH; if (on) { bitsup = arrowUpOn; bitsdown = arrowDownOn; } else { bitsup = arrowUpOff; bitsdown = arrowDownOff; } break; } switch (state) { case DOWN_IN_UP_BOX: x = 0; y = 0; bits = bitsup; break; case DOWN_IN_DOWN_BOX: bits = bitsdown; break; default: return; } XBitmapBitsPut (w, x, y, ARROWWIDTH, ARROWHEIGHT, bits, s->forecolor, s->backcolor, 0, GXcopy, AllPlanes); } static moveLocator (w, s, p, pos, max) Window w; struct scrollbar *s; struct perwindow *p; int pos, max; { int x, y, lw, lh; int x0, y0, w0, h0; int x1, y1, w1, h1; int oldpos, oldmax, oldlen; if (max > maxpos (p)) max = maxpos (p); if (max < 0) max = 0; if (pos > maxpos (p)) pos = maxpos (p); if (pos < 0) pos = 0; oldpos = p->locatorpos; oldmax = p->locatormax; oldlen = oldmax - oldpos; w0 = h0 = w1 = h1 = 0; switch (s->orientation) { case SCROLL_TOP: case SCROLL_BOTTOM: x = postoloc (pos); y = SCROLLWIDTH / 2 - LOCATORWIDTH / 2; y0 = y; y1 = y; lh = LOCATORWIDTH; lw = max - pos; h0 = lh; h1 = lh; if (pos < 0) { /* * erase the whole thing */ x0 = postoloc (oldpos); w0 = oldlen; } else if (p->locatorpos < 0) { ; } else { if (pos > oldpos) { /* * erase before portion */ x0 = postoloc (oldpos); w0 = pos - oldpos; } if (max < oldmax) { /* * erase after portion */ x1 = postoloc (max); w1 = oldmax - max; } } break; case SCROLL_LEFT: case SCROLL_RIGHT: x = SCROLLWIDTH / 2 - LOCATORWIDTH / 2; y = postoloc (pos); x0 = x; x1 = x; lw = LOCATORWIDTH; lh = max - pos; w0 = lw; w1 = lw; if (pos < 0) { /* * erase the whole thing */ y0 = postoloc (oldpos); h0 = oldlen; } else if (p->locatorpos < 0) { ; } else { if (pos > oldpos) { /* * erase before portion */ y0 = postoloc (oldpos); h0 = pos - oldpos; } if (max < oldmax) { /* * erase after portion */ y1 = postoloc (max); h1 = oldmax - max; } } break; } if (pos >= 0) { Vertex v[5]; v[0].x = x; v[0].y = y; v[0].flags = 0; v[1].x = lw-1; v[1].y = 0; v[1].flags = VertexRelative; v[2].x = 0; v[2].y = lh-1; v[2].flags = VertexRelative; v[3].x = 1-lw; v[3].y = 0; v[3].flags = VertexRelative; v[4].x = 0; v[4].y = 1-lh; v[4].flags = VertexRelative; XDraw (w, v, 5, 1, 1, s->forecolor, GXcopy, AllPlanes); XPixSet (w, x+1, y+1, lw-2, lh-2, s->backcolor); } if (oldpos >= 0) { if (w0 != 0 && h0 != 0) XTileSet (w, x0, y0, w0, h0, s->background); if (w1 != 0 && h1 != 0) XTileSet (w, x1, y1, w1, h1, s->background); } p->locatorpos = pos; p->locatormax = max; p->locatormille = postomille (p->locatorpos, p); p->locatormaxmille = postomille (p->locatormax, p); } # define getbit(array, bit, word) ((word < 0 || word >= 50) ? 0 : ((array[word] >> bit) & 01)) static setArrows () { int i; int word, bit; unsigned short tempLeftOn[2], tempRightOn[2]; unsigned short tempLeftOff[2], tempRightOff[2]; int on, off; Bitmap dragmap; int k; for (i = 0; i < ARROWHEIGHT; i++) for (k = 0; k < 2; k++) { arrowUpOff[i*2+k] = arrowDownOff[(ARROWHEIGHT-1-i)*2 + k]; arrowUpOn[i*2+k] = arrowDownOn[(ARROWHEIGHT-1-i)*2 + k]; } for (i = 0; i < ARROWHEIGHT; i++) { for (k = 0; k < 2; k++) { tempLeftOn[k] = tempLeftOff[k] = 0; tempRightOn[k] = tempRightOff[k] = 0; } for (k = 0; k < 2; k++) { for (bit = 0; bit < 16; bit++) { off = getbit (arrowDownOff, i % 16, ((15-bit) + (1-k) * 16) * 2 + i/16); on = getbit (arrowDownOn, i % 16, ((15-bit) + (1-k) * 16) * 2 + i/16); if (off) tempRightOff[1-k] |= (1 << (15 - bit)); if (on) tempRightOn[1-k] |= (1 << (15 - bit)); off = getbit (arrowUpOff, i % 16, ((15-bit) + (1-k) * 16) * 2 + i/16); on = getbit (arrowUpOn, i % 16, ((15-bit) + (1-k) * 16) * 2 + i/16); if (off) tempLeftOff[1-k] |= (1 << (15 - bit)); if (on) tempLeftOn[1-k] |= (1 << (15 - bit)); } } arrowLeftOn[i*2] = tempLeftOn[0]; arrowLeftOn[i*2+1] = tempLeftOn[1]; arrowLeftOff[i*2] = tempLeftOff[0]; arrowLeftOff[i*2+1] = tempLeftOff[1]; arrowRightOn[i*2] = tempRightOn[0]; arrowRightOn[i*2+1] = tempRightOn[1]; arrowRightOff[i*2] = tempRightOff[0]; arrowRightOff[i*2+1] = tempRightOff[1]; } dragmap = XStoreBitmap (16, 16, dragBits); dragCursor = XStoreCursor (dragmap, dragmap, 8, 8, 1, 0, GXnoop); } #endif