/usr/share/doc/xviewg/examples/scrollbar/scroll_cells.c is in xview-examples 3.2p1.4-28.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | /*
* scroll_cells.c -- scroll a bitmap of cells around in a canvas.
* The cells are rectangular areas labeled with numbers which may
* represent arbitrary data such as icon images. The cell sizes are
* defined to be 64 by 64 aligned in rows and columns. This example
* is used to demonstrate how to configure scrollbars to accommodate
* arbitrary data within a window.
*/
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h> /* Using Xlib graphics */
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/scrollbar.h>
#include <xview/font.h>
#include <xview/xv_xrect.h>
#define CELL_WIDTH 64
#define CELL_HEIGHT 64
#define CELLS_PER_HOR_PAGE 5 /* when paging w/scrollbar */
#define CELLS_PER_VER_PAGE 5 /* when paging w/scrollbar */
#define CELLS_PER_ROW 8
#define CELLS_PER_COL 16
Pixmap cell_map; /* pixmap copied onto canvas window */
Scrollbar horiz_scrollbar;
Scrollbar vert_scrollbar;
GC gc; /* General usage GC */
main(argc, argv)
int argc;
char *argv[];
{
Frame frame;
Canvas canvas;
void repaint_proc();
/* Initialize, create frame and canvas... */
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(XV_NULL, FRAME,
FRAME_LABEL, argv[0],
FRAME_SHOW_FOOTER, TRUE,
NULL);
canvas = (Canvas)xv_create(frame, CANVAS,
/* make subwindow the size of a "page" */
XV_WIDTH, CELL_WIDTH * CELLS_PER_HOR_PAGE,
XV_HEIGHT, CELL_HEIGHT * CELLS_PER_VER_PAGE,
/* canvas is much larger than the window */
CANVAS_WIDTH, CELL_WIDTH * CELLS_PER_ROW + 1,
CANVAS_HEIGHT, CELL_HEIGHT * CELLS_PER_COL + 1,
CANVAS_AUTO_EXPAND, FALSE,
CANVAS_AUTO_SHRINK, FALSE,
/* don't retain window -- we'll need
* to repaint it all the time */
CANVAS_RETAINED, FALSE,
/* we're using Xlib graphics calls in repaint_proc() */
CANVAS_X_PAINT_WINDOW, TRUE,
CANVAS_REPAINT_PROC, repaint_proc,
/* we'll be repainting over exposed areas,
* so don't bother clearing */
OPENWIN_AUTO_CLEAR, FALSE,
NULL);
/*
* Create scrollbars attached to the canvas. When user clicks
* on cable, page by the page size (PAGE_LENGTH). Scrolling
* should move cell by cell, not by one pixel (PIXELS_PER_UNIT).
*/
vert_scrollbar = xv_create(canvas, SCROLLBAR,
SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
SCROLLBAR_PIXELS_PER_UNIT, CELL_HEIGHT,
SCROLLBAR_OBJECT_LENGTH, CELLS_PER_COL,
SCROLLBAR_PAGE_LENGTH, CELLS_PER_VER_PAGE,
SCROLLBAR_VIEW_LENGTH, CELLS_PER_VER_PAGE,
NULL);
horiz_scrollbar = xv_create(canvas, SCROLLBAR,
SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
SCROLLBAR_PIXELS_PER_UNIT, CELL_WIDTH,
SCROLLBAR_OBJECT_LENGTH, CELLS_PER_ROW,
SCROLLBAR_PAGE_LENGTH, CELLS_PER_HOR_PAGE,
SCROLLBAR_VIEW_LENGTH, CELLS_PER_HOR_PAGE,
NULL);
/*
* create pixmap and draw cells into it ... this is the abstraction.
* The cell_map is copied into the window via XCopyPlane in the
* repaint procedure.
*/
{
short x, y, pt = 0;
Xv_Font font;
XPoint points[256]; /* keep Xlib calls to a minimum */
XGCValues gcvalues;
Display *dpy = (Display *)xv_get(canvas, XV_DISPLAY);
font = (Xv_Font)xv_find(frame, FONT,
#ifndef __linux__
FONT_NAME, "icon",
#else
FONT_NAME, "lucidasanstypewriter-24",
#endif
NULL);
cell_map = XCreatePixmap(dpy, DefaultRootWindow(dpy),
CELLS_PER_ROW * CELL_WIDTH + 1,
CELLS_PER_COL * CELL_HEIGHT + 1,
1); /* We only need a 1-bit deep pixmap */
/* Create the gc for the cell_map -- since it is 1-bit deep,
* use 0 and 1 for fg/bg values. Also, limit number of
* events generated by setting graphics exposures to False.
*/
gcvalues.graphics_exposures = False;
gcvalues.foreground = WhitePixel(dpy,DefaultScreen(dpy));
if (font)
gcvalues.font = (Font)xv_get(font, XV_XID);
gc = XCreateGC(dpy, cell_map,
GCFont|GCForeground|GCBackground|GCGraphicsExposures,
&gcvalues);
XFillRectangle (dpy, cell_map, gc, 0, 0, CELLS_PER_ROW * CELL_WIDTH + 1,
CELLS_PER_COL * CELL_HEIGHT + 1);
XSetForeground (dpy, gc, 1L);
XSetBackground (dpy, gc, 0L);
if (!font) {
/* dot every other pixel */
for (x = 0; x <= CELL_WIDTH * CELLS_PER_ROW; x += 2)
for (y = 0; y <= CELL_HEIGHT * CELLS_PER_COL; y += 2) {
if (x % CELL_WIDTH != 0 && y % CELL_HEIGHT != 0)
continue;
points[pt].x = x, points[pt].y = y;
if (++pt == sizeof points / sizeof points[0]) {
XDrawPoints(dpy, cell_map, gc, points, pt,
CoordModeOrigin);
pt = 0;
}
}
if (pt != sizeof points) /* flush remaining points */
XDrawPoints(dpy, cell_map, gc,
points, pt, CoordModeOrigin);
}
/* Icon font not available. Instead, label each cell
* with a string describing the cell's coordinates.
*/
for (x = 0; x < CELLS_PER_ROW; x++)
for (y = 0; y < CELLS_PER_COL; y++) {
char buf[8];
if (!font) {
sprintf(buf, "%d,%d", x+1, y+1);
XDrawString(dpy, cell_map, gc,
x * CELL_WIDTH + 5, y * CELL_HEIGHT + 25,
buf, strlen(buf));
} else {
buf[0] = x + y * CELLS_PER_COL;
XDrawString(dpy, cell_map, gc,
x * CELL_WIDTH, y * CELL_HEIGHT, buf, 1);
}
}
/* we're now done with the cell_map, so free gc and create
* a new one based on the window that will use it. Otherwise,
* the GC may not work because of different depths.
*/
if (font)
xv_destroy(font);
XFreeGC(dpy, gc);
gcvalues.background = WhitePixel(dpy, DefaultScreen(dpy));
gcvalues.foreground = BlackPixel(dpy, DefaultScreen(dpy));
gcvalues.plane_mask = 1L;
gc = XCreateGC(dpy, DefaultRootWindow(dpy),
GCForeground|GCBackground|GCGraphicsExposures, &gcvalues);
}
/* shrink frame to minimal size and start notifier */
window_fit(frame);
xv_main_loop(frame);
}
/*
* The repaint procedure is called whenever repainting is needed in
* a paint window. Since the canvas is not retained, this routine
* is going to be called anytime the user scrolls the canvas. The
* canvas will handle repainting the portion of the canvas that
* was in view and has scrolled onto another viewable portion of
* the window. The xrects parameter will cover the new areas that
* were not in view before and have just scrolled into view. If
* the window resizes or if the window is exposed by other windows
* disappearing or cycling through the window tree, then the number
* of xrects will be more than one and we'll have to copy the new
* areas one by one. Clipping isn't necessary since the areas to
* be rendered are set by the xrects value.
*/
void
repaint_proc(canvas, paint_window, dpy, win, xrects)
Canvas canvas;
Xv_Window paint_window;
Display *dpy;
Window win;
Xv_xrectlist *xrects;
{
int x, y;
x = (int)xv_get(horiz_scrollbar, SCROLLBAR_VIEW_START);
y = (int)xv_get(vert_scrollbar, SCROLLBAR_VIEW_START);
for (xrects->count--; xrects->count >= 0; xrects->count--) {
printf("top-left cell = %d, %d -- %d,%d %d,%d\n", x+1, y+1,
xrects->rect_array[xrects->count].x,
xrects->rect_array[xrects->count].y,
xrects->rect_array[xrects->count].width,
xrects->rect_array[xrects->count].height);
XCopyPlane(dpy, cell_map, win, gc,
xrects->rect_array[xrects->count].x,
xrects->rect_array[xrects->count].y,
xrects->rect_array[xrects->count].width,
xrects->rect_array[xrects->count].height,
xrects->rect_array[xrects->count].x,
xrects->rect_array[xrects->count].y, 1L);
}
}
|