aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/xgterm/scrollbar.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/xgterm/scrollbar.c')
-rw-r--r--vendor/x11iraf/xgterm/scrollbar.c531
1 files changed, 531 insertions, 0 deletions
diff --git a/vendor/x11iraf/xgterm/scrollbar.c b/vendor/x11iraf/xgterm/scrollbar.c
new file mode 100644
index 00000000..ca077b43
--- /dev/null
+++ b/vendor/x11iraf/xgterm/scrollbar.c
@@ -0,0 +1,531 @@
+/*
+ * $XConsortium: scrollbar.c,v 1.44 94/04/02 12:42:01 gildea Exp $
+ */
+
+/*
+ * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital Equipment
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ *
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include "ptyx.h" /* gets Xt headers, too */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/Xatom.h>
+
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+
+#include <X11/Xaw/Scrollbar.h>
+
+#include "data.h"
+#include "error.h"
+#include "menu.h"
+
+/* Event handlers */
+
+static void ScrollTextTo();
+static void ScrollTextUpDownBy();
+
+
+/* resize the text window for a terminal screen, modifying the
+ * appropriate WM_SIZE_HINTS and taking advantage of bit gravity.
+ */
+
+static void ResizeScreen(xw, min_width, min_height )
+ register XgtermWidget xw;
+ int min_width, min_height;
+{
+ register TScreen *screen = &xw->screen;
+#ifndef nothack
+ XSizeHints sizehints;
+ long supp;
+#endif
+ XtGeometryResult geomreqresult;
+ Dimension reqWidth, reqHeight, repWidth, repHeight;
+
+ /*
+ * I'm going to try to explain, as I understand it, why we
+ * have to do XGetWMNormalHints and XSetWMNormalHints here,
+ * although I can't guarantee that I've got it right.
+ *
+ * In a correctly written toolkit program, the Shell widget
+ * parses the user supplied geometry argument. However,
+ * because of the way xgterm does things, the VT100 widget does
+ * the parsing of the geometry option, not the Shell widget.
+ * The result of this is that the Shell widget doesn't set the
+ * correct window manager hints, and doesn't know that the
+ * user has specified a geometry.
+ *
+ * The XtVaSetValues call below tells the Shell widget to
+ * change its hints. However, since it's confused about the
+ * hints to begin with, it doesn't get them all right when it
+ * does the SetValues -- it undoes some of what the VT100
+ * widget did when it originally set the hints.
+ *
+ * To fix this, we do the following:
+ *
+ * 1. Get the sizehints directly from the window, going around
+ * the (confused) shell widget.
+ * 2. Call XtVaSetValues to let the shell widget know which
+ * hints have changed. Note that this may not even be
+ * necessary, since we're going to right ahead after that
+ * and set the hints ourselves, but it's good to put it
+ * here anyway, so that when we finally do fix the code so
+ * that the Shell does the right thing with hints, we
+ * already have the XtVaSetValues in place.
+ * 3. We set the sizehints directly, this fixing up whatever
+ * damage was done by the Shell widget during the
+ * XtVaSetValues.
+ *
+ * Gross, huh?
+ *
+ * The correct fix is to redo VTRealize, VTInitialize and
+ * VTSetValues so that font processing happens early enough to
+ * give back responsibility for the size hints to the Shell.
+ *
+ * Someday, we hope to have time to do this. Someday, we hope
+ * to have time to completely rewrite xgterm.
+ */
+
+#ifndef nothack
+ /*
+ * NOTE: If you change the way any of the hints are calculated
+ * below, make sure you change the calculation both in the
+ * sizehints assignments and in the XtVaSetValues.
+ */
+
+ if (! XGetWMNormalHints(screen->display, XtWindow(XtParent(xw)),
+ &sizehints, &supp))
+ sizehints.flags = 0;
+ sizehints.base_width = min_width;
+ sizehints.base_height = min_height;
+ sizehints.width_inc = FontWidth(screen);
+ sizehints.height_inc = FontHeight(screen);
+ sizehints.min_width = sizehints.base_width + sizehints.width_inc;
+ sizehints.min_height = sizehints.base_height + sizehints.height_inc;
+ sizehints.flags |= (PBaseSize|PMinSize|PResizeInc);
+ /* These are obsolete, but old clients may use them */
+ sizehints.width = (screen->max_col + 1) * FontWidth(screen)
+ + min_width;
+ sizehints.height = (screen->max_row + 1) * FontHeight(screen)
+ + min_height;
+#endif
+
+ /*
+ * Note: width and height are not set here because they are
+ * obsolete.
+ */
+ XtVaSetValues(XtParent(xw),
+ XtNbaseWidth, min_width,
+ XtNbaseHeight, min_height,
+ XtNwidthInc, FontWidth(screen),
+ XtNheightInc, FontHeight(screen),
+ XtNminWidth, min_width + FontWidth(screen),
+ XtNminHeight, min_height + FontHeight(screen),
+ NULL);
+
+ reqWidth = (screen->max_col + 1) * FontWidth(screen) + min_width;
+ reqHeight = FontHeight(screen) * (screen->max_row + 1) + min_height;
+ geomreqresult = XtMakeResizeRequest ((Widget)xw, reqWidth, reqHeight,
+ &repWidth, &repHeight);
+
+ if (geomreqresult == XtGeometryAlmost) {
+ geomreqresult = XtMakeResizeRequest ((Widget)xw, repWidth,
+ repHeight, NULL, NULL);
+ }
+
+#ifndef nothack
+ XSetWMNormalHints(screen->display, XtWindow(XtParent(xw)), &sizehints);
+#endif
+}
+
+void DoResizeScreen (xw)
+ register XgtermWidget xw;
+{
+ int border = 2 * xw->screen.border;
+ ResizeScreen (xw, border + xw->screen.scrollbar, border);
+}
+
+
+static Widget CreateScrollBar(xw, x, y, height)
+ XgtermWidget xw;
+ int x, y, height;
+{
+ Widget scrollWidget;
+
+ static Arg argList[] = {
+ {XtNx, (XtArgVal) 0},
+ {XtNy, (XtArgVal) 0},
+ {XtNheight, (XtArgVal) 0},
+ {XtNreverseVideo, (XtArgVal) 0},
+ {XtNorientation, (XtArgVal) XtorientVertical},
+ {XtNborderWidth, (XtArgVal) 1},
+ };
+
+ argList[0].value = (XtArgVal) x;
+ argList[1].value = (XtArgVal) y;
+ argList[2].value = (XtArgVal) height;
+ argList[3].value = (XtArgVal) xw->misc.re_verse;
+
+ scrollWidget = XtCreateWidget("scrollbar", scrollbarWidgetClass,
+ (Widget)xw, argList, XtNumber(argList));
+ XtAddCallback (scrollWidget, XtNscrollProc, ScrollTextUpDownBy, 0);
+ XtAddCallback (scrollWidget, XtNjumpProc, ScrollTextTo, 0);
+ return (scrollWidget);
+}
+
+static void RealizeScrollBar (sbw, screen)
+ Widget sbw;
+ TScreen *screen;
+{
+ XtRealizeWidget (sbw);
+}
+
+
+ScrollBarReverseVideo(scrollWidget)
+ register Widget scrollWidget;
+{
+ Arg args[4];
+ int nargs = XtNumber(args);
+ unsigned long bg, fg, bdr;
+ Pixmap bdpix;
+
+ XtSetArg(args[0], XtNbackground, &bg);
+ XtSetArg(args[1], XtNforeground, &fg);
+ XtSetArg(args[2], XtNborderColor, &bdr);
+ XtSetArg(args[3], XtNborderPixmap, &bdpix);
+ XtGetValues (scrollWidget, args, nargs);
+ args[0].value = (XtArgVal) fg;
+ args[1].value = (XtArgVal) bg;
+ nargs--; /* don't set border_pixmap */
+ if (bdpix == XtUnspecifiedPixmap) { /* if not pixmap then pixel */
+ args[2].value = args[1].value; /* set border to new fg */
+ } else { /* ignore since pixmap */
+ nargs--; /* don't set border pixel */
+ }
+ XtSetValues (scrollWidget, args, nargs);
+}
+
+
+
+ScrollBarDrawThumb(scrollWidget)
+ register Widget scrollWidget;
+{
+ register TScreen *screen = &term->screen;
+ register int thumbTop, thumbHeight, totalHeight;
+
+ thumbTop = screen->topline + screen->savedlines;
+ thumbHeight = screen->max_row + 1;
+ totalHeight = thumbHeight + screen->savedlines;
+
+ XawScrollbarSetThumb(scrollWidget,
+ ((float)thumbTop) / totalHeight,
+ ((float)thumbHeight) / totalHeight);
+
+}
+
+ResizeScrollBar(scrollWidget, x, y, height)
+ register Widget scrollWidget;
+ int x, y;
+ unsigned height;
+{
+ XtConfigureWidget(scrollWidget, x, y, scrollWidget->core.width,
+ height, scrollWidget->core.border_width);
+ if (term->misc.sb_right)
+ XtMoveWidget(scrollWidget, x,y);
+ ScrollBarDrawThumb(scrollWidget);
+}
+
+WindowScroll(screen, top)
+ register TScreen *screen;
+ int top;
+{
+ register int i, lines;
+ register int scrolltop, scrollheight, refreshtop;
+ register int x = 0;
+
+ if (top < -screen->savedlines)
+ top = -screen->savedlines;
+ else if (top > 0)
+ top = 0;
+ if((i = screen->topline - top) == 0) {
+ ScrollBarDrawThumb(screen->scrollWidget);
+ 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;
+ }
+ x = (term->misc.sb_right? screen->border : screen->scrollbar+screen->border);
+ scrolling_copy_area(screen, scrolltop, scrollheight, -i);
+ screen->topline = top;
+
+ ScrollSelection(screen, i);
+
+ XClearArea(
+ screen->display,
+ TextWindow(screen),
+ (int) x,
+ (int) refreshtop * FontHeight(screen) + screen->border,
+ (unsigned) Width(screen),
+ (unsigned) lines * FontHeight(screen),
+ FALSE);
+ ScrnRefresh(screen, refreshtop, 0, lines, screen->max_col + 1, False);
+
+ ScrollBarDrawThumb(screen->scrollWidget);
+}
+
+
+ScrollBarOn (xw, init, doalloc)
+ XgtermWidget xw;
+ int init, doalloc;
+{
+ register TScreen *screen = &xw->screen;
+ register int border = 2 * screen->border;
+ register int i;
+
+ if(screen->scrollbar)
+ return;
+
+ if (init) { /* then create it only */
+ if (screen->scrollWidget) return;
+
+ /* make it a dummy size and resize later */
+ if ((screen->scrollWidget = CreateScrollBar (xw, -1, - 1, 5))
+ == NULL) {
+ Bell();
+ return;
+ }
+
+ return;
+
+ }
+
+ if (!screen->scrollWidget) {
+ Bell ();
+ Bell ();
+ return;
+ }
+
+ if (doalloc && screen->allbuf) {
+ if((screen->allbuf =
+ (ScrnBuf) realloc((char *) screen->buf,
+ (unsigned) 4*(screen->max_row + 2 +
+ screen->savelines) *
+ sizeof(char *)))
+ == NULL)
+ Error (ERROR_SBRALLOC);
+ screen->buf = &screen->allbuf[4 * screen->savelines];
+ memmove( (char *)screen->buf, (char *)screen->allbuf,
+ 4 * (screen->max_row + 2) * sizeof (char *));
+ for(i = 4 * screen->savelines - 1 ; i >= 0 ; i--)
+ if((screen->allbuf[i] =
+ (Char *)calloc((unsigned) screen->max_col+1, sizeof(char))) ==
+ NULL)
+ Error (ERROR_SBRALLOC2);
+ }
+
+ if (term->misc.sb_right) {
+ ResizeScrollBar (screen->scrollWidget,
+ screen->fullVwin.fullwidth -
+ screen->scrollWidget->core.width -
+ screen->scrollWidget->core.border_width,
+ 0,
+ Height (screen) + border -1);
+ } else {
+ ResizeScrollBar (screen->scrollWidget, -1, -1,
+ Height (screen) + border);
+ }
+ RealizeScrollBar (screen->scrollWidget, screen);
+ screen->scrollbar = screen->scrollWidget->core.width +
+ screen->scrollWidget->core.border_width;
+
+ ScrollBarDrawThumb(screen->scrollWidget);
+ DoResizeScreen (xw);
+ XtMapWidget(screen->scrollWidget);
+ update_scrollbar ();
+ if (screen->buf) {
+ XClearWindow (screen->display, XtWindow (term));
+ Redraw ();
+ }
+}
+
+ScrollBarOff(screen)
+ register TScreen *screen;
+{
+ if(!screen->scrollbar)
+ return;
+ XtUnmapWidget(screen->scrollWidget);
+ screen->scrollbar = 0;
+ DoResizeScreen (term);
+ update_scrollbar ();
+ if (screen->buf) {
+ XClearWindow (screen->display, XtWindow (term));
+ Redraw ();
+ }
+}
+
+/*ARGSUSED*/
+static void ScrollTextTo(scrollbarWidget, client_data, call_data)
+ Widget scrollbarWidget;
+ XtPointer client_data;
+ XtPointer call_data;
+{
+ float *topPercent = (float *) call_data;
+ register TScreen *screen = &term->screen;
+ int thumbTop; /* relative to first saved line */
+ int newTopLine;
+
+/*
+ screen->savedlines : Number of offscreen text lines,
+ screen->maxrow + 1 : Number of onscreen text lines,
+ screen->topline : -Number of lines above the last screen->max_row+1 lines
+*/
+
+ thumbTop = *topPercent * (screen->savedlines + screen->max_row+1);
+ newTopLine = thumbTop - screen->savedlines;
+ WindowScroll(screen, newTopLine);
+}
+
+/*ARGSUSED*/
+static void ScrollTextUpDownBy(scrollbarWidget, client_data, call_data)
+ Widget scrollbarWidget;
+ XtPointer client_data;
+ XtPointer call_data;
+{
+ int pixels = (int) call_data;
+
+ register TScreen *screen = &term->screen;
+ register int rowOnScreen, newTopLine;
+
+ rowOnScreen = pixels / FontHeight(screen);
+ if (rowOnScreen == 0) {
+ if (pixels < 0)
+ rowOnScreen = -1;
+ else if (pixels > 0)
+ rowOnScreen = 1;
+ }
+ newTopLine = screen->topline + rowOnScreen;
+ WindowScroll(screen, newTopLine);
+}
+
+
+/*
+ * assume that b is lower case and allow plural
+ */
+static int specialcmplowerwiths (a, b)
+ char *a, *b;
+{
+ register char ca, cb;
+
+ if (!a || !b) return 0;
+
+ while (1) {
+ ca = *a;
+ cb = *b;
+ if (isascii(ca) && isupper(ca)) { /* lowercasify */
+#ifdef _tolower
+ ca = _tolower (ca);
+#else
+ ca = tolower (ca);
+#endif
+ }
+ if (ca != cb || ca == '\0') break; /* if not eq else both nul */
+ a++, b++;
+ }
+ if (cb == '\0' && (ca == '\0' || (ca == 's' && a[1] == '\0')))
+ return 1;
+
+ return 0;
+}
+
+static int params_to_pixels (screen, params, n)
+ TScreen *screen;
+ String *params;
+ int n;
+{
+ register mult = 1;
+ register char *s;
+
+ switch (n > 2 ? 2 : n) {
+ case 2:
+ s = params[1];
+ if (specialcmplowerwiths (s, "page")) {
+ mult = (screen->max_row + 1) * FontHeight(screen);
+ } else if (specialcmplowerwiths (s, "halfpage")) {
+ mult = ((screen->max_row + 1) * FontHeight(screen)) >> 1;
+ } else if (specialcmplowerwiths (s, "pixel")) {
+ mult = 1;
+ } /* else assume that it is Line */
+ mult *= atoi (params[0]);
+ break;
+ case 1:
+ mult = atoi (params[0]) * FontHeight(screen); /* lines */
+ break;
+ default:
+ mult = screen->scrolllines * FontHeight(screen);
+ break;
+ }
+
+ return mult;
+}
+
+
+/*ARGSUSED*/
+void HandleScrollForward (gw, event, params, nparams)
+ Widget gw;
+ XEvent *event;
+ String *params;
+ Cardinal *nparams;
+{
+ XgtermWidget w = (XgtermWidget) gw;
+ register TScreen *screen = &w->screen;
+
+ ScrollTextUpDownBy (gw, (XtPointer) NULL,
+ (XtPointer)params_to_pixels (screen, params, (int) *nparams));
+ return;
+}
+
+
+/*ARGSUSED*/
+void HandleScrollBack (gw, event, params, nparams)
+ Widget gw;
+ XEvent *event;
+ String *params;
+ Cardinal *nparams;
+{
+ XgtermWidget w = (XgtermWidget) gw;
+ register TScreen *screen = &w->screen;
+
+ ScrollTextUpDownBy (gw, (XtPointer) NULL,
+ (XtPointer)-params_to_pixels (screen, params, (int) *nparams));
+ return;
+}