|
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 - downloadIndex: ┃ T s ┃
Length: 17852 (0x45bc) Types: TextFile Names: »scrollbar.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─ ⟦this⟧ »./X.V10R4/xterm/scrollbar.c«
/* * $Source: /u1/X/xterm/RCS/scrollbar.c,v $ * $Header: scrollbar.c,v 10.100 86/12/01 14:45:27 jg Rel $ */ #include <stdio.h> #include <sys/time.h> #include <X/Xlib.h> #include <setjmp.h> #include "scrollbar.h" #include "ptyx.h" #include "data.h" #include "error.h" #ifdef MODEMENU #include "menu.h" #endif MODEMENU #include "button.ic" #include "dark.ic" #include "light.ic" #include "upline.ic" #include "downline.ic" #include "uppage.ic" #include "downpage.ic" #include "top.ic" #include "bottom.ic" #include "saveoff.ic" #include "saveon.ic" #ifndef lint static char sccs_id[] = "@(#)scrollbar.c\tX10/6.6\t11/3/86"; #endif lint static struct timeval stepspeed; ScrollBar * CreateScrollBar(w, x, y, height, fg, bg, bordertile, val, valregion, topval, botval, arrow) Window w; int x, y, height, fg, bg, val, valregion, topval, botval; Pixmap bordertile; Cursor arrow; { register ScrollBar *sb; register int i; Pixmap btile, bgnd; extern char *calloc(); static Window Make_tiled_window(); extern Pixmap Make_tile(); if(!w || height < MINSCROLLBARHEIGHT || (sb = (ScrollBar *)calloc(1, sizeof(ScrollBar))) == NULL) return(NULL); btile = bordertile; if(bg == BlackPixel && fg == WhitePixel) { bg = WhitePixel; fg = BlackPixel; if(btile == WhitePixmap) btile = BlackPixmap; } sb->fg = fg; sb->bg = bg; sb->cursor = arrow; if((sb->bar = Make_tiled_window(light_width, light_height, light_bits, fg, bg, &bgnd, w, x, y, (SCROLLBARWIDTH - 1), height, 1, bordertile)) == NULL) goto failed_bar; if((sb->button = XCreateWindow(sb->bar, -1, -1, (SCROLLBARWIDTH - 1), BUTTONHEIGHT - 1, 1, btile, bgnd)) == NULL) goto failed_button; if((sb->save = XCreateWindow(sb->bar, -1, BUTTONHEIGHT - 1, (SCROLLBARWIDTH - 1), BUTTONHEIGHT - 1, 1, btile, bgnd)) == NULL) goto failed_save; if((sb->region = Make_tiled_window(dark_width, dark_height, dark_bits, fg, bg, &bgnd, sb->bar, 0, 0, (SCROLLBARWIDTH - 1), 10, 0, (Pixmap)NULL)) == NULL) { XDestroyWindow(sb->save); failed_save: XDestroyWindow(sb->button); failed_button: XDestroyWindow(sb->bar); failed_bar: free((char *)sb); return(NULL); } sb->savebits[SAVE_OFF] = saveoff_bits; sb->savebits[SAVE_ON] = saveon_bits; sb->buttonbits[BUTTON_UPLINE / 2] = upline_bits; sb->buttonbits[BUTTON_DOWNLINE / 2] = downline_bits; sb->buttonbits[BUTTON_UPPAGE / 2] = uppage_bits; sb->buttonbits[BUTTON_DOWNPAGE / 2] = downpage_bits; sb->buttonbits[BUTTON_TOP / 2] = top_bits; sb->buttonbits[BUTTON_BOTTOM / 2] = bottom_bits; sb->buttonbits[BUTTON_NORMAL / 2] = button_bits; XDefineCursor(sb->bar, sb->cursor); XSelectInput(sb->bar, ButtonPressed | ButtonReleased | ExposeWindow | EnterWindow | LeaveWindow | UnmapWindow); XSelectInput(sb->button, EnterWindow | LeaveWindow); XMapWindow(sb->button); /* will really map when bar is mapped */ XMapWindow(sb->save); /* will really map when bar is mapped */ sb->buttonstate = sb->buttonset = BUTTON_NORMAL; sb->savestate = sb->saveset = SAVE_ON; sb->set.value = val; sb->set.regionheight = valregion; sb->set.topvalue = topval; sb->set.bottomvalue = botval; sb->set.height = height - BARSTART; return(sb); } ShowScrollBar(sb) register ScrollBar *sb; { if(sb->visible) return; sb->visible = 1; if(sb->regionvisible) { XUnmapWindow(sb->region); sb->regionvisible = 0; } XMapWindow(sb->bar); DrawScrollRegion(sb); sb->action = SHOW; } HideScrollBar(sb) register ScrollBar *sb; { if(!sb->visible) return; sb->visible = 0; XUnmapWindow(sb->bar); } DrawScrollRegion(sb) register ScrollBar *sb; { register int region, temp; if(sb->set.regionheight <= 0) sb->set.regionheight = 0; if((region = sb->set.topvalue - sb->set.bottomvalue) >= 0) { if(sb->set.value > sb->set.topvalue) sb->set.value = sb->set.topvalue; else if(sb->set.value < sb->set.bottomvalue) sb->set.value = sb->set.bottomvalue; } else { region = -region; if(sb->set.value < sb->set.topvalue) sb->set.value = sb->set.topvalue; else if(sb->set.value > sb->set.bottomvalue) sb->set.value = sb->set.bottomvalue; } if(sb->set.value == sb->set.topvalue) { sb->set.pixelheight = (region == 0) ? sb->set.height : (sb->set.height - 1) * sb->set.regionheight / (sb->set.regionheight + region); sb->set.y = BARSTART; } else if(sb->set.value == sb->set.bottomvalue) { sb->set.pixelheight = (sb->set.height - 1) * sb->set.regionheight / (sb->set.regionheight + region); sb->set.y = BARSTART + sb->set.height - sb->set.pixelheight; } else { if(sb->set.topvalue >= sb->set.bottomvalue) { temp = sb->set.topvalue - 1; region = temp - (sb->set.bottomvalue + 1); sb->set.y = temp - sb->set.value; } else { temp = sb->set.topvalue + 1; region = (sb->set.bottomvalue - 1) - temp; sb->set.y = sb->set.value - temp; } sb->set.y = (BARSTART + 1) + sb->set.y * (sb->set.height - 2) / (temp = sb->set.regionheight + region); sb->set.pixelheight = (sb->set.height - 2) * sb->set.regionheight / temp; } if(sb->set.pixelheight <= 0) sb->set.pixelheight = 1; if(sb->set.regionheight == 0) { sb->state = sb->set; if(sb->regionvisible) { XUnmapWindow(sb->region); sb->regionvisible = 0; } return; } if(!sb->visible || sb->regionvisible && sb->state.y == sb->set.y && sb->state.pixelheight == sb->set.pixelheight) { sb->state = sb->set; return; } sb->state = sb->set; XConfigureWindow(sb->region, 0, sb->state.y, (SCROLLBARWIDTH - 1), sb->state.pixelheight); if(!sb->regionvisible) { XMapWindow(sb->region); sb->regionvisible = 1; } } DrawButton(sb) register ScrollBar *sb; { register int fg, bg; if(sb->visible && sb->buttonstate != sb->buttonset) { if((sb->buttonstate = sb->buttonset) & HILITED) { fg = sb->bg; bg = sb->fg; } else { fg = sb->fg; bg = sb->bg; } XBitmapBitsPut(sb->button, 0, 0, SCROLLBARWIDTH - 1, BUTTONHEIGHT - 1, sb->buttonbits[sb->buttonstate / 2], fg, bg, (Bitmap)0, GXcopy, AllPlanes); } } DrawSave(sb) register ScrollBar *sb; { if(sb->visible && sb->savestate != sb->saveset) XBitmapBitsPut(sb->save, 0, 0, SCROLLBARWIDTH - 1, BUTTONHEIGHT - 1, sb->savebits[sb->savestate = sb->saveset], sb->fg, sb->bg, (Bitmap)0, GXcopy, AllPlanes); } ResizeScrollBar(sb, x, y, height, region) register ScrollBar *sb; int x, y, height, region; { register int act; act = sb->action; sb->action = NONE; switch(act) { case SHOW: return; case HIDE: HideScrollBar(sb); return; } if(!sb->visible) return; if(sb->regionvisible) { XUnmapWindow(sb->region); sb->regionvisible = 0; } XConfigureWindow(sb->bar, x, y, (SCROLLBARWIDTH - 1), height); sb->set.height = height - BARSTART; sb->set.regionheight = region; DrawScrollRegion(sb); } PositionRegion(sb, y) register ScrollBar *sb; register int y; { if(y <= BARSTART) sb->set.value = sb->set.topvalue; else if(y >= BARSTART + sb->set.height * (sb->set.bottomvalue - sb->set.topvalue) / (sb->set.bottomvalue + sb->set.regionheight - sb->set.topvalue)) sb->set.value = sb->set.bottomvalue; else sb->set.value = sb->set.topvalue + (y - BARSTART) * (sb->set.bottomvalue + sb->set.regionheight - sb->set.topvalue) / sb->set.height; DrawScrollRegion(sb); return(sb->state.value); } ButtonRegion(sb) register ScrollBar *sb; { register int reverse, pagesize; if(!(sb->buttonset & HILITED)) return(sb->set.value); reverse = (sb->set.bottomvalue > sb->set.topvalue); pagesize = sb->set.regionheight - 1; switch(sb->buttonset) { case BUTTON_UPLINEHI: if(reverse) sb->set.value--; else sb->set.value++; break; case BUTTON_DOWNLINEHI: if(reverse) sb->set.value++; else sb->set.value--; break; case BUTTON_UPPAGEHI: if(reverse) sb->set.value -= pagesize; else sb->set.value += pagesize; break; case BUTTON_DOWNPAGEHI: if(reverse) sb->set.value += pagesize; else sb->set.value -= pagesize; break; case BUTTON_TOPHI: sb->set.value = sb->set.topvalue; break; case BUTTON_BOTTOMHI: sb->set.value = sb->set.bottomvalue; } DrawScrollRegion(sb); return(sb->set.value); } DownButtonDown(term, reply, pty) Terminal *term; register XKeyOrButtonEvent *reply; int pty; /* file descriptor of pty */ { register Screen *screen = &term->screen; register ScrollBar *sb = screen->sb; register Window window = reply->subwindow; if(!window || window == sb->region) { WindowScroll(screen, PositionRegion(sb, reply->y)); return; } if(window == sb->save) { SetSaveState(sb, !GetSaveState(sb)); return; } if(window != sb->button || !XGrabMouse(sb->button, sb->cursor, ButtonReleased | EnterWindow | LeaveWindow)) { Bell(); return; } if(reply->detail & ControlMask) sb->buttonset = BUTTON_BOTTOMHI; else if(reply->detail & ShiftMask) sb->buttonset = BUTTON_DOWNPAGEHI; else { sb->buttonset = BUTTON_DOWNLINEHI; stepspeed.tv_usec = PAUSETIME; screen->timeout = &stepspeed; WindowScroll(screen, ButtonRegion(screen->sb)); } DrawButton(sb); } UpButtonDown(term, reply, pty) Terminal *term; register XKeyOrButtonEvent *reply; int pty; /* file descriptor of pty */ { register Screen *screen = &term->screen; register ScrollBar *sb = screen->sb; register Window window = reply->subwindow; if(!window || window == sb->region) { WindowScroll(screen, PositionRegion(sb, reply->y)); return; } if(window == sb->save) { SetSaveState(sb, !GetSaveState(sb)); return; } if(window != sb->button || !XGrabMouse(sb->button, sb->cursor, ButtonReleased | EnterWindow | LeaveWindow)) { Bell(); return; } if(reply->detail & ControlMask) sb->buttonset = BUTTON_TOPHI; else if(reply->detail & ShiftMask) sb->buttonset = BUTTON_UPPAGEHI; else { sb->buttonset = BUTTON_UPLINEHI; stepspeed.tv_usec = PAUSETIME; screen->timeout = &stepspeed; WindowScroll(screen, ButtonRegion(screen->sb)); } DrawButton(sb); } ButtonUp(term, reply, pty) Terminal *term; XKeyOrButtonEvent *reply; int pty; /* file descriptor of pty */ { register Screen *screen = &term->screen; register ScrollBar *sb = screen->sb; register int state; if((state = GetButtonState(sb)) == BUTTON_NORMAL) return; /* don't scroll further on line mode */ if(state > BUTTON_DOWNLINEHI) WindowScroll(screen, ButtonRegion(sb)); sb->buttonset = BUTTON_NORMAL; DrawButton(sb); screen->timeout = NULL; XUngrabMouse(); } WindowScroll(screen, top) register Screen *screen; int top; { register int i, lines; register int scrolltop, scrollheight, refreshtop; if((i = screen->topline - top) == 0) return; if(screen->cursor_state) HideCursor(); lines = i > 0 ? i : -i; if(lines > screen->max_row + 1) lines = screen->max_row + 1; scrollheight = screen->max_row - lines + 1; if(i > 0) refreshtop = scrolltop = 0; else { scrolltop = lines; refreshtop = scrollheight; } if(scrollheight > 0) { if (screen->multiscroll && scrollheight == 1 && screen->topline == 0 && screen->top_marg == 0 && screen->bot_marg == screen->max_row) { if (screen->incopy < 0 && screen->scrolls == 0) CopyWait (screen); screen->scrolls++; } else { if (screen->incopy) CopyWait (screen); screen->incopy = -1; } XMoveArea(VWindow(screen), screen->border, scrolltop * FontHeight(screen) + screen->border + Titlebar(screen), screen->border, (scrolltop + i) * FontHeight(screen) + screen->border + Titlebar(screen), Width(screen), scrollheight * FontHeight(screen)); } screen->topline = top; XTileSet(VWindow(screen), screen->border, refreshtop * FontHeight(screen) + screen->border + Titlebar(screen), Width(screen), lines * FontHeight(screen), screen->bgndtile); ScrnRefresh(screen, refreshtop, 0, lines, screen->max_col + 1); } ScrollBarOn(screen, show, init) register Screen *screen; int show, init; { register int border = 2 * screen->border; register int i; char *realloc(), *calloc(); if(screen->scrollbar) return; if(!screen->sb) { if((screen->sb = CreateScrollBar(VWindow(screen), Width(screen) + border, Titlebar(screen) - 1, Height(screen) + border, screen->foreground, screen->background, screen->bordertile, 0, screen->max_row + 1, 0, 0, screen->arrow)) == NULL) { Bell(); return; } if((screen->allbuf = (ScrnBuf) realloc(screen->buf, 2*(screen->max_row + 2 + screen->savelines) * sizeof(char *))) == NULL) Error (ERROR_SBRALLOC); screen->buf = &screen->allbuf[2 * screen->savelines]; bcopy ((char *)screen->allbuf, (char *)screen->buf, 2 * (screen->max_row + 2) * sizeof (char *)); for(i = 2 * screen->savelines - 1 ; i >= 0 ; i--) if((screen->allbuf[i] = calloc(screen->max_col + 1, sizeof(char))) == NULL) Error (ERROR_SBRALLOC2); screen->sb->saveset = !screen->alternate; } else { XConfigureWindow(screen->sb->bar, FullWidth(screen), Titlebar(screen) - 1, (SCROLLBARWIDTH - 1), i = FullHeight(screen) - Titlebar(screen)); screen->sb->set.height = i - BARSTART; screen->sb->set.regionheight = screen->max_row + 1; } if(show) { screen->scrollbar = SCROLLBARWIDTH; ShowScrollBar(screen->sb); if(!init) { XSetResizeHint(VWindow(screen), border + SCROLLBARWIDTH, border + Titlebar(screen) + screen->statusheight, FontWidth(screen), FontHeight(screen)); XChangeWindow(VWindow(screen), (screen->max_col + 1) * FontWidth(screen) + border + SCROLLBARWIDTH, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + border + Titlebar(screen)); } } } ScrollBarOff(screen) register Screen *screen; { register int border = 2 * screen->border; if(!screen->scrollbar) return; screen->sb->action = HIDE; screen->scrollbar = 0; XSetResizeHint(VWindow(screen), border, border + Titlebar(screen) + screen->statusheight, FontWidth(screen), FontHeight(screen)); XChangeWindow(VWindow(screen), (screen->max_col + 1) * FontWidth(screen) + border, FontHeight(screen) * (screen->max_row + 1) + screen->statusheight + border + Titlebar(screen)); } ClearLinesOffTop(screen) register Screen *screen; { if(!screen->sb) return; if(screen->topline) WindowScroll(screen, 0); SetScrollBarTop(screen->sb, 0); DrawScrollRegion(screen->sb); } SetSaveState(sb, state) register ScrollBar *sb; int state; { extern Terminal term; register Screen *screen = &term.screen; if(screen->alternate) return; if(screen->scroll_amt) FlushScroll(screen); sb->saveset = state; DrawSave(sb); } SetButtonState(sb, state) register ScrollBar *sb; int state; { sb->buttonset = state; DrawButton(sb); } static Window Make_tiled_window(bitmap_width, bitmap_height, bitmap_bits, foreground, background, bgnd, parent, x, y, width, height, borderwidth, bordertile) int bitmap_width, bitmap_height, foreground, background, x, y, width, height, borderwidth; short *bitmap_bits; Window parent; Pixmap *bgnd, bordertile; { register Pixmap pix; register Window w; extern Pixmap Make_tile(); if((pix = Make_tile(bitmap_width, bitmap_height, bitmap_bits, foreground, background)) == NULL) return(NULL); w = XCreateWindow(parent, x, y, width, height, borderwidth, bordertile, pix); *bgnd = pix; return(w); } Pixmap Make_tile(bitmap_width, bitmap_height, bitmap_bits, foreground, background) int bitmap_width, bitmap_height, foreground, background; short *bitmap_bits; { register Bitmap bm; register Pixmap pix; if((bm = XStoreBitmap(bitmap_width, bitmap_height, bitmap_bits)) == NULL) return(NULL); pix = XMakePixmap(bm, foreground, background); XFreeBitmap(bm); return(pix); } ScrollToBottom(sb) register ScrollBar *sb; { SetScrollBarValue(sb, GetScrollBarBottom(sb)); DrawScrollRegion(sb); WindowScroll(&term.screen, GetScrollBarValue(sb)); } #ifdef MODEMENU #define SMENU_SCROLLKEY 0 #define SMENU_SCROLLINPUT (SMENU_SCROLLKEY+1) #define SMENU_LINESTOP (SMENU_SCROLLINPUT+1) #define SMENU_LINE (SMENU_LINESTOP+1) #define SMENU_CLEARTOP (SMENU_LINE+1) #define SMENU_HIDE (SMENU_CLEARTOP+1) static char *stext[] = { "Scroll to Bottom on Key", "Scroll to Bottom on Input", "Lines Off Top Saved", "-", "Clear Lines Off Top", "Hide Scrollbar", 0, }; static int salternate; static int slinestop; static int sscrollinput; static int sscrollkey; Menu *ssetupmenu(menu) register Menu **menu; { register Screen *screen = &term.screen; register char **cp; if (*menu == NULL) { if ((*menu = NewMenu("Scrollbar", re_verse)) == NULL) return(NULL); for(cp = stext ; *cp ; cp++) AddMenuItem(*menu, *cp); if(sscrollkey = screen->scrollkey) CheckItem(*menu, SMENU_SCROLLKEY); if(sscrollinput = screen->scrollinput) CheckItem(*menu, SMENU_SCROLLINPUT); if(slinestop = (screen->sb && GetSaveState(screen->sb))) CheckItem(*menu, SMENU_LINESTOP); if(salternate = screen->alternate) DisableItem(*menu, SMENU_LINESTOP); DisableItem(*menu, SMENU_LINE); return(*menu); } if(sscrollkey != screen->scrollkey) SetItemCheck(*menu, SMENU_SCROLLKEY, (sscrollkey = screen->scrollkey)); if(sscrollinput != screen->scrollinput) SetItemCheck(*menu, SMENU_SCROLLINPUT, (sscrollinput = screen->scrollinput)); if(screen->sb && slinestop != GetSaveState(screen->sb)) SetItemCheck(*menu, SMENU_LINESTOP, (slinestop = GetSaveState(screen->sb))); if(salternate != screen->alternate) SetItemDisable(*menu, SMENU_LINESTOP, (salternate = screen->alternate)); return(*menu); } sdomenufunc(item) int item; { register Screen *screen = &term.screen; switch (item) { case SMENU_SCROLLKEY: screen->scrollkey = !screen->scrollkey; break; case SMENU_SCROLLINPUT: screen->scrollinput = !screen->scrollinput; break; case SMENU_LINESTOP: SetSaveState(screen->sb, !GetSaveState(screen->sb)); break; case SMENU_CLEARTOP: ClearLinesOffTop(screen); break; case SMENU_HIDE: ScrollBarOff(screen); break; } } #endif MODEMENU