/* X11buttons - buttons for X11 dialogs and windows */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
/***********************************************************************/
/** **/
/** General Includes and Definitions **/
/** **/
/***********************************************************************/
#include "xlisp.h"
#include "xlstat.h"
#include "xlgraph.h"
extern Display *StX11Display();
extern LVAL StX11ItemObject();
extern XContext EventContext, ObjectContext, ThumbContext, ScrollActionContext;
extern Cursor DoubleArrowCursor, RightArrowCursor, LeftArrowCursor;
extern Cursor UpDownArrowCursor, UpArrowCursor, DownArrowCursor;
extern Pixmap ScrollThumbPM;
/* forward declarations */
LOCAL int is_vertical_scroll_bar _((Window s));
/***********************************************************************/
/** **/
/** Event Handler **/
/** **/
/***********************************************************************/
static LVAL scroll_handler(report, modal)
XEvent report;
int modal;
{
Display *dpy = StX11Display();
Window s;
LVAL object;
int up, is_vertical, x, y, old_x, old_y, (*action)();
s = report.xany.window;
if (XFindContext(dpy, s, ObjectContext, (caddr_t *) &object) == 0 &&
objectp(object)) {
is_vertical = is_vertical_scroll_bar(s);
if (XFindContext(dpy, s, ScrollActionContext, (caddr_t *) &action) != 0)
xlfail("can't find thumb context");
switch (report.type) {
case ButtonPress:
switch (report.xbutton.button) {
case Button1:
case Button3:
up = (report.xbutton.button == Button1) ? TRUE : FALSE;
if (is_vertical)
XDefineCursor(dpy, s, (up) ? UpArrowCursor : DownArrowCursor);
else
XDefineCursor(dpy, s, (up) ? LeftArrowCursor : RightArrowCursor);
if (action != NULL)
(*action)(object, s, (up) ? 'L' : 'R',
report.xbutton.x, report.xbutton.y);
while (! XCheckTypedEvent(dpy, ButtonRelease, &report));
if (is_vertical) XDefineCursor(dpy, s, UpDownArrowCursor);
else XDefineCursor(dpy, s, DoubleArrowCursor);
break;
case Button2:
if (action != NULL)
(*action)(object, s, 'M', report.xbutton.x, report.xbutton.y);
XSync(dpy, FALSE);
#ifdef DODO
XGrabPointer(dpy, s, TRUE, ButtonMotionMask,
GrabModeAsync, GrabModeAsync, s, None, CurrentTime);
#endif /* DODO */
x = report.xbutton.x;
y = report.xbutton.y;
old_x = x;
old_y = y;
while (! XCheckWindowEvent(dpy, s, ButtonReleaseMask, &report)) {
while (XCheckWindowEvent(dpy, s, ButtonMotionMask, &report)) {
x = report.xmotion.x;
y = report.xmotion.y;
}
if (x != old_x || y != old_y) {
if (action != NULL)
(*action)(object, s, 'M', report.xbutton.x, report.xbutton.y);
XSync(dpy, FALSE);
old_x = x;
old_y = y;
}
}
#ifdef DODO
XUngrabPointer(dpy, CurrentTime);
#endif /* DODO */
break;
}
break;
}
}
return(NIL);
}
/***********************************************************************/
/** **/
/** Constructing and Removing Scrollbars **/
/** **/
/***********************************************************************/
VOID InstallScrollBar(w, object, left, top, width, height, ps, action)
Window w, *ps;
LVAL object;
int left, top, width, height;
VOID (*action) ();
{
Display *dpy = StX11Display();
int screen = StX11Screen();
Window s, thumb;
s = XCreateSimpleWindow(dpy, w, left, top, width, height, 1,
BlackPixel(dpy, screen), WhitePixel(dpy, screen));
XSelectInput(dpy, s,
ExposureMask | ButtonMotionMask |
ButtonPressMask | ButtonReleaseMask);
thumb = XCreateSimpleWindow(dpy, s, left, top, width, height, 0,
WhitePixel(dpy, screen),
WhitePixel(dpy, screen));
XSetWindowBackgroundPixmap(dpy, thumb, ScrollThumbPM);
if (width > height) XDefineCursor(dpy, s, DoubleArrowCursor);
else XDefineCursor(dpy, s, UpDownArrowCursor);
if (XSaveContext(dpy, s, EventContext, (caddr_t) scroll_handler) != 0)
xlfail("could not install event handler");
if (XSaveContext(dpy, s, ObjectContext, (caddr_t) object) != 0)
xlfail("could not install object in scroll bar");
if (XSaveContext(dpy, s, ThumbContext, (caddr_t) thumb) != 0)
xlfail("could not install thumb in scroll bar");
if (XSaveContext(dpy, s, ScrollActionContext, (caddr_t) action) != 0)
xlfail("could not install action in scroll bar");
XMapSubwindows(dpy, s);
*ps = s;
}
VOID DeleteScrollBar(s)
Window s;
{
Display *dpy = StX11Display();
if (XDeleteContext(dpy, s, EventContext) != 0)
xlfail("could not delete event context");
if (XDeleteContext(dpy, s, ObjectContext) != 0)
xlfail("could not delete object context");
if (XDeleteContext(dpy, s, ThumbContext) != 0)
xlfail("could not delete thumb context");
if (XDeleteContext(dpy, s, ScrollActionContext) != 0)
xlfail("could not delete action context");
}
/***********************************************************************/
/** **/
/** Hiding and Showing Scrollbars **/
/** **/
/***********************************************************************/
VOID ShowScrollBar(s, left, top, width, height)
Window s;
int left, top, width, height;
{
Display *dpy = StX11Display();
XMoveResizeWindow(dpy, s, left, top, width, height);
XMapWindow(dpy, s);
}
VOID HideScrollBar(s)
Window s;
{
Display *dpy = StX11Display();
XUnmapWindow(dpy, s);
}
/***********************************************************************/
/** **/
/** Adjusting Scrollbars **/
/** **/
/***********************************************************************/
VOID AdjustScrollBar(s, val, page, max)
Window s;
int val, page, max;
{
Display *dpy = StX11Display();
Window root, thumb;
int left, top;
unsigned int width, height, b_width, depth;
int tleft, ttop, twidth, theight;
double val_frac, page_frac;
if (max > 0) {
XGetGeometry(dpy, s, &root, &left, &top, &width, &height,
&b_width, &depth);
if (XFindContext(dpy, s, ThumbContext, (caddr_t *) &thumb) != 0)
xlfail("can't find thumb context");
val_frac = ((double) val / (double) max);
page_frac = ((double) page / (double) max);
if (width > height) { /* horizontal scroll bar */
ttop = 0;
theight = height;
tleft = width * val_frac;
twidth = width * page_frac;
}
else { /* vertical scroll bar */
tleft = 0;
twidth = width;
ttop = height * val_frac;
theight = height * page_frac;
}
XMoveResizeWindow(dpy, thumb, tleft, ttop, twidth, theight);
}
}
LOCAL int is_vertical_scroll_bar(s)
Window s;
{
Display *dpy = StX11Display();
Window root;
int lx, ly;
unsigned int width, height, b_width, depth;
XGetGeometry(dpy, s, &root, &lx, &ly, &width, &height, &b_width, &depth);
return((height > width) ? TRUE : FALSE);
}
syntax highlighted by Code2HTML, v. 0.9.1