/***************************************************************************/
/***************************************************************************/
/* */
/* (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 <Xm/Xm.h>
#include <limits.h>
#include <sys/param.h>
#include "xdir.h"
static XRectangle *orig_outlines;
static XRectangle *outlines;
static int num_outlines;
static int outlines_drawn;
static int orig_move_x;
static int orig_move_y;
static Window main_input_window;
static int x_leftmost_range;
static int x_rightmost_range;
static int y_topmost_range;
static int y_bottommost_range;
extern Display *display;
extern Window root_window;
extern GC gc_move;
extern struct dirwin_st *dirwin_head;
extern Widget w_toplev;
void create_invisible_windows();
void destroy_invisible_windows();
void
hilite_entry(einfo)
struct entry_info *einfo;
{
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
einfo->state = SELECTED;
draw_entry(einfo);
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
}
void
unhilite_entry(einfo)
struct entry_info *einfo;
{
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
einfo->state = UNSELECTED;
draw_entry(einfo);
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
}
void
init_outlines(dirwin, x, y)
struct dirwin_st *dirwin;
int x;
int y;
{
int start_row;
int end_row;
int start_col;
int end_col;
int col;
int row;
int nrows;
int indx;
Dimension drawing_area_width;
Dimension drawing_area_height;
Position drawing_area_x;
Position drawing_area_y;
int x_offset_virtual_to_global;
int y_offset_virtual_to_global;
int x_root;
int y_root;
Window child;
int min_x = INT_MAX;
int max_x = 0;
int min_y = INT_MAX;
int max_y = 0;
Window rr;
int xr;
int yr;
unsigned int wr;
unsigned int hr;
unsigned int bwr;
unsigned int dr;
int i;
/* Calculate offsets for virtual to global coordinate translations */
XTranslateCoordinates(display, XtWindow(dirwin->w_drawingArea),
root_window, 0, 0, &x_root, &y_root, &child);
x_offset_virtual_to_global = actual_x(dirwin, 0)+x_root;
y_offset_virtual_to_global = actual_y(dirwin, 0)+y_root;
/* Remember original cursor global coordinates */
orig_move_x = x+x_offset_virtual_to_global;
orig_move_y = y+y_offset_virtual_to_global;
/* Get drawing area geometry */
XtVaGetValues(dirwin->w_drawingArea,
XmNwidth, &drawing_area_width,
XmNheight, &drawing_area_height,
XmNx, &drawing_area_x,
XmNy, &drawing_area_y,
NULL
);
/* Create rectangles to be used to draw outlines of entries being moved */
outlines_drawn = False;
num_outlines = 0;
start_row = dirwin->first_visible_row;
end_row = start_row+dirwin->nrows_visible-1;
end_row = MIN(end_row, dirwin->nrows-1);
nrows = dirwin->nrows;
switch (dirwin->layout) {
case TABULAR:
case ICONIC:
start_col = virtual_x(dirwin, 0)
/(dirwin->max_entry_width+HSPACING);
start_col = MAX(start_col, 0);
end_col = virtual_x(dirwin, drawing_area_width)
/(dirwin->max_entry_width+HSPACING);
end_col = MIN(end_col, dirwin->ncols-1);
orig_outlines =
(XRectangle *)XtMalloc((end_col-start_col+1)*(end_row-start_row+1)
*sizeof(XRectangle));
for (col=start_col; col<=end_col; col++)
for (row=start_row; row<=end_row; row++) {
indx = col*nrows+row;
if (indx >= dirwin->nentries)
break;
if (dirwin->entries[indx].state == SELECTED) {
orig_outlines[num_outlines].x = HMARGIN
+col*(dirwin->max_entry_width+HSPACING);
orig_outlines[num_outlines].y =
row*(dirwin->entry_height+VSPACING);
orig_outlines[num_outlines].width =
dirwin->entries[indx].width;
orig_outlines[num_outlines].height =
dirwin->entry_height;
num_outlines++;
}
}
break;
case TREE:
orig_outlines = (XRectangle *)XtMalloc((end_row-start_row+1)
*sizeof(XRectangle));
for (row=start_row; row<=end_row; row++) {
if (dirwin->entries[row].state == SELECTED) {
orig_outlines[num_outlines].x =
dirwin->entries[row].level*INDENT+HMARGIN+CWIDTH+CMARGIN;
orig_outlines[num_outlines].y =
row*(dirwin->entry_height+VSPACING);
orig_outlines[num_outlines].width = dirwin->entries[row].width;
orig_outlines[num_outlines].height = dirwin->entry_height;
num_outlines++;
}
}
break;
case FULL_INFO:
orig_outlines =
(XRectangle *)XtMalloc((end_row-start_row+1)*sizeof(XRectangle));
for (row=start_row; row<=end_row; row++)
if (dirwin->entries[row].state == SELECTED) {
orig_outlines[num_outlines].x = HMARGIN;
orig_outlines[num_outlines].y =
row*(dirwin->entry_height+VSPACING);
orig_outlines[num_outlines].width =
dirwin->entries[row].width;
orig_outlines[num_outlines].height =
dirwin->entry_height;
num_outlines++;
}
break;
}
outlines = (XRectangle *)XtMalloc(num_outlines*sizeof(XRectangle));
bcopy(orig_outlines, outlines, num_outlines*sizeof(XRectangle));
/* Install event handlers on Xdir's widgets that absorb motion events */
create_invisible_windows();
/* Convert rectangles from virtual to global coordinated */
for (i=0; i<num_outlines; i++) {
orig_outlines[i].x += x_offset_virtual_to_global;
orig_outlines[i].y += y_offset_virtual_to_global;
}
/* Determine bounds for moving outlines */
for (i=0; i<num_outlines; i++) {
min_x = MIN(min_x, orig_outlines[i].x);
max_x = MAX(max_x, (int)(orig_outlines[i].x+orig_outlines[i].width));
min_y = MIN(min_y, orig_outlines[i].y);
max_y = MAX(max_y, (int)(orig_outlines[i].y+orig_outlines[i].height));
}
XGetGeometry(display, root_window, &rr, &xr, &yr, &wr, &hr, &bwr, &dr);
x_leftmost_range = orig_move_x-min_x;
x_rightmost_range = wr-(max_x-orig_move_x)-1;
y_topmost_range = orig_move_y-min_y;
y_bottommost_range = hr-(max_y-orig_move_y)-1;
}
void
move_outlines(widget, x, y)
Widget widget;
int x;
int y;
{
int i;
int x_offset;
int y_offset;
int x_global;
int y_global;
Window child;
/* Erase previous outlines */
if (outlines_drawn)
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
/* Adjust coordinates of outline rectangles */
XTranslateCoordinates(display, XtWindow(widget), root_window, x, y,
&x_global, &y_global, &child);
if (x_global <= x_leftmost_range)
x_global = x_leftmost_range;
else if (x_global >= x_rightmost_range)
x_global = x_rightmost_range;
x_offset = x_global-orig_move_x;
if (y_global <= y_topmost_range)
y_global = y_topmost_range;
else if (y_global >= y_bottommost_range)
y_global = y_bottommost_range;
y_offset = y_global-orig_move_y;
for (i=0; i<num_outlines; i++) {
outlines[i].x = orig_outlines[i].x+x_offset;
outlines[i].y = orig_outlines[i].y+y_offset;
}
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
outlines_drawn = True;
}
void
remove_move_outlines()
{
/* Erase previous outlines */
if (outlines_drawn)
XDrawRectangles(display, XDefaultRootWindow(display), gc_move,
outlines, num_outlines);
/* Free up memory */
XtFree((char *)outlines);
XtFree((char *)orig_outlines);
/* Remove event handlers on Xdir's widgets that absorb motion events */
destroy_invisible_windows();
}
/*
* create_invisible_windows - Creates invisible input-only windows to
* overlay the non-drawingArea portions of
* the application. This is done so that
* none of the application's widgets will
* get the motion events intended for
* moving the outlines of selected entries.
*/
void
create_invisible_windows()
{
struct dirwin_st *dirwin;
Dimension w1;
Dimension h1;
int x2;
int y2;
Dimension w2;
Dimension h2;
XSetWindowAttributes xswa;
unsigned long valuemask;
Window child;
Window shell_window;
/* Specify the window attributes */
xswa.override_redirect = True;
valuemask = CWOverrideRedirect;
/* Overlay input windows over non-drawingArea parts of directory displays */
dirwin = dirwin_head;
while(dirwin) {
XtVaGetValues(dirwin->w_form,
XmNwidth, &w1,
XmNheight, &h1,
NULL
);
XtVaGetValues(dirwin->w_drawingArea,
XmNwidth, &w2,
XmNheight, &h2,
NULL
);
shell_window = XtWindow(XtParent(dirwin->w_form));
XTranslateCoordinates(display, XtWindow(dirwin->w_drawingArea),
shell_window, 0, 0, &x2, &y2, &child);
dirwin->input_windows[0] = XCreateWindow(display, shell_window,
0, 0, (int)w1, y2,
0, 0, InputOnly, CopyFromParent, valuemask, &xswa);
XMapWindow(display, dirwin->input_windows[0]);
dirwin->input_windows[1] = XCreateWindow(display, shell_window,
(int)(x2+w2), y2, (int)(w1-(x2+w2)), (int)h2,
0, 0, InputOnly, CopyFromParent, valuemask, &xswa);
XMapWindow(display, dirwin->input_windows[1]);
dirwin->input_windows[2] = XCreateWindow(display, shell_window,
0, (int)(y2+h2), w1, (int)(h1-(y2+h2)),
0, 0, InputOnly, CopyFromParent, valuemask, &xswa);
XMapWindow(display, dirwin->input_windows[2]);
dirwin->input_windows[3] = XCreateWindow(display, shell_window,
0, y2, x2, (int)h2,
0, 0, InputOnly, CopyFromParent, valuemask, &xswa);
XMapWindow(display, dirwin->input_windows[3]);
dirwin = dirwin->next;
}
/* Overlay invisible window over main window to deflect input events */
XtVaGetValues(w_toplev,
XmNwidth, &w1,
XmNheight, &h1,
NULL
);
main_input_window = XCreateWindow(display, XtWindow(w_toplev), 0, 0,
(int)w1, (int)h1, 0, 0, InputOnly, CopyFromParent,
valuemask, &xswa);
XMapWindow(display, main_input_window);
/*************** How about help, preferences, and about windows? ********/
}
/*
* destroy_invisible_windows - Destroys the invisible windows that overlay
* the non-drawingArea portions of the
* application.
*/
void
destroy_invisible_windows()
{
struct dirwin_st *dirwin;
int i;
/* Destroy invisible windows overlaying portions of directory displays */
dirwin = dirwin_head;
while(dirwin) {
for (i=0; i<4; i++)
XDestroyWindow(display, dirwin->input_windows[i]);
dirwin = dirwin->next;
}
/* Destroy invisible window overlaying main window */
XDestroyWindow(display, main_input_window);
}
syntax highlighted by Code2HTML, v. 0.9.1