home *** CD-ROM | disk | FTP | other *** search
- /* X11slider - slider/scroll items for X11 dialogs */
- /* 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 <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/Xos.h>
-
- #include "dialogs.h"
-
- extern Display *StX11Display();
- extern Point DialogStringSize();
- extern LVAL StX11ItemObject();
- extern char *checkstring();
-
- typedef struct {
- unsigned long fore, back;
- } ColorPair;
-
- /* layout defines */
- # define BUTTON_SIZE 16
- # define MIN_SLIDER_HEIGHT 16
- # define MIN_SLIDER_WIDTH 250
- # define THUMB_WIDTH BUTTON_SIZE / 2
-
- /***********************************************************************/
- /** **/
- /** Global Variables **/
- /** **/
- /***********************************************************************/
-
- /* configuration parameters - should be set using the defaults database */
- extern XFontStruct *DialogFont;
- extern unsigned long DialogBorderColor;
- extern ColorPair DialogC;
- extern unsigned int dialog_border_width;
- extern int min_slider_width;
-
- extern GC DialogGC, DialogRGC;
-
- extern XContext ObjectContext, Button1Context,
- Button2Context, ThumbContext;
-
- extern Pixmap LeftSliderPM, RightSliderPM;
- extern Cursor DoubleArrowCursor, RightArrowCursor, LeftArrowCursor,
- ArrowCursor;
-
- /***********************************************************************/
- /** **/
- /** Slider Items **/
- /** **/
- /***********************************************************************/
-
- static adjust_slider(item)
- LVAL item;
- {
- Display *dpy = StX11Display();
- LVAL win_id;
- LVAL s_window_id = xlenter("WINDOW-ID");
- Window win, thumb;
- Point size;
- int left, low, high, val, width;
- double x;
-
- win_id = slot_value(item, s_window_id);
- if (fixp(win_id)) {
- win = (Window) getfixnum(win_id);
- size = ListToPoint(slot_value(item, s_size));
- low = getfixnum(slot_value(item, s_min_value));
- high = getfixnum(slot_value(item, s_max_value));
- val = getfixnum(slot_value(item, s_value));
- width = size.h - 2 * BUTTON_SIZE - THUMB_WIDTH;
- if (low < high) {
- x = ((double) (val - low)) / ((double) (high - low));
- left = BUTTON_SIZE + x * width;
- left = max(BUTTON_SIZE, min(left, width + BUTTON_SIZE));
- }
- else left = BUTTON_SIZE;
- if (XFindContext(dpy, win, ThumbContext, &thumb) != 0)
- xlfail("can't find thumb context");
- XMoveWindow(dpy, thumb, left, 0);
- }
- }
-
- static track_thumb(dpy, win, report, item)
- Display *dpy;
- Window win;
- XEvent report;
- LVAL item;
- {
- Point size;
- int low, high, val, old_val, width, page, up, done = FALSE;
- double x;
-
- size = ListToPoint(slot_value(item, s_size));
- low = getfixnum(slot_value(item, s_min_value));
- high = getfixnum(slot_value(item, s_max_value));
- width = size.h - 2 * BUTTON_SIZE - THUMB_WIDTH;
-
- switch (report.xbutton.button) {
- case Button1:
- case Button3:
- up = (report.xbutton.button == Button3) ? TRUE : FALSE;
- XDefineCursor(dpy, win, (up) ? RightArrowCursor : LeftArrowCursor);
- old_val = low - 1; /* an "impossible" value */
- while (! done) {
- if (XCheckTypedEvent(dpy, ButtonRelease, &report)) done = TRUE;
- else{
- val = getfixnum(slot_value(item, s_value));
- page = getfixnum(slot_value(item, s_page_increment));
- if (up) val += page;
- else val -= page;
- val = max(low, min(val, high));
- DialogScrollItemValue(item, TRUE, val);
- if (val != old_val) send_message(item, sk_scroll_action);
- old_val = val;
- XSync(dpy, FALSE);
- }
- }
- break;
- case Button2:
- if (width > 0)
- x = ((double) report.xbutton.x - BUTTON_SIZE) / ((double) width);
- else x = 0.0;
- val = low + x * (high - low);
- val = max(low, min(val, high));
- DialogScrollItemValue(item, TRUE, val);
- XGrabPointer(dpy, win, TRUE, ButtonMotionMask,
- GrabModeAsync, GrabModeAsync, win,
- DoubleArrowCursor, CurrentTime);
- while (! done) {
- XNextEvent(dpy, &report);
- switch (report.type) {
- case ButtonRelease:
- done = TRUE;
- break;
- case MotionNotify:
- x = ((double) report.xmotion.x - BUTTON_SIZE) / ((double) width);
- val = low + x * (high - low);
- val = max(low, min(val, high));
- DialogScrollItemValue(item, TRUE, val);
- break;
- default:
- break;
- }
- }
- XUngrabPointer(dpy, CurrentTime);
- send_message(item, sk_do_action);
- XSync(dpy, FALSE);
- break;
- }
-
- XDefineCursor(dpy, win, DoubleArrowCursor);
- }
-
- static LVAL slider_handler(report, modal)
- XEvent report;
- int modal;
- {
- Display *dpy = StX11Display();
- Window win;
- LVAL item;
- LVAL result = NIL;
-
- win = report.xany.window;
- item = StX11ItemObject(dpy, win);
- if (item != NIL) {
- switch (report.type) {
- case Expose:
- break;
- case ButtonPress:
- track_thumb(dpy, win, report, item);
- /*
- if (! modal) {
- send_message(item, sk_do_action);
- XSync(dpy, FALSE);
- }
- */
- /* send_message(item, sk_do_action);*/
- XSync(dpy, FALSE);
- break;
- case ButtonRelease:
- break;
- default:
- break;
- }
- }
- return(result);
- }
-
- static LVAL button_handler(report, is_right)
- XEvent report;
- int is_right;
- {
- Display *dpy = StX11Display();
- Window win;
- LVAL item;
- LVAL result = NIL;
- int low, high, val, done, old_val;
-
- win = report.xany.window;
- item = StX11ItemObject(dpy, win);
- if (item != NIL) {
- switch (report.type) {
- case ButtonPress:
- done = FALSE;
- low = getfixnum(slot_value(item, s_min_value));
- high = getfixnum(slot_value(item, s_max_value));
- old_val = low - 1; /* an "impossible" value */
- while (! done) {
- if (XCheckTypedEvent(dpy, ButtonRelease, &report)) done = TRUE;
- else {
- val = getfixnum(slot_value(item, s_value));
- if (is_right) val++;
- else val--;
- val = max(low, min(val, high));
- DialogScrollItemValue(item, TRUE, val);
- if (val != old_val) send_message(item, sk_scroll_action);
- old_val = val;
- XSync(dpy, FALSE);
- }
- }
- /* send_message(item, sk_do_action); */
- break;
- default:
- break;
- }
- }
- return(result);
- }
-
- static LVAL left_button_handler(report, modal)
- XEvent report;
- int modal;
- {
- return(button_handler(report, FALSE));
- }
-
- static LVAL right_button_handler(report, modal)
- XEvent report;
- int modal;
- {
- return(button_handler(report, TRUE));
- }
-
- InstallScrollItem(win, item)
- Window win;
- LVAL item;
- {
- Display *dpy = StX11Display();
- Point loc, size;
- Window slider, button1, button2, thumb;
- LVAL s_window_id = xlenter("WINDOW-ID");
-
- check_value(item);
- loc = ListToPoint(slot_value(item, s_location));
- size = ListToPoint(slot_value(item, s_size));
- size.v = BUTTON_SIZE;
- slider = XCreateSimpleWindow(dpy, win, loc.h, loc.v, size.h, size.v,
- dialog_border_width,
- DialogBorderColor, DialogC.back);
- XSelectInput(dpy, slider,
- ExposureMask | ButtonPressMask | ButtonReleaseMask);
- XDefineCursor(dpy, slider, DoubleArrowCursor);
-
- button1 = XCreateSimpleWindow(dpy, slider,
- -dialog_border_width, -dialog_border_width,
- BUTTON_SIZE, BUTTON_SIZE,
- dialog_border_width,
- DialogBorderColor, DialogC.back);
- XSelectInput(dpy, button1,
- ExposureMask | ButtonPressMask | ButtonReleaseMask);
- XSetWindowBackgroundPixmap(dpy, button1, LeftSliderPM);
- #ifdef DODO
- XDefineCursor(dpy, button1, LeftArrowCursor);
- #endif DODO
- XDefineCursor(dpy, button1, ArrowCursor);
-
- button2 = XCreateSimpleWindow(dpy, slider,
- size.h - BUTTON_SIZE, -dialog_border_width,
- BUTTON_SIZE, BUTTON_SIZE,
- dialog_border_width,
- DialogBorderColor, DialogC.back);
- XSelectInput(dpy, button2,
- ExposureMask | ButtonPressMask | ButtonReleaseMask);
- XSetWindowBackgroundPixmap(dpy, button2, RightSliderPM);
- #ifdef DODO
- XDefineCursor(dpy, button2, RightArrowCursor);
- #endif DODO
- XDefineCursor(dpy, button2, ArrowCursor);
-
- thumb = XCreateSimpleWindow(dpy, slider, BUTTON_SIZE, 0,
- THUMB_WIDTH, BUTTON_SIZE,
- 0, DialogBorderColor, DialogC.fore);
-
- set_slot_value(item, s_window_id, cvfixnum((FIXTYPE) slider));
-
- install_dialog_item_handler(dpy, slider, slider_handler, item);
- if (XSaveContext(dpy, slider, ObjectContext, (XContext) item) != 0)
- xlfail("could not install object in window");
- if (XSaveContext(dpy, slider, ThumbContext, (XContext) thumb) != 0)
- xlfail("could not install thumb in slider");
-
- if (XSaveContext(dpy, slider, Button1Context, (XContext) button1) != 0)
- xlfail("could not install left button in slider");
- install_dialog_item_handler(dpy, button1, left_button_handler, item);
- if (XSaveContext(dpy, button1, ObjectContext, (XContext) item) != 0)
- xlfail("could not install object in window");
-
- if (XSaveContext(dpy, slider, Button2Context, (XContext) button2) != 0)
- xlfail("could not install right button in slider");
- install_dialog_item_handler(dpy, button2, right_button_handler, item);
- if (XSaveContext(dpy, button2, ObjectContext, (XContext) item) != 0)
- xlfail("could not install object in window");
-
- adjust_slider(item);
-
- XMapSubwindows(dpy, slider);
- }
-
- DeleteScrollItem(win, item)
- Window win;
- LVAL item;
- {
- Display *dpy = StX11Display();
- Window slider, button1, button2;
- LVAL s_window_id = xlenter("WINDOW-ID");
-
- slider = (Window) getfixnum(slot_value(item, s_window_id));
-
- delete_dialog_item_handler(dpy, slider);
- if (XDeleteContext(dpy, slider, ObjectContext) != 0)
- xlfail("cound not delete object context");
- if (XDeleteContext(dpy, slider, ThumbContext) != 0)
- xlfail("cound not delete thumb context");
-
- if (XFindContext(dpy, slider, Button1Context, &button1) != 0)
- xlfail("can't find left button context");
- if (XDeleteContext(dpy, slider, Button1Context) != 0)
- xlfail("cound not delete left button context");
- delete_dialog_item_handler(dpy, button1);
- if (XDeleteContext(dpy, button1, ObjectContext) != 0)
- xlfail("cound not delete object context");
-
- if (XFindContext(dpy, slider, Button2Context, &button2) != 0)
- xlfail("can't find right button context");
- if (XDeleteContext(dpy, slider, Button2Context) != 0)
- xlfail("cound not delete right button context");
- delete_dialog_item_handler(dpy, button2);
- if (XDeleteContext(dpy, button2, ObjectContext) != 0)
- xlfail("cound not delete object context");
-
- set_slot_value(item, s_window_id, NIL);
- }
-
- DialogScrollGetDefaultSize(item, width, height)
- LVAL item;
- int *width, *height;
- {
- if (width != nil) *width = MIN_SLIDER_WIDTH;
- if (height != nil) *height = MIN_SLIDER_HEIGHT;
- }
-
- LVAL DialogScrollItemValue(item, set, value)
- LVAL item;
- int set, value;
- {
- if (set) {
- set_slot_value(item, s_value, cvfixnum((FIXTYPE) value));
- check_value(item);
- adjust_slider(item);
- }
- else check_value(item);
-
- return(slot_value(item, s_value));
- }
-
- LVAL DialogScrollItemMin(item, set, value)
- LVAL item;
- int set, value;
- {
- if (set) {
- set_slot_value(item, s_min_value, cvfixnum((FIXTYPE) value));
- check_value(item);
- adjust_slider(item);
- }
- return(slot_value(item, s_min_value));
- }
-
- LVAL DialogScrollItemMax(item, set, value)
- LVAL item;
- int set, value;
- {
- if (set) {
- set_slot_value(item, s_max_value, cvfixnum((FIXTYPE) value));
- check_value(item);
- adjust_slider(item);
- }
- return(slot_value(item, s_max_value));
- }
-
- static check_value(item)
- LVAL item;
- {
- LVAL low, high, value;
- int ilow, ihigh, ivalue;
-
- low = slot_value(item, s_min_value);
- high = slot_value(item, s_max_value);
- value = slot_value(item, s_value);
-
- ilow = (fixp(low)) ? getfixnum(low): 0;
- ihigh = (fixp(high)) ? getfixnum(high) : 100;
- ivalue = (fixp(value)) ? getfixnum(value) : ilow;
-
- if (ilow >= ihigh) ihigh = ilow + 1;
- ivalue = max(ilow, min(ihigh, ivalue));
-
- if (! fixp(low) || ilow != getfixnum(low))
- set_slot_value(item, s_min_value, cvfixnum((FIXTYPE) ilow));
- if (! fixp(high) || ihigh != getfixnum(high))
- set_slot_value(item, s_max_value, cvfixnum((FIXTYPE) ihigh));
- if (! fixp(value) || ivalue != getfixnum(value))
- set_slot_value(item, s_value, cvfixnum((FIXTYPE) ivalue));
- }
-