/***************************************************************************/
/***************************************************************************/
/* */
/* (c) 1995-1999. The Regents of the University of California. All */
/* rights reserved. */
/* */
/* This work was produced at the University of California, Lawrence */
/* Livermore National Laboratory (UC LLNL) under contract no. */
/* W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy */
/* (DOE) and The Regents of the University of California (University) */
/* for the operation of UC LLNL. Copyright is reserved to the */
/* University for purposes of controlled dissemination, */
/* commercialization through formal licensing, or other disposition */
/* under terms of Contract 48; DOE policies, regulations and orders; */
/* and U.S. statutes. The rights of the Federal Government are */
/* reserved under Contract 48 subject to the restrictions agreed upon */
/* by the DOE and University. */
/* */
/* */
/* DISCLAIMER */
/* */
/* This software was prepared as an account of work sponsored by an */
/* agency of the United States Government. Neither the United States */
/* Government nor the University of California nor any of their */
/* employees, makes any warranty, express or implied, or assumes any */
/* liability or responsibility for the accuracy, completeness, or */
/* usefulness of any information, apparatus, product, or process */
/* disclosed, or represents that its specific commercial products, */
/* process, or service by trade name, trademark, manufacturer, or */
/* otherwise, does not necessarily constitute or imply its */
/* endorsement, recommendation, or favoring by the United States */
/* Government or the University of California. The views and opinions */
/* of the authors expressed herein do not necessarily state or reflect */
/* those of the United States Government or the University of */
/* California, and shall not be used for advertising or product */
/* endorsement purposes. */
/* */
/* Permission to use, copy, modify and distribute this software and its */
/* documentation for any non-commercial purpose, without fee, is */
/* hereby granted, provided that the above copyright notice and this */
/* permission notice appear in all copies of the software and */
/* supporting documentation, and that all UC LLNL identification in */
/* the user interface remain unchanged. The title to copyright LLNL */
/* XDIR shall at all times remain with The Regents of the University */
/* of California and users agree to preserve same. Users seeking the */
/* right to make derivative works with LLNL XDIR for commercial */
/* purposes may obtain a license from the Lawrence Livermore National */
/* Laboratory's Technology Transfer Office, P.O. Box 808, L-795, */
/* Livermore, CA 94550. */
/* */
/***************************************************************************/
/***************************************************************************/
#include <sys/param.h>
#include <Xm/Xm.h>
#include "xdir.h"
#define HPAGEINCREMENT 4
extern Display *display;
extern GC gcv1;
extern int safe_to_redraw;
void scroll_vertical();
void scroll_horizontal();
void
cb_scroll_vertical(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)call_data;
/* Make sure that the data structures are consistent */
if (!safe_to_redraw)
return;
scroll_vertical(dirwin, cbs->value);
}
void
scroll_down(dirwin)
struct dirwin_st *dirwin;
{
Widget w_vertical_sb;
int value;
XtVaGetValues(dirwin->w_scrolledWindow, XmNverticalScrollBar,
&w_vertical_sb, NULL);
XtVaGetValues(w_vertical_sb, XmNvalue, &value, NULL);
scroll_vertical(dirwin, value+1);
}
void
scroll_up(dirwin)
struct dirwin_st *dirwin;
{
Widget w_vertical_sb;
int value;
XtVaGetValues(dirwin->w_scrolledWindow, XmNverticalScrollBar,
&w_vertical_sb, NULL);
XtVaGetValues(w_vertical_sb, XmNvalue, &value, NULL);
scroll_vertical(dirwin, value-1);
}
void
scroll_vertical(dirwin, value)
struct dirwin_st *dirwin;
int value;
{
Dimension drawing_area_width;
int width;
int height;
int x;
int y;
int offset;
int src_x;
int src_y;
int dest_x;
int dest_y;
int minimum;
int maximum;
int slider_size;
Widget w_vertical_sb;
/* If no change, or value out of range, nothing to do */
XtVaGetValues(dirwin->w_scrolledWindow, XmNverticalScrollBar,
&w_vertical_sb, NULL);
XtVaGetValues(w_vertical_sb,
XmNminimum, &minimum,
XmNmaximum, &maximum,
XmNsliderSize, &slider_size,
NULL
);
if (value == dirwin->first_visible_row || value < minimum
|| value > maximum-slider_size)
return;
XtVaSetValues(w_vertical_sb, XmNvalue, value, NULL);
/* If no overlap, redraw entire window */
if (value >= dirwin->first_visible_row+dirwin->nrows_visible ||
value+dirwin->nrows_visible <= dirwin->first_visible_row) {
dirwin->first_visible_row = value;
redraw_entire_dir(dirwin);
return;
}
/* There is overlap. Block copy overlap. Explicitly redraw rest */
XtVaGetValues(dirwin->w_drawingArea, XmNwidth, &drawing_area_width, NULL);
if (value > dirwin->first_visible_row) {
offset = value-dirwin->first_visible_row;
src_x = 0;
src_y = VTMARGIN+offset*(dirwin->entry_height+VSPACING);
dest_x = 0;
dest_y = VTMARGIN;
width = drawing_area_width;
height = (dirwin->nrows_visible-offset)
*(dirwin->entry_height+VSPACING)-VSPACING;
XSync(display, 0);
XCopyArea(display, XtWindow(dirwin->w_drawingArea),
XtWindow(dirwin->w_drawingArea), gcv1, src_x, src_y, width, height,
dest_x, dest_y);
dirwin->first_visible_row = value;
x = virtual_x(dirwin, 0);
y = virtual_y(dirwin, VTMARGIN+(dirwin->nrows_visible-offset)
*(dirwin->entry_height+VSPACING));
width = drawing_area_width;
height = offset*(dirwin->entry_height+VSPACING)-VSPACING;
redraw_dir(dirwin, x, y, width, height, True, NULL, 0);
} else {
offset = dirwin->first_visible_row-value;
src_x = 0;
src_y = VTMARGIN;
dest_x = 0;
dest_y = VTMARGIN+offset*(dirwin->entry_height+VSPACING);
width = drawing_area_width;
height = (dirwin->nrows_visible-offset)
*(dirwin->entry_height+VSPACING)-VSPACING;
XSync(display, 0);
XCopyArea(display, XtWindow(dirwin->w_drawingArea),
XtWindow(dirwin->w_drawingArea), gcv1, src_x, src_y, width, height,
dest_x, dest_y);
dirwin->first_visible_row = value;
x = virtual_x(dirwin, 0);
y = virtual_y(dirwin, 0);
width = drawing_area_width;
height = VTMARGIN+offset*(dirwin->entry_height+VSPACING);
redraw_dir(dirwin, x, y, width, height, True, NULL, 0);
}
}
void
cb_scroll_horizontal(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
XmScrollBarCallbackStruct *cbs = (XmScrollBarCallbackStruct *)call_data;
/* Make sure that the data structures are consistent */
if (!safe_to_redraw)
return;
scroll_horizontal(dirwin, cbs->value);
}
void
scroll_right(dirwin)
struct dirwin_st *dirwin;
{
Widget w_horizontal_sb;
int value;
XtVaGetValues(dirwin->w_scrolledWindow, XmNhorizontalScrollBar,
&w_horizontal_sb, NULL);
XtVaGetValues(w_horizontal_sb, XmNvalue, &value, NULL);
scroll_horizontal(dirwin, value+1);
}
void
scroll_left(dirwin)
struct dirwin_st *dirwin;
{
Widget w_horizontal_sb;
int value;
XtVaGetValues(dirwin->w_scrolledWindow, XmNhorizontalScrollBar,
&w_horizontal_sb, NULL);
XtVaGetValues(w_horizontal_sb, XmNvalue, &value, NULL);
scroll_horizontal(dirwin, value-1);
}
void
scroll_horizontal(dirwin, value)
struct dirwin_st *dirwin;
int value;
{
Dimension drawing_area_width;
Dimension drawing_area_height;
int width;
int height;
int x;
int y;
int offset;
int src_x;
int src_y;
int dest_x;
int dest_y;
XRectangle rect;
int minimum;
int maximum;
int slider_size;
Widget w_horizontal_sb;
/* If no change, or value out of range, nothing to do */
XtVaGetValues(dirwin->w_scrolledWindow, XmNhorizontalScrollBar,
&w_horizontal_sb, NULL);
XtVaGetValues(w_horizontal_sb,
XmNminimum, &minimum,
XmNmaximum, &maximum,
XmNsliderSize, &slider_size,
NULL
);
if (value == dirwin->first_visible_hincrement || value < minimum
|| value > maximum-slider_size)
return;
XtVaSetValues(w_horizontal_sb, XmNvalue, value, NULL);
/* Get drawing area dimensions */
XtVaGetValues(dirwin->w_drawingArea,
XmNwidth, &drawing_area_width,
XmNheight, &drawing_area_height,
NULL
);
/* If no overlap, redraw entire window */
if (value >= dirwin->first_visible_hincrement
+dirwin->nhincrements_visible ||
dirwin->nhincrements_visible < dirwin->first_visible_hincrement) {
redraw_entire_dir(dirwin);
dirwin->first_visible_hincrement = value;
goto clear_margins;
}
/* There is overlap. Block copy overlap. Explicitly redraw rest */
if (value > dirwin->first_visible_hincrement) {
offset = value-dirwin->first_visible_hincrement;
src_x = offset*HINCREMENT;
src_y = 0;
dest_x = 0;
dest_y = 0;
width = drawing_area_width-src_x;
height = drawing_area_height;
XSync(display, 0);
XCopyArea(display, XtWindow(dirwin->w_drawingArea),
XtWindow(dirwin->w_drawingArea), gcv1, src_x, src_y, width, height,
dest_x, dest_y);
rect.x = width;
rect.y = 0;
rect.width = src_x;
rect.height = drawing_area_height;
x = virtual_x(dirwin, width);
y = virtual_y(dirwin, 0);
width = src_x;
height = drawing_area_height;
redraw_dir(dirwin, x, y, width, height, True, &rect, 1);
} else {
offset = dirwin->first_visible_hincrement-value;
src_x = 0;
src_y = 0;
dest_x = offset*HINCREMENT;
dest_y = 0;
width = drawing_area_width-dest_x;
height = drawing_area_height;
XSync(display, 0);
XCopyArea(display, XtWindow(dirwin->w_drawingArea),
XtWindow(dirwin->w_drawingArea), gcv1, src_x, src_y, width, height,
dest_x, dest_y);
rect.x = 0;
rect.y = 0;
rect.width = dest_x;
rect.height = drawing_area_height;
x = virtual_x(dirwin, 0);
y = virtual_y(dirwin, 0);
width = dest_x;
height = drawing_area_height;
redraw_dir(dirwin, x, y, width, height, True, &rect, 1);
}
dirwin->first_visible_hincrement = value;
clear_margins:
/* Clear left margin */
if (value*HINCREMENT < HMARGIN) {
x = 0;
y = 0;
width = HMARGIN-value*HINCREMENT;
height = drawing_area_height;
XClearArea(display, XtWindow(dirwin->w_drawingArea), x, y, width,
height, False);
}
/* Clear right margin */
if (dirwin->virtual_width-value*HINCREMENT-HMARGIN
< (int)drawing_area_width) {
x = dirwin->virtual_width-value*HINCREMENT-HMARGIN;
y = 0;
width = drawing_area_width-x;
height = drawing_area_height;
XClearArea(display, XtWindow(dirwin->w_drawingArea), x, y, width,
height, False);
}
}
/*
* reset_scrollbars - Set the display's scrollbars to values appropriate
* to its contents. Set vertical scrollbar value to
* "vert_value". Set to -1 to retain current value.
* Set horizontal scrollbar value to "horiz_value".
* Set to -1 to retain current value.
*/
void
reset_scrollbars(dirwin, horiz_value, vert_value)
struct dirwin_st *dirwin;
int horiz_value;
int vert_value;
{
Widget w_vertical_sb;
Widget w_horizontal_sb;
int value;
int slider_size;
int nhincrements;
int nhincrements_visible;
Dimension drawing_area_width;
XtVaGetValues(dirwin->w_scrolledWindow,
XmNhorizontalScrollBar, &w_horizontal_sb,
XmNverticalScrollBar, &w_vertical_sb,
NULL
);
/* Adjust vertical scrollbar parameters */
if (XtIsManaged(w_vertical_sb)) {
if (vert_value == -1)
XtVaGetValues(w_vertical_sb, XmNvalue, &value, NULL);
else
value = vert_value;
if ((dirwin->nrows < value+dirwin->nrows_visible-1) && value)
value = MAX(0, dirwin->nrows-dirwin->nrows_visible);
slider_size = MIN(dirwin->nrows_visible, dirwin->nrows);
XtVaSetValues(w_vertical_sb,
XmNmaximum, MAX(dirwin->nrows, 1),
XmNsliderSize, MAX(slider_size, 1),
XmNpageIncrement, MAX(dirwin->nrows_visible-1, 1),
XmNvalue, MIN(value, dirwin->nrows-slider_size),
NULL
);
XtVaGetValues(w_vertical_sb, XmNvalue, &dirwin->first_visible_row,
NULL);
} else
dirwin->first_visible_row = 0;
/* Adjust horizontal scrollbar parameters */
if (XtIsManaged(w_horizontal_sb)) {
if (horiz_value == -1)
XtVaGetValues(w_horizontal_sb, XmNvalue, &value, NULL);
else
value = horiz_value;
nhincrements = (dirwin->virtual_width+HINCREMENT-1)/HINCREMENT;
XtVaGetValues(dirwin->w_drawingArea, XmNwidth, &drawing_area_width,
NULL);
nhincrements_visible =(int)(drawing_area_width+HINCREMENT-1)/HINCREMENT;
slider_size = MIN(nhincrements_visible, nhincrements);
XtVaSetValues(w_horizontal_sb,
XmNmaximum, MAX(nhincrements, 1),
XmNsliderSize, MAX(slider_size, 1),
XmNpageIncrement, MAX(HPAGEINCREMENT, 1),
XmNvalue, MIN(value, nhincrements-slider_size),
NULL
);
XtVaGetValues(w_horizontal_sb, XmNvalue,
&dirwin->first_visible_hincrement, NULL);
dirwin->nhincrements = nhincrements;
dirwin->nhincrements_visible = nhincrements_visible;
} else
dirwin->first_visible_hincrement = 0;
}
void
scroll_entry_into_view(einfo)
struct entry_info *einfo;
{
struct dirwin_st *dirwin = einfo->dirwin;
int row = einfo->indx%dirwin->nrows;
int value;
int x;
int col;
int left_da_x;
int right_da_x;
Dimension drawing_area_width;
int width;
/* Scroll vertically, if necessary */
if (row < dirwin->first_visible_row)
scroll_vertical(dirwin, row);
else if (row >= dirwin->first_visible_row+dirwin->nrows_visible)
scroll_vertical(dirwin, row-dirwin->nrows_visible+1);
/* Scroll horizontally, if necessary */
switch (dirwin->layout) {
case TABULAR:
case ICONIC:
col = einfo->indx/dirwin->nrows;
x = HMARGIN+col*(dirwin->max_entry_width+HSPACING);
width = einfo->width;
break;
case TREE:
x = HMARGIN+einfo->level*INDENT;
width = CWIDTH+CMARGIN+einfo->width;
break;
case FULL_INFO:
x = HMARGIN;
width = einfo->width;
break;
}
XtVaGetValues(dirwin->w_drawingArea, XmNwidth, &drawing_area_width, NULL);
left_da_x = virtual_x(dirwin, 0);
right_da_x = left_da_x+drawing_area_width;
if (x < left_da_x) {
if (dirwin->layout == TREE && einfo->level != 0)
value = (x-HMARGIN)/HINCREMENT;
else
value = 0;
scroll_horizontal(dirwin, value);
} else if (x+width > right_da_x) {
if (dirwin->layout == TREE && einfo->level != 0)
value = MAX(x, right_da_x-width-HMARGIN)/HINCREMENT;
else
value = 0;
scroll_horizontal(dirwin, value);
}
}
syntax highlighted by Code2HTML, v. 0.9.1