diff options
Diffstat (limited to 'nx-X11/lib/dpstk/DPSScrollW.c')
-rw-r--r-- | nx-X11/lib/dpstk/DPSScrollW.c | 3500 |
1 files changed, 0 insertions, 3500 deletions
diff --git a/nx-X11/lib/dpstk/DPSScrollW.c b/nx-X11/lib/dpstk/DPSScrollW.c deleted file mode 100644 index 9c2f7e005..000000000 --- a/nx-X11/lib/dpstk/DPSScrollW.c +++ /dev/null @@ -1,3500 +0,0 @@ - /* - * DPSScrollW.c - * - * (c) Copyright 1993-1994 Adobe Systems Incorporated. - * All rights reserved. - * - * Permission to use, copy, modify, distribute, and sublicense this software - * and its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notices appear in all copies and that - * both those copyright notices and this permission notice appear in - * supporting documentation and that the name of Adobe Systems Incorporated - * not be used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. No trademark license - * to use the Adobe trademarks is hereby granted. If the Adobe trademark - * "Display PostScript"(tm) is used to describe this software, its - * functionality or for any other purpose, such use shall be limited to a - * statement that this software works in conjunction with the Display - * PostScript system. Proper trademark attribution to reflect Adobe's - * ownership of the trademark shall be given whenever any such reference to - * the Display PostScript system is made. - * - * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR - * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. - * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE - * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT - * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE. - * - * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems - * Incorporated which may be registered in certain jurisdictions - * - * Author: Adobe Systems Incorporated - */ -/* $XFree86$ */ - -#include <X11/IntrinsicP.h> -#include <X11/StringDefs.h> -#include <X11/ShellP.h> -#include <X11/Xproto.h> -#include <stdlib.h> -#include <Xm/Xm.h> - -/* There are no words to describe how I feel about having to do this */ - -#if XmVersion > 1001 -#include <Xm/ManagerP.h> -#else -#include <Xm/XmP.h> -#endif - -#include <Xm/DrawingA.h> -#include <Xm/ScrolledW.h> -#include <Xm/ScrollBar.h> - -#include <DPS/dpsXclient.h> -#include "dpsXcommonI.h" -#include <DPS/dpsXshare.h> -#include "DSWwraps.h" -#include <stdio.h> -#include <DPS/DPSScrollWP.h> - -#undef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#undef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#undef ABS -#define ABS(x) ((x) >= 0 ? (x) : -(x)) -#undef CEIL -#define CEIL(x) ((int) ((float)((int)(x)) == (x) ? (x) : (x) + 1)) - -/* Define macros to get rectangle entries. All rectangles are stored as - x, y, width, height. NOTE: ONLY FOR USER SPACE RECTANGLES, NOT X - RECTANGLES!!!! */ - -#define LEFT(r) ((r)[0]) -#define RIGHT(r) ((r)[0] + (r)[2]) -#define BOTTOM(r) ((r)[1]) -#define TOP(r) ((r)[1] + (r)[3]) -#define WIDTH(r) ((r)[2]) -#define HEIGHT(r) ((r)[3]) - -/* This is used in converting bounding boxes into user space to ensure - that we don't end up slopping over into another pixel */ - -#define DELTA .001 - -#define Offset(field) XtOffsetOf(DPSScrolledWindowRec, sw.field) - -static float initScale = 1.0; - -static XtResource resources[] = { - {XtNcontext, XtCContext, XtRDPSContext, sizeof(DPSContext), - Offset(context), XtRImmediate, (XtPointer) NULL}, - {XtNareaWidth, XtCAreaWidth, XtRInt, sizeof(int), - Offset(area_width), XtRImmediate, (XtPointer) ((int) (8.5*72))}, - {XtNareaHeight, XtCAreaHeight, XtRInt, sizeof(int), - Offset(area_height), XtRImmediate, (XtPointer) (11*72)}, - {XtNscale, XtCScale, XtRFloat, sizeof(float), - Offset(scale), XtRFloat, (XtPointer) &initScale}, - {XtNctm, XtCCtm, XtRFloatArray, sizeof(float *), - Offset(ctm_ptr), XtRImmediate, (XtPointer) NULL}, - {XtNinvCtm, XtCInvCtm, XtRFloatArray, sizeof(float *), - Offset(inv_ctm_ptr), XtRImmediate, (XtPointer) NULL}, - {XtNuseBackingPixmap, XtCUseBackingPixmap, XtRBoolean, sizeof(Boolean), - Offset(use_backing_pixmap), XtRImmediate, (XtPointer) True}, - {XtNuseFeedbackPixmap, XtCUseFeedbackPixmap, XtRBoolean, sizeof(Boolean), - Offset(use_feedback_pixmap), XtRImmediate, (XtPointer) True}, - {XtNbackingPixmap, XtCBackingPixmap, XtRPixmap, sizeof(Pixmap), - Offset(backing_pixmap), XtRImmediate, (XtPointer) None}, - {XtNfeedbackPixmap, XtCFeedbackPixmap, XtRPixmap, sizeof(Pixmap), - Offset(feedback_pixmap), XtRImmediate, (XtPointer) None}, - {XtNdocumentSizePixmaps, XtCDocumentSizePixmaps, - XtRBoolean, sizeof(Boolean), - Offset(document_size_pixmaps), XtRImmediate, (XtPointer) False}, - {XtNwindowGState, XtCWindowGState, XtRDPSGState, sizeof(DPSGState), - Offset(window_gstate), XtRImmediate, (XtPointer) 0}, - {XtNbackingGState, XtCBackingGState, XtRDPSGState, sizeof(DPSGState), - Offset(backing_gstate), XtRImmediate, (XtPointer) 0}, - {XtNfeedbackGState, XtCFeedbackGState, XtRDPSGState, sizeof(DPSGState), - Offset(feedback_gstate), XtRImmediate, (XtPointer) 0}, - {XtNdirtyAreas, XtCDirtyAreas, XtRFloatArray, sizeof(float *), - Offset(dirty_areas), XtRImmediate, (XtPointer) NULL}, - {XtNnumDirtyAreas, XtCNumDirtyAreas, XtRShort, sizeof(short), - Offset(num_dirty_areas), XtRImmediate, (XtPointer) 0}, - {XtNpixmapLimit, XtCPixmapLimit, XtRInt, sizeof(int), - Offset(pixmap_limit), XtRImmediate, (XtPointer) -1}, - {XtNabsolutePixmapLimit, XtCAbsolutePixmapLimit, XtRInt, sizeof(int), - Offset(absolute_pixmap_limit), XtRImmediate, (XtPointer) 0}, - {XtNwatchProgress, XtCWatchProgress, XtRBoolean, sizeof(Boolean), - Offset(watch_progress), XtRImmediate, (XtPointer) False}, - {XtNwatchProgressDelay, XtCWatchProgressDelay, XtRInt, sizeof(int), - Offset(watch_progress_delay), XtRImmediate, (XtPointer) 1000}, - {XtNminimalDrawing, XtCMinimalDrawing, XtRBoolean, sizeof(Boolean), - Offset(minimal_drawing), XtRImmediate, (XtPointer) False}, - {XtNapplicationScrolling, XtCApplicationScrolling, - XtRBoolean, sizeof(Boolean), - Offset(application_scrolling), XtRImmediate, (XtPointer) False}, - {XtNsetupCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), - Offset(setup_callback), XtRCallback, (XtPointer) NULL}, - {XtNexposeCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), - Offset(expose_callback), XtRCallback, (XtPointer) NULL}, - {XtNbackgroundCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), - Offset(background_callback), XtRCallback, (XtPointer) NULL}, - {XtNfeedbackCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), - Offset(feedback_callback), XtRCallback, (XtPointer) NULL}, - {XtNresizeCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList), - Offset(resize_callback), XtRCallback, (XtPointer) NULL}, -}; - -static Boolean GiveFeedbackPixmap(Widget w, Pixmap p, int width, int height, int depth, Screen *screen); -static Boolean SetValues(Widget old, Widget req, Widget new, ArgList args, Cardinal *num_args); -static Boolean TakeFeedbackPixmap(Widget w, Pixmap *p, int *width, int *height, int *depth, Screen **screen); -static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *desired, XtWidgetGeometry *allowed); -static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *desired, XtWidgetGeometry *allowed); -static void AbortPendingDrawing(Widget w); -static void AddExposureToPending(DPSScrolledWindowWidget dsw, XExposeEvent *ev); -static void AddRectsToDirtyArea(DPSScrolledWindowWidget dsw, float *newRect, int n); -static void AddRectsToPending(DPSScrolledWindowWidget dsw, int *newRect, int n); -static void AddToDirtyArea(Widget w, float *rect, long n); -static void AddUserSpaceRectsToPending(DPSScrolledWindowWidget dsw, float *newRect, int n); -static void CallFeedbackCallback(DPSScrolledWindowWidget dsw, float *r, int n); -static void CheckFeedbackPixmap(DPSScrolledWindowWidget dsw); -static void ClassPartInitialize(WidgetClass widget_class); -static void ConvertPSToX(Widget w, double psX, double psY, int *xX, int *xY); -static void ConvertToOrigPS(DPSScrolledWindowWidget dsw, int xX, int xY, float *psX, float *psY); -static void ConvertToPS(DPSScrolledWindowWidget dsw, float xX, float xY, float *psX, float *psY); -static void ConvertToX(DPSScrolledWindowWidget dsw, float psX, float psY, int *xX, int *xY); -static void ConvertXToPS(Widget w, long xX, long xY, float *psX, float *psY); -static void CopyRectsToCurrentDrawing(DPSScrolledWindowWidget dsw, float *newRect, int n); -static void CopyRectsToDirtyArea(DPSScrolledWindowWidget dsw, float *newRect, int n); -static void CopyToFeedbackPixmap(DPSScrolledWindowWidget dsw, float *rects, int n); -static void Destroy(Widget widget); -static void DrawingAreaExpose(Widget w, XtPointer clientData, XtPointer callData); -static void DrawingAreaGraphicsExpose(Widget w, XtPointer clientData, XEvent *event, Boolean *goOn); -static void EndFeedbackDrawing(Widget w, int restore); -static void FinishDrawing(DPSScrolledWindowWidget dsw); -static void FinishPendingDrawing(Widget w); -static void GetDrawingInfo(Widget w, DSWDrawableType *type, Drawable *drawable, DPSGState *gstate, DPSContext *context); -static void GetScrollInfo(Widget w, int *h_value, int *h_size, int *h_max, int *v_value, int *v_size, int *v_max); -static void HScrollCallback(Widget w, XtPointer clientData, XtPointer callData); -static void Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args); -static void Realize(Widget w, XtValueMask *mask, XSetWindowAttributes *attr); -static void Resize(Widget w); -static void ScrollBy(Widget w, long dx, long dy); -static void ScrollMoved(DPSScrolledWindowWidget dsw); -static void ScrollPoint(Widget w, double psX, double psY, long xX, long xY); -static void ScrollTo(Widget w, long x, long y); -static void SetFeedbackDirtyArea(Widget w, float *rects, int count, XtPointer continue_feedback_data); -static void SetScale(Widget w, double scale, long fixedX, long fixedY); -static void SetScaleAndScroll(Widget w, double scale, double psX, double psY, long xX, long xY); -static void StartFeedbackDrawing(Widget w, XtPointer start_feedback_data); -static void UpdateDrawing(Widget w, float *rects, int count); -static void VScrollCallback(Widget w, XtPointer clientData, XtPointer callData); - -DPSScrolledWindowClassRec dpsScrolledWindowClassRec = { - /* Core class part */ - { - /* superclass */ (WidgetClass) &xmManagerClassRec, - /* class_name */ "DPSScrolledWindow", - /* widget_size */ sizeof(DPSScrolledWindowRec), - /* class_initialize */ NULL, - /* class_part_initialize */ ClassPartInitialize, - /* class_inited */ False, - /* initialize */ Initialize, - /* initialize_hook */ NULL, - /* realize */ Realize, - /* actions */ NULL, - /* num_actions */ 0, - /* resources */ resources, - /* num_resources */ XtNumber(resources), - /* xrm_class */ NULLQUARK, - /* compress_motion */ True, - /* compress_exposure */ XtExposeCompressMultiple, - /* compress_enterleave */ True, - /* visible_interest */ False, - /* destroy */ Destroy, - /* resize */ Resize, - /* expose */ NULL, - /* set_values */ SetValues, - /* set_values_hook */ NULL, - /* set_values_almost */ XtInheritSetValuesAlmost, - /* get_values_hook */ NULL, - /* accept_focus */ NULL, - /* version */ XtVersion, - /* callback offsets */ NULL, - /* tm_table */ NULL, - /* query_geometry */ QueryGeometry, - /* display_accelerator */ NULL, - /* extension */ NULL, - }, - /* Composite class part */ - { - /* geometry_manager */ GeometryManager, - /* change_managed */ NULL, - /* insert_child */ XtInheritInsertChild, - /* delete_child */ XtInheritDeleteChild, - /* extension */ NULL, - }, - /* Constraint class part */ - { - /* resources */ NULL, - /* num_resources */ 0, - /* constraint_size */ 0, - /* initialize */ NULL, - /* destroy */ NULL, - /* set_values */ NULL, - /* extension */ NULL, - }, - /* Manager class part */ - { - /* translations */ XtInheritTranslations, - /* syn_resources */ NULL, - /* num_syn_resources */ 0, - /* syn_constraint_resources */ NULL, - /* num_syn_constraint_resources */ 0, - /* parent_process */ XmInheritParentProcess, - /* extension */ NULL, - }, - /* DPSScrolledWindow class part */ - { - /* set_scale */ SetScale, - /* scroll_point */ ScrollPoint, - /* scroll_by */ ScrollBy, - /* scroll_to */ ScrollTo, - /* set_scale_and_scroll */ SetScaleAndScroll, - /* convert_x_to_ps */ ConvertXToPS, - /* convert_ps_to_x */ ConvertPSToX, - /* add_to_dirty_area */ AddToDirtyArea, - /* take_feedback_pixmap */ TakeFeedbackPixmap, - /* give_feedback_pixmap */ GiveFeedbackPixmap, - /* start_feedback_drawing */ StartFeedbackDrawing, - /* end_feedback_drawing */ EndFeedbackDrawing, - /* set_feedback_dirty_area */ SetFeedbackDirtyArea, - /* finish_pending_drawing */ FinishPendingDrawing, - /* abort_pending_drawing */ AbortPendingDrawing, - /* get_drawing_info */ GetDrawingInfo, - /* update_drawing */ UpdateDrawing, - /* get_scroll_info */ GetScrollInfo, - /* extension */ NULL, - } -}; - -WidgetClass dpsScrolledWindowWidgetClass = - (WidgetClass) &dpsScrolledWindowClassRec; - -/***** UTILITY FUNCTIONS *****/ - -static void PrintRectList(float *r, short num_r) -{ - int i; - - for (i = 0; i < num_r; i++) { - printf("Rectangle %d: ", i); - printf("X %g Y %g W %g H %g\n", r[0], r[1], r[2], r[3]); - r += 4; - } -} - -/* Make sure the list pointed to by r can hold n more rectangles. Always - grow by at least min_grow */ - -static void GrowRectList( - float **r, - short *r_size, - short num_r, - int n, int min_grow) -{ - if (*r_size < num_r + n) { - if (min_grow > 1 && num_r + n - *r_size < min_grow) { - *r_size += min_grow; - } else *r_size = num_r + n; - *r = (float *) XtRealloc((char *) *r, *r_size * 4 * sizeof(float)); - } -} - -static void GrowIntRectList( - int **r, - short *r_size, - short num_r, - int n, int min_grow) -{ - if (*r_size < num_r + n) { - if (min_grow > 1 && num_r + n - *r_size < min_grow) { - *r_size += min_grow; - } else *r_size = num_r + n; - *r = (int *) XtRealloc((char *) *r, *r_size * 4 * sizeof(int)); - } -} - -static Boolean Intersects(float *r1, float *r2) -{ - if (RIGHT(r1) <= LEFT(r2)) return False; - if (RIGHT(r2) <= LEFT(r1)) return False; - if (TOP(r1) <= BOTTOM(r2)) return False; - if (TOP(r2) <= BOTTOM(r1)) return False; - - return True; -} - -/* Subtract sub from src, putting result into dst. Return rectangle count */ - -static int Subtract(float *src, float *sub, float *dst) -{ - int n = 0; - - /* If bottom of sub is greater than bottom of src, there's a - rectangle across the bottom */ - if (BOTTOM(sub) > BOTTOM(src)) { - LEFT(dst) = LEFT(src); - BOTTOM(dst) = BOTTOM(src); - WIDTH(dst) = WIDTH(src); - HEIGHT(dst) = BOTTOM(sub) - BOTTOM(src); - n++; - dst += 4; - } - - /* If left of sub is greater than left of src, there's a left rectangle. */ - if (LEFT(sub) > LEFT(src)) { - LEFT(dst) = LEFT(src); - BOTTOM(dst) = MAX(BOTTOM(src), BOTTOM(sub)); - WIDTH(dst) = LEFT(sub) - LEFT(src); - HEIGHT(dst) = MIN(TOP(src), TOP(sub)) - BOTTOM(dst); - n++; - dst += 4; - } - - /* If right of sub is less than right of src, there's a right rect */ - if (RIGHT(sub) < RIGHT(src)) { - LEFT(dst) = RIGHT(sub); - BOTTOM(dst) = MAX(BOTTOM(src), BOTTOM(sub)); - WIDTH(dst) = RIGHT(src) - RIGHT(sub); - HEIGHT(dst) = MIN(TOP(src), TOP(sub)) - BOTTOM(dst); - n++; - dst += 4; - } - - /* If top of sub is less than top of src, there's a top rectangle */ - if (TOP(sub) < TOP(src)) { - LEFT(dst) = LEFT(src); - BOTTOM(dst) = TOP(sub); - WIDTH(dst) = WIDTH(src); - HEIGHT(dst) = TOP(src) - TOP(sub); - n++; - dst += 4; - } - - return n; -} - -static void Copy(float *src, float *dst) -{ - LEFT(dst) = LEFT(src); - BOTTOM(dst) = BOTTOM(src); - WIDTH(dst) = WIDTH(src); - HEIGHT(dst) = HEIGHT(src); -} - -static void Intersection(float *r1, float *r2, float *dst) -{ - LEFT(dst) = MAX(LEFT(r1), LEFT(r2)); - BOTTOM(dst) = MAX(BOTTOM(r1), BOTTOM(r2)); - WIDTH(dst) = MIN(RIGHT(r1), RIGHT(r2)) - LEFT(dst); - HEIGHT(dst) = MIN(TOP(r1), TOP(r2)) - BOTTOM(dst); -} - -/* These are used by the SubtractRects and IntersectRects procedures */ - -static float *rbuf = NULL; -static short rbuf_size = 0; -#define GROW_BUF 10 - -/* Replace the rectangle list in src with src minus sub */ - -static void SubtractRects( - float **src, - short *src_size, - short *num_src, - float *sub, - int num_sub) -{ - short num_rbuf; - float *r; - int i; - - /* Go through, subtracting the first sub rectangle from each src - rectangle. Put the result in the internal buffer, then copy this - list to the src. Repeat for each sub rectangle. */ - - while (num_sub > 0) { - num_rbuf = 0; - for (r = *src, i = 0; i < *num_src; r += 4, i++) { - if (Intersects(r, sub)) { - /* Subtract sub from r, putting result into rbuf. First - make sure there are at least 4 spaces in the buffer */ - GrowRectList(&rbuf, &rbuf_size, num_rbuf, 4, GROW_BUF); - - /* Do the subtraction */ - num_rbuf += Subtract(r, sub, rbuf + (num_rbuf*4)); - } else { - /* Copy r into buffer */ - GrowRectList(&rbuf, &rbuf_size, num_rbuf, 1, GROW_BUF); - Copy(r, rbuf + (num_rbuf*4)); - num_rbuf++; - } - } - - /* Copy buffered rectangles back into src */ - GrowRectList(src, src_size, 0, num_rbuf, 1); - for (i = 0; i < num_rbuf * 4; i++) (*src)[i] = rbuf[i]; - *num_src = num_rbuf; - - /* Check if we've taken everything away */ - if (*num_src == 0) return; - - /* Skip on to the next sub rectangle */ - num_sub--; - sub += 4; - } -} - -/* Replace list r1 with the intersection of r1 and r2 */ - -static void IntersectRects( - float **r1, - short *r1_size, - short *num_r1, - float *r2, - int num_r2) -{ - short num_rbuf = 0; - float *r; - int i; - - /* Fairly straightforward. Intersect each rectangle in r1 with each - rectangle in r2, then copy the results to r1 */ - - while (num_r2 > 0) { - for (r = *r1, i = 0; i < *num_r1; r += 4, i++) { - if (Intersects(r, r2)) { - GrowRectList(&rbuf, &rbuf_size, num_rbuf, 1, GROW_BUF); - Intersection(r, r2, rbuf + (num_rbuf*4)); - num_rbuf++; - } - } - num_r2--; - r2 += 4; - } - - /* Copy intersection rectangles back into r1 */ - GrowRectList(r1, r1_size, 0, num_rbuf, 1); - for (i = 0; i < num_rbuf * 4; i++) (*r1)[i] = rbuf[i]; - *num_r1 = num_rbuf; -} - -static void SimplifyRects(float *rect, short *num) -{ - int i, j, k; - float *r, *r1; - - i = 0; - while (i < *num) { - r = rect + (i * 4); - if (WIDTH(r) == 0 || HEIGHT(r) == 0) { - for (k = 4*(i+1); k < *num * 4; k++) rect[k-4] = rect[k]; - (*num)--; - goto LOOPEND; - } - j = i+1; - while (j < *num) { - r1 = rect + (j * 4); - if (TOP(r1) <= TOP(r) && BOTTOM(r1) >= BOTTOM(r) && - LEFT(r1) >= LEFT(r) && RIGHT(r1) <= RIGHT(r)) { - for (k = 4*(j+1); k < *num * 4; k++) rect[k-4] = rect[k]; - (*num)--; - } else if (TOP(r) <= TOP(r1) && BOTTOM(r) >= BOTTOM(r1) && - LEFT(r) >= LEFT(r1) && RIGHT(r) <= RIGHT(r1)) { - for (k = 4*(i+1); k < *num * 4; k++) rect[k-4] = rect[k]; - (*num)--; - goto LOOPEND; - } else j++; - } - i++; -LOOPEND:; - } -} - -static void ComputeOffsets(DPSScrolledWindowWidget dsw, int *dx, int *dy) -{ - if (dsw->sw.doing_feedback && dsw->sw.feedback_pixmap != None) { - *dx = *dy = 0; - } else { - if (dsw->sw.pixmap_width == dsw->sw.drawing_area->core.width) *dx = 0; - else *dx = -dsw->sw.origin_x; - if (dsw->sw.pixmap_height == dsw->sw.drawing_area->core.height) *dy = 0; - else *dy = CEIL(dsw->sw.drawing_height) - dsw->sw.origin_y; - } -} - -static void ClassPartInitialize(WidgetClass widget_class) -{ - register DPSScrolledWindowWidgetClass wc = - (DPSScrolledWindowWidgetClass) widget_class; - DPSScrolledWindowWidgetClass super = - (DPSScrolledWindowWidgetClass) wc->core_class.superclass; - - if (wc->sw_class.set_scale == InheritSetScale) { - wc->sw_class.set_scale = super->sw_class.set_scale; - } - if (wc->sw_class.scroll_point == InheritScrollPoint) { - wc->sw_class.scroll_point = super->sw_class.scroll_point; - } - if (wc->sw_class.scroll_by == InheritScrollBy) { - wc->sw_class.scroll_by = super->sw_class.scroll_by; - } - if (wc->sw_class.scroll_to == InheritScrollTo) { - wc->sw_class.scroll_to = super->sw_class.scroll_to; - } - if (wc->sw_class.set_scale_and_scroll == InheritSetScaleAndScroll) { - wc->sw_class.set_scale_and_scroll = - super->sw_class.set_scale_and_scroll; - } - if (wc->sw_class.convert_x_to_ps == InheritConvertXToPS) { - wc->sw_class.convert_x_to_ps = super->sw_class.convert_x_to_ps; - } - if (wc->sw_class.convert_ps_to_x == InheritConvertPSToX) { - wc->sw_class.convert_ps_to_x = super->sw_class.convert_ps_to_x; - } - if (wc->sw_class.add_to_dirty_area == InheritAddToDirtyArea) { - wc->sw_class.add_to_dirty_area = super->sw_class.add_to_dirty_area; - } - if (wc->sw_class.take_feedback_pixmap == InheritTakeFeedbackPixmap) { - wc->sw_class.take_feedback_pixmap = - super->sw_class.take_feedback_pixmap; - } - if (wc->sw_class.give_feedback_pixmap == InheritGiveFeedbackPixmap) { - wc->sw_class.give_feedback_pixmap = - super->sw_class.give_feedback_pixmap; - } - if (wc->sw_class.start_feedback_drawing == InheritStartFeedbackDrawing) { - wc->sw_class.start_feedback_drawing = - super->sw_class.start_feedback_drawing; - } - if (wc->sw_class.end_feedback_drawing == InheritEndFeedbackDrawing) { - wc->sw_class.end_feedback_drawing = - super->sw_class.end_feedback_drawing; - } - if (wc->sw_class.set_feedback_dirty_area == InheritSetFeedbackDirtyArea) { - wc->sw_class.set_feedback_dirty_area = - super->sw_class.set_feedback_dirty_area; - } - if (wc->sw_class.finish_pending_drawing == InheritFinishPendingDrawing) { - wc->sw_class.finish_pending_drawing = - super->sw_class.finish_pending_drawing; - } - if (wc->sw_class.abort_pending_drawing == InheritAbortPendingDrawing) { - wc->sw_class.abort_pending_drawing = - super->sw_class.abort_pending_drawing; - } - if (wc->sw_class.get_drawing_info == InheritGetDrawingInfo) { - wc->sw_class.get_drawing_info = super->sw_class.get_drawing_info; - } - if (wc->sw_class.update_drawing == InheritUpdateDrawing) { - wc->sw_class.update_drawing = super->sw_class.update_drawing; - } - if (wc->sw_class.get_scroll_info == InheritGetScrollInfo) { - wc->sw_class.get_scroll_info = super->sw_class.get_scroll_info; - } -} - -static void CreateChildren(DPSScrolledWindowWidget dsw) -{ - Widget w; - - w = dsw->sw.scrolled_window = - XtVaCreateManagedWidget("scrolledWindow", - xmScrolledWindowWidgetClass, - (Widget) dsw, - XtNwidth, dsw->core.width, - XtNheight, dsw->core.height, - XmNscrollingPolicy, XmAPPLICATION_DEFINED, - NULL); - - dsw->sw.h_scroll = - XtVaCreateManagedWidget("horizontalScrollBar", - xmScrollBarWidgetClass, w, - XmNorientation, XmHORIZONTAL, - NULL); - XtAddCallback(dsw->sw.h_scroll, XmNvalueChangedCallback, HScrollCallback, - (XtPointer) dsw); - XtAddCallback(dsw->sw.h_scroll, XmNdragCallback, HScrollCallback, - (XtPointer) dsw); - - dsw->sw.v_scroll = - XtVaCreateManagedWidget("verticalScrollBar", - xmScrollBarWidgetClass, w, - XmNorientation, XmVERTICAL, - NULL); - XtAddCallback(dsw->sw.v_scroll, XmNvalueChangedCallback, VScrollCallback, - (XtPointer) dsw); - XtAddCallback(dsw->sw.v_scroll, XmNdragCallback, VScrollCallback, - (XtPointer) dsw); - - - dsw->sw.drawing_area = - XtVaCreateManagedWidget("drawingArea", - xmDrawingAreaWidgetClass, w, NULL); - XtAddCallback(dsw->sw.drawing_area, XtNexposeCallback, DrawingAreaExpose, - (XtPointer) dsw); - XtAddRawEventHandler(dsw->sw.drawing_area, 0, True, - DrawingAreaGraphicsExpose, (XtPointer) dsw); - - XmScrolledWindowSetAreas(w, dsw->sw.h_scroll, dsw->sw.v_scroll, - dsw->sw.drawing_area); -} - -/* ARGSUSED */ - -static void Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) new; - XGCValues gcVal; - Bool inited; - - if (dsw->sw.area_width <= 0) dsw->sw.area_width = 8.5*72; - if (dsw->sw.area_height <= 0) dsw->sw.area_height = 11*72; - if (dsw->sw.scale <= 0) dsw->sw.scale = 1.0; - dsw->sw.ctm_ptr = dsw->sw.ctm; - dsw->sw.inv_ctm_ptr = dsw->sw.inv_ctm; - dsw->sw.backing_pixmap = None; - dsw->sw.feedback_pixmap = None; - dsw->sw.window_gstate = 0; - dsw->sw.backing_gstate = 0; - dsw->sw.feedback_gstate = 0; - dsw->sw.scrolling = False; - dsw->sw.num_pending_expose = dsw->sw.pending_expose_size = 0; - dsw->sw.pending_expose = NULL; - dsw->sw.num_pending_dirty = dsw->sw.pending_dirty_size = 0; - dsw->sw.pending_dirty = NULL; - dsw->sw.num_current_drawing = dsw->sw.current_drawing_size = 0; - dsw->sw.current_drawing = NULL; - dsw->sw.num_prev_dirty_areas = dsw->sw.prev_dirty_areas_size = 0; - dsw->sw.prev_dirty_areas = NULL; - dsw->sw.drawing_stage = DSWStart; - dsw->sw.work = 0; - dsw->sw.big_pixmap = False; - - /* Set the initial dirty area to everything */ - - dsw->sw.dirty_areas_size = 0; - dsw->sw.dirty_areas = NULL; - - GrowRectList(&dsw->sw.dirty_areas, &dsw->sw.dirty_areas_size, 0, 1, 1); - dsw->sw.num_dirty_areas = 1; - LEFT(dsw->sw.dirty_areas) = 0.0; - BOTTOM(dsw->sw.dirty_areas) = 0.0; - WIDTH(dsw->sw.dirty_areas) = dsw->sw.area_width; - HEIGHT(dsw->sw.dirty_areas) = dsw->sw.area_height; - - /* Make the scratch list have at least one element */ - - dsw->sw.num_scratch = dsw->sw.scratch_size = 0; - dsw->sw.scratch = NULL; - GrowRectList(&dsw->sw.scratch, &dsw->sw.scratch_size, 0, 1, 1); - - /* Get the context */ - - if (dsw->sw.context == NULL) { - dsw->sw.context = XDPSGetSharedContext(XtDisplay(dsw)); - } - - /* Watch progress only works with pass-through event dispatching */ - - if (dsw->sw.watch_progress && - XDPSSetEventDelivery(XtDisplay(dsw), dps_event_query) != - dps_event_pass_through) dsw->sw.watch_progress = False; - - if (_XDPSTestComponentInitialized(dsw->sw.context, - dps_init_bit_dsw, &inited) == - dps_status_unregistered_context) { - XDPSRegisterContext(dsw->sw.context, False); - } - - dsw->sw.use_saved_scroll = False; - dsw->sw.context_inited = False; - dsw->sw.doing_feedback = False; - dsw->sw.feedback_displayed = False; - - CreateChildren(dsw); - - dsw->sw.ge_gc = XtGetGC(dsw->sw.drawing_area, 0, (XGCValues *) NULL); - - gcVal.graphics_exposures = False; - dsw->sw.no_ge_gc = XtGetGC(dsw->sw.drawing_area, GCGraphicsExposures, - &gcVal); -} - -static void Destroy(Widget widget) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) widget; - - if (dsw->sw.backing_pixmap != None) { - XFreePixmap(XtDisplay(dsw), dsw->sw.backing_pixmap); - } - if (dsw->sw.feedback_pixmap != None) { - XFreePixmap(XtDisplay(dsw), dsw->sw.feedback_pixmap); - } - - if (dsw->sw.window_gstate != 0) { - XDPSFreeContextGState(dsw->sw.context, dsw->sw.window_gstate); - } - if (dsw->sw.backing_gstate != 0) { - XDPSFreeContextGState(dsw->sw.context, dsw->sw.backing_gstate); - } - if (dsw->sw.feedback_gstate != 0) { - XDPSFreeContextGState(dsw->sw.context, dsw->sw.feedback_gstate); - } - - if (dsw->sw.pending_expose != NULL) { - XtFree((char *) dsw->sw.pending_expose); - } - if (dsw->sw.current_drawing != NULL) { - XtFree((char *) dsw->sw.current_drawing); - } - if (dsw->sw.prev_dirty_areas != NULL) { - XtFree((char *) dsw->sw.prev_dirty_areas); - } - if (dsw->sw.dirty_areas != NULL) XtFree((char *) dsw->sw.dirty_areas); - if (dsw->sw.pending_dirty != NULL) XtFree((char *) dsw->sw.pending_dirty); - if (dsw->sw.scratch != NULL) XtFree((char *) dsw->sw.scratch); - - XtReleaseGC(widget, dsw->sw.ge_gc); - XtReleaseGC(widget, dsw->sw.no_ge_gc); -} - -static void SetOriginAndGetTransform(DPSScrolledWindowWidget dsw) -{ - float psX, psY; - - ConvertToOrigPS(dsw, dsw->sw.origin_x, dsw->sw.origin_y, &psX, &psY); - _DPSSWSetMatrixAndGetTransform(dsw->sw.context, psX, psY, dsw->sw.scale, - dsw->sw.origin_x, dsw->sw.origin_y, - dsw->sw.ctm, dsw->sw.inv_ctm, - &dsw->sw.x_offset, &dsw->sw.y_offset); -} - -static void SetPixmapOrigin(DPSScrolledWindowWidget dsw) -{ - float psX, psY; - - ConvertToOrigPS(dsw, dsw->sw.origin_x, dsw->sw.origin_y, &psX, &psY); - _DPSSWSetMatrix(dsw->sw.context, psX, psY, dsw->sw.scale, - dsw->sw.origin_x, dsw->sw.origin_y); -} - -static void SetPixmapOffset(DPSScrolledWindowWidget dsw) -{ - int ox, oy; - - if (dsw->sw.pixmap_width <= (int) dsw->sw.drawing_area->core.width) ox = 0; - else ox = -dsw->sw.origin_x; - if (dsw->sw.pixmap_height <= (int) dsw->sw.drawing_area->core.height) { - oy = dsw->sw.drawing_area->core.height; - } else oy = dsw->sw.pixmap_height - dsw->sw.origin_y + - dsw->sw.drawing_area->core.height; - - DPSsetXoffset(dsw->sw.context, ox, oy); -} - -static Boolean pixmapError; -static int (*oldHandler)(Display *, XErrorEvent *); - -static int PixmapHandler(Display *dpy, XErrorEvent *error) -{ - if (error->error_code == BadAlloc && - error->request_code == X_CreatePixmap) { - pixmapError = True; - return 0; - } else return (*oldHandler) (dpy, error); -} - -static Pixmap AllocPixmap(DPSScrolledWindowWidget dsw, unsigned w, unsigned h) -{ - Pixmap p; - unsigned int dBytes; - Widget wid = dsw->sw.drawing_area; - unsigned area = (w * h); - - if (dsw->sw.pixmap_limit > 0) { - if (area > (unsigned)dsw->sw.pixmap_limit) return None; - } else if (dsw->sw.pixmap_limit < 0 - && area > (unsigned)(dsw->sw.unscaled_width * dsw->sw.unscaled_height) - && area > (unsigned)(wid->core.width * wid->core.height)) return None; - - if (dsw->sw.absolute_pixmap_limit > 0) { - dBytes = (wid->core.depth + 7) / 8; /* Convert into bytes */ - if (area * dBytes > (unsigned)dsw->sw.absolute_pixmap_limit * 1024) { - return None; - } - } - - XSync(XtDisplay(dsw), False); - oldHandler = XSetErrorHandler(PixmapHandler); - pixmapError = False; - p = XCreatePixmap(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), w, h, - wid->core.depth); - XSync(XtDisplay(dsw), False); - (void) XSetErrorHandler(oldHandler); - if (pixmapError) return None; - else return p; -} - -static void CreateBackingPixmap(DPSScrolledWindowWidget dsw) -{ - Pixmap p; - - if (dsw->sw.document_size_pixmaps) { - dsw->sw.pixmap_width = - MAX(CEIL(dsw->sw.drawing_width), - (int) dsw->sw.drawing_area->core.width); - dsw->sw.pixmap_height = - MAX(CEIL(dsw->sw.drawing_height), - (int) dsw->sw.drawing_area->core.height); - - p = dsw->sw.backing_pixmap = - AllocPixmap(dsw, dsw->sw.pixmap_width, dsw->sw.pixmap_height); - if (p != None) { - dsw->sw.big_pixmap = - dsw->sw.pixmap_width > - (int) dsw->sw.drawing_area->core.width || - dsw->sw.pixmap_height > - (int) dsw->sw.drawing_area->core.height; - return; - } - } - dsw->sw.big_pixmap = False; - dsw->sw.pixmap_width = dsw->sw.drawing_area->core.width; - dsw->sw.pixmap_height = dsw->sw.drawing_area->core.height; - p = dsw->sw.backing_pixmap = - AllocPixmap(dsw, dsw->sw.pixmap_width, dsw->sw.pixmap_height); - if (p == None) dsw->sw.pixmap_width = dsw->sw.pixmap_height = 0; -} - -static void FreeBackingPixmap(DPSScrolledWindowWidget dsw) -{ - if (dsw->sw.backing_pixmap == None) return; - XFreePixmap(XtDisplay(dsw), dsw->sw.backing_pixmap); - dsw->sw.backing_pixmap = None; - dsw->sw.big_pixmap = False; - dsw->sw.pixmap_width = dsw->sw.pixmap_height = 0; - XDPSFreeContextGState(dsw->sw.context, dsw->sw.backing_gstate); -} - -static void SetDrawingAreaPosition( - DPSScrolledWindowWidget dsw, - float ix, - float iy, - int vx, - int vy, - Boolean setOrigin) -{ - int xoff, yoff; - int hSize, vSize; - float scrollX, scrollY; - - /* Convert ix, iy into X units */ - - ix *= dsw->sw.drawing_width / dsw->sw.area_width; - iy *= dsw->sw.drawing_height / dsw->sw.area_height; - - if ((int)dsw->sw.drawing_area->core.width >= CEIL(dsw->sw.drawing_width)) { - /* The scaled width is narrower than the view window, so - center the picture and set scroll bar to be unscrollable */ - - xoff = ((int) dsw->sw.drawing_area->core.width - - CEIL(dsw->sw.drawing_width)) - / 2.0; - scrollX = 0; - hSize = CEIL(dsw->sw.drawing_width); - } else { - /* The scaled width is larger than the view window, so - turn on the scroll bar, and set up its maximum and - slider size. Do this by converting the image offset into X - coordinates and subtracting the view offset */ - - scrollX = ix - vx; - scrollX = MAX(scrollX, 0); - scrollX = MIN(scrollX, CEIL(dsw->sw.drawing_width) - - (int) dsw->sw.drawing_area->core.width); - hSize = dsw->sw.drawing_area->core.width; - xoff = -(int) (scrollX + 0.5); - } - - /* Now do the same thing for the height. We want to compute the offset - relative to the lower left corner, but X coordinates are relative - to the upper left, so the drawing height must be added in. Also, since - the coordinates go in the other direction, the view offset must be - added, not subtracted. */ - - if ((int) dsw->sw.drawing_area->core.height >= - CEIL(dsw->sw.drawing_height)) { - yoff = ((int) dsw->sw.drawing_area->core.height - - CEIL(dsw->sw.drawing_height)) / 2.0; - scrollY = CEIL(dsw->sw.drawing_height) - - (int) dsw->sw.drawing_area->core.height; - vSize = CEIL(dsw->sw.drawing_height); - } else { - scrollY = iy + vy - (int) dsw->sw.drawing_area->core.height; - scrollY = MAX(scrollY, 0); - scrollY = MIN(scrollY, CEIL(dsw->sw.drawing_height) - - (int) dsw->sw.drawing_area->core.height); - vSize = dsw->sw.drawing_area->core.height; - yoff = -(int) (scrollY + 0.5); - } - - /* Update the scrollbars */ - dsw->sw.scroll_x = (int) (scrollX + 0.5); - dsw->sw.scroll_y = (int) (CEIL(dsw->sw.drawing_height) - - (int) dsw->sw.drawing_area->core.height - - scrollY + 0.5); - - yoff = dsw->sw.drawing_area->core.height - yoff; - - dsw->sw.scroll_h_value = dsw->sw.scroll_x; - dsw->sw.scroll_h_size = hSize; - dsw->sw.scroll_h_max = CEIL(dsw->sw.drawing_width); - dsw->sw.scroll_v_value = dsw->sw.scroll_y; - dsw->sw.scroll_v_size = vSize; - dsw->sw.scroll_v_max = CEIL(dsw->sw.drawing_height); - - if (!dsw->sw.application_scrolling) { - XtVaSetValues(dsw->sw.h_scroll, XmNmaximum, dsw->sw.scroll_h_max, - XmNvalue, dsw->sw.scroll_x, XmNsliderSize, hSize, NULL); - XtVaSetValues(dsw->sw.v_scroll, XmNmaximum, dsw->sw.scroll_v_max, - XmNvalue, dsw->sw.scroll_y, XmNsliderSize, vSize, NULL); - } - - if (setOrigin) { - /* Set the origin in the X window to reflect the new location */ - dsw->sw.origin_x = xoff; - dsw->sw.origin_y = yoff; - } -} - -static void DrawBackground( - DPSScrolledWindowWidget dsw, - DSWDrawableType which) -{ - DSWExposeCallbackRec e; - - e.type = which; - e.directions = DSWFinish; - e.results = DSWUndefined; - e.first = True; - e.background = True; - if (which == DSWBackingPixmap) { - e.drawable = dsw->sw.backing_pixmap; - e.gstate = dsw->sw.backing_gstate; - } else if (which == DSWFeedbackPixmap) { - e.drawable = dsw->sw.feedback_pixmap; - e.gstate = dsw->sw.feedback_gstate; - } else { - e.drawable = XtWindow(dsw->sw.drawing_area); - e.gstate = dsw->sw.window_gstate; - } - e.context = dsw->sw.context; - - SimplifyRects(dsw->sw.current_drawing, &dsw->sw.num_current_drawing); - - XDPSSetContextGState(dsw->sw.context, e.gstate); - _DPSSWSetRectViewClip(dsw->sw.context, dsw->sw.current_drawing, - dsw->sw.num_current_drawing * 4); - - e.rects = dsw->sw.current_drawing; - e.rect_count = dsw->sw.num_current_drawing; - - do { - XtCallCallbackList((Widget) dsw, dsw->sw.background_callback, - (XtPointer) &e); - if (e.results == DSWUndefined) { - if (XtHasCallbacks((Widget) dsw, XtNbackgroundCallback) != - XtCallbackHasNone) { - XtAppWarningMsg(XtWidgetToApplicationContext((Widget) dsw), - "returnError", "backgroundCallback", - "DPSScrollError", - "Background callback did not set result field", - (String *) NULL, (Cardinal *) NULL); - } - e.results = DSWFinished; - } - } while (e.results != DSWFinished); - - - DPSinitviewclip(dsw->sw.context); -} - -static void ClipToDrawingSize( - DPSScrolledWindowWidget dsw, - DSWDrawableType which) -{ - int i; - float r[4]; - - if (CEIL(dsw->sw.drawing_width) >= (int) dsw->sw.drawing_area->core.width && - CEIL(dsw->sw.drawing_height) >= (int) dsw->sw.drawing_area->core.height) return; - - /* Copy current drawing area to scratch */ - - GrowRectList(&dsw->sw.scratch, &dsw->sw.scratch_size, 0, - dsw->sw.num_current_drawing, 1); - dsw->sw.num_scratch = dsw->sw.num_current_drawing; - for (i = 0; i < dsw->sw.num_current_drawing * 4; i++) { - dsw->sw.scratch[i] = dsw->sw.current_drawing[i]; - } - - /* Construct a rectangle of the drawing area */ - - ConvertToPS(dsw, dsw->sw.origin_x + DELTA, dsw->sw.origin_y - DELTA, - r, r+1); - ConvertToPS(dsw, dsw->sw.origin_x + CEIL(dsw->sw.drawing_width) - DELTA, - dsw->sw.origin_y - CEIL(dsw->sw.drawing_height) + DELTA, - r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - - /* Subtract the area of the drawing from the current drawing list */ - - SubtractRects(&dsw->sw.current_drawing, &dsw->sw.current_drawing_size, - &dsw->sw.num_current_drawing, r, 1); - - if (dsw->sw.num_current_drawing != 0) { - DrawBackground(dsw, which); - /* Now intersect the rectangle with the current drawing area */ - IntersectRects(&dsw->sw.scratch, &dsw->sw.scratch_size, - &dsw->sw.num_scratch, r, 1); - /* If nothing left, we won't be drawing anything more, so - synchronize. Otherwise wait until we're done drawing */ - if (dsw->sw.num_scratch == 0) DPSWaitContext(dsw->sw.context); - } - - /* Copy scratch back into the current drawing list */ - GrowRectList(&dsw->sw.current_drawing, &dsw->sw.current_drawing_size, 0, - dsw->sw.num_scratch, 1); - dsw->sw.num_current_drawing = dsw->sw.num_scratch; - for (i = 0; i < dsw->sw.num_scratch * 4; i++) { - dsw->sw.current_drawing[i] = dsw->sw.scratch[i]; - } -} - -static DSWResults ClipAndDraw( - DPSScrolledWindowWidget dsw, - DSWDrawableType which, - DSWDirections howMuch, - Boolean first) -{ - DSWExposeCallbackRec e; - - e.type = which; - e.directions = howMuch; - e.results = DSWUndefined; - e.first = first; - e.background = False; - if (which == DSWBackingPixmap) { - e.drawable = dsw->sw.backing_pixmap; - e.gstate = dsw->sw.backing_gstate; - } else if (which == DSWFeedbackPixmap) { - e.drawable = dsw->sw.feedback_pixmap; - e.gstate = dsw->sw.feedback_gstate; - } else { - e.drawable = XtWindow(dsw->sw.drawing_area); - e.gstate = dsw->sw.window_gstate; - } - e.context = dsw->sw.context; - - if (first) { - XDPSSetContextGState(dsw->sw.context, e.gstate); - if (howMuch != DSWAbort) { - ClipToDrawingSize(dsw, which); - SimplifyRects(dsw->sw.current_drawing, - &dsw->sw.num_current_drawing); - if (dsw->sw.num_current_drawing == 0) return DSWFinished; - _DPSSWSetRectViewClip(dsw->sw.context, dsw->sw.current_drawing, - dsw->sw.num_current_drawing * 4); - } - } - - e.rects = dsw->sw.current_drawing; - e.rect_count = dsw->sw.num_current_drawing; - - do { - XtCallCallbackList((Widget) dsw, dsw->sw.expose_callback, - (XtPointer) &e); - if (e.results == DSWUndefined) { - if (XtHasCallbacks((Widget) dsw, - XtNexposeCallback) != XtCallbackHasNone) { - XtAppWarningMsg(XtWidgetToApplicationContext((Widget) dsw), - "returnError", "exposeCallback", - "DPSScrollError", - "Expose callback did not set result field", - (String *) NULL, (Cardinal *) NULL); - } - e.results = DSWFinished; - } - } while ((e.results != DSWFinished && howMuch == DSWFinish) || - (e.results != DSWFinished && e.results != DSWAborted && - howMuch == DSWAbortOrFinish) || - (e.results != DSWAborted && howMuch == DSWAbort)); - - if (e.results == DSWFinished) { - DPSinitviewclip(dsw->sw.context); - DPSWaitContext(dsw->sw.context); - } - return e.results; -} - -static void SplitExposeEvent( - DPSScrolledWindowWidget dsw, - XExposeEvent *ev) -{ - float *r; - float llx, lly, urx, ury; - int xr[4]; - int i; - int dx, dy; - - ComputeOffsets(dsw, &dx, &dy); - - /* Put the expose event into the scratch list */ - dsw->sw.num_scratch = 1; - r = dsw->sw.scratch; - ConvertToPS(dsw, ev->x + DELTA, ev->y + ev->height - DELTA, &llx, &lly); - ConvertToPS(dsw, ev->x + ev->width - DELTA, ev->y + DELTA, &urx, &ury); - LEFT(r) = llx; - BOTTOM(r) = lly; - WIDTH(r) = urx - llx; - HEIGHT(r) = ury - lly; - - /* Subtract the dirty area from the exposed area and copy the resulting - area to the window */ - SubtractRects(&dsw->sw.scratch, &dsw->sw.scratch_size, - &dsw->sw.num_scratch, - dsw->sw.dirty_areas, dsw->sw.num_dirty_areas); - for (i = 0; i < dsw->sw.num_scratch; i++) { - r = dsw->sw.scratch + 4*i; - ConvertToX(dsw, LEFT(r), TOP(r), xr, xr+1); - ConvertToX(dsw, RIGHT(r), BOTTOM(r), xr+2, xr+3); - xr[2] -= xr[0]; - xr[3] -= xr[1]; - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), dsw->sw.no_ge_gc, - xr[0] + dx, xr[1] + dy, xr[2], xr[3], xr[0], xr[1]); - } - - /* Now do it again, but intersect the exposed area with the dirty area - and add the intersection to the pending list */ - - dsw->sw.num_scratch = 1; - r = dsw->sw.scratch; - LEFT(r) = llx; - BOTTOM(r) = lly; - WIDTH(r) = urx - llx; - HEIGHT(r) = ury - lly; - IntersectRects(&dsw->sw.scratch, &dsw->sw.scratch_size, - &dsw->sw.num_scratch, - dsw->sw.dirty_areas, dsw->sw.num_dirty_areas); - AddUserSpaceRectsToPending(dsw, dsw->sw.scratch, dsw->sw.num_scratch); -} - -/* ARGSUSED */ - -static Bool CheckWatchProgressEvent( - Display *dpy, - XEvent *e, - char *arg) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) arg; - - return (e->xany.window == dsw->sw.backing_pixmap && - (e->type == GraphicsExpose || e->type == NoExpose)) || - (e->xany.window == XtWindow(dsw->sw.drawing_area) && - e->type == Expose); -} - -static void CopyWindowToBackingPixmap( - DPSScrolledWindowWidget dsw) -{ - int llx, lly, urx, ury; - XEvent e; - XExposeEvent *ev = (XExposeEvent *) &e; - int i; - float *r; - int copies = 0; - int dx, dy; - - ComputeOffsets(dsw, &dx, &dy); - - for (i = 0; i < dsw->sw.num_dirty_areas; i++) { - r = dsw->sw.dirty_areas + i*4; - ConvertToX(dsw, LEFT(r), BOTTOM(r), &llx, &lly); - ConvertToX(dsw, RIGHT(r), TOP(r), &urx, &ury); - XCopyArea(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), - dsw->sw.backing_pixmap, dsw->sw.ge_gc, - llx, ury, urx-llx, lly-ury, llx + dx, ury + dy); - copies++; - } - - /* Unfortunately the Intrinsics won't let us get ahold of the the - GraphicsExpose events for the pixmap, so we have to wait and - get them the old fashioned way. Yuck. */ - - while (copies > 0) { - XIfEvent(XtDisplay(dsw), &e, CheckWatchProgressEvent, - (char *) dsw); - if (e.type == Expose) { - SplitExposeEvent(dsw, ev); - continue; - } else if (e.type == GraphicsExpose) { - ev->x -= dx; - ev->y -= dy; - AddExposureToPending(dsw, ev); - if (ev->count == 0) copies--; - } else copies--; /* NoExpose */ - } - CopyRectsToCurrentDrawing(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - - dsw->sw.num_pending_dirty = 0; - dsw->sw.num_pending_expose = 0; - if (dsw->sw.num_current_drawing == 0) { - dsw->sw.drawing_stage = DSWDone; - dsw->sw.num_dirty_areas = 0; - } else { - /* The dirty area is now the intersection of the old dirty area and - the newly-created current drawing list */ - IntersectRects(&dsw->sw.dirty_areas, &dsw->sw.dirty_areas_size, - &dsw->sw.num_dirty_areas, - dsw->sw.current_drawing, dsw->sw.num_current_drawing); - } -} - -/* Subtract the window area from the dirty area, and make the - result be the new current drawing list */ - -static void SetCurrentDrawingToBackground( - DPSScrolledWindowWidget dsw) -{ - int i; - float r[4]; - - ConvertToPS(dsw, 0 + DELTA, dsw->sw.drawing_area->core.height - DELTA, - r, r+1); - ConvertToPS(dsw, dsw->sw.drawing_area->core.width - DELTA, 0 + DELTA, - r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - - SubtractRects(&dsw->sw.dirty_areas, &dsw->sw.dirty_areas_size, - &dsw->sw.num_dirty_areas, r, 1); - - GrowRectList(&dsw->sw.current_drawing, &dsw->sw.current_drawing_size, - 0, dsw->sw.num_dirty_areas, 1); - for (i = 0; i < 4 * dsw->sw.num_dirty_areas; i++) { - dsw->sw.current_drawing[i] = dsw->sw.dirty_areas[i]; - } - dsw->sw.num_current_drawing = dsw->sw.num_dirty_areas; -} - -static void CopyPendingExpose(DPSScrolledWindowWidget dsw) -{ - int dx, dy; - int i; - int *r; - - ComputeOffsets(dsw, &dx, &dy); - - for (i = 0; i < dsw->sw.num_pending_expose; i++) { - r = dsw->sw.pending_expose + 4*i; - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, - LEFT(r) + dx, BOTTOM(r) + dy, WIDTH(r), HEIGHT(r), - LEFT(r), BOTTOM(r)); - } - dsw->sw.num_pending_expose = dsw->sw.num_pending_dirty = 0; -} - -static void UpdateWindowFromBackingPixmap( - DPSScrolledWindowWidget dsw, - float *rects, - int n) -{ - int dx, dy; - int llx, lly, urx, ury; - int i; - float *r; - - ComputeOffsets(dsw, &dx, &dy); - - for (i = 0; i < n; i++) { - r = rects + 4*i; - ConvertToX(dsw, LEFT(r), BOTTOM(r), &llx, &lly); - ConvertToX(dsw, RIGHT(r), TOP(r), &urx, &ury); - - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, - llx+dx-1, ury+dy-1, urx-llx+2, lly-ury+2, llx-1, ury-1); - } -} - -static void UpdateWindowFromFeedbackPixmap( - DPSScrolledWindowWidget dsw, - float *rects, - int n) -{ - int llx, lly, urx, ury; - int i; - float *r; - - for (i = 0; i < n; i++) { - r = rects + (i * 4); - ConvertToX(dsw, LEFT(r), BOTTOM(r), &llx, &lly); - ConvertToX(dsw, RIGHT(r), TOP(r), &urx, &ury); - - XCopyArea(XtDisplay(dsw), dsw->sw.feedback_pixmap, - XtWindow(dsw->sw.drawing_area), dsw->sw.no_ge_gc, - llx-1, ury-1, urx-llx+2, lly-ury+2, llx-1, ury-1); - } -} - -/* This is the heart of the drawing code; it does one piece of drawing. - It can be called either directly or as a work procedure */ - -static Boolean DoDrawing(XtPointer clientData) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) clientData; - DSWResults results; - DSWDrawableType which; - - if (dsw->sw.drawing_stage == DSWStart && dsw->sw.watch_progress && - dsw->sw.backing_pixmap != None && dsw->sw.num_current_drawing == 0) { - dsw->sw.drawing_stage = DSWDrewVisible; - CopyWindowToBackingPixmap(dsw); - } - - switch (dsw->sw.drawing_stage) { - case DSWStart: - case DSWDrawingVisible: - if (dsw->sw.watch_progress || dsw->sw.backing_pixmap == None) { - which = DSWWindow; - } else which = DSWBackingPixmap; - results = ClipAndDraw(dsw, which, DSWDrawSome, - (dsw->sw.drawing_stage == DSWStart)); - if (results == DSWFinished) { - if (dsw->sw.watch_progress && dsw->sw.backing_pixmap != None) { - dsw->sw.drawing_stage = DSWDrewVisible; - CopyWindowToBackingPixmap(dsw); - } else { - if (dsw->sw.minimal_drawing && dsw->sw.big_pixmap) { - dsw->sw.drawing_stage = DSWDrewVisible; - SetCurrentDrawingToBackground(dsw); - } else { - dsw->sw.drawing_stage = DSWDone; - dsw->sw.num_dirty_areas = 0; - } - if (dsw->sw.num_pending_expose != 0 && - dsw->sw.backing_pixmap != None) { - CopyPendingExpose(dsw); - } - } - } else dsw->sw.drawing_stage = DSWDrawingVisible; - break; - - case DSWDrewVisible: - case DSWDrawingBackground: - results = ClipAndDraw(dsw, DSWBackingPixmap, DSWDrawSome, - (dsw->sw.drawing_stage == DSWDrewVisible)); - if (results == DSWFinished) { - dsw->sw.drawing_stage = DSWDone; - dsw->sw.num_dirty_areas = 0; - } - else dsw->sw.drawing_stage = DSWDrawingBackground; - break; - - case DSWDone: - break; - } - - if (dsw->sw.drawing_stage == DSWDone && dsw->sw.num_pending_dirty != 0) { - CopyRectsToCurrentDrawing(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - CopyRectsToDirtyArea(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - dsw->sw.num_pending_dirty = 0; - dsw->sw.num_pending_expose = 0; - dsw->sw.drawing_stage = DSWStart; - } - - if (dsw->sw.drawing_stage == DSWDone) { - dsw->sw.work = 0; - if (dsw->sw.watch_progress) { - /* Some of the background drawing may have been to areas that - are visible */ - UpdateWindowFromBackingPixmap(dsw, dsw->sw.current_drawing, - dsw->sw.num_current_drawing); - } - dsw->sw.num_current_drawing = 0; - if (dsw->sw.scrolling) { - dsw->sw.scrolling = False; - ScrollMoved(dsw); - } - return True; - } else return False; -} - -static void StartDrawing(DPSScrolledWindowWidget dsw) -{ - float r[4]; - - CopyRectsToCurrentDrawing(dsw, dsw->sw.dirty_areas, - dsw->sw.num_dirty_areas); - - if (dsw->sw.watch_progress || dsw->sw.backing_pixmap == None) { - /* Intersect the current drawing area with the pending dirty area - (The pending dirty area represents the window exposures that - have happened so far) */ - IntersectRects(&dsw->sw.current_drawing, &dsw->sw.current_drawing_size, - &dsw->sw.num_current_drawing, - dsw->sw.pending_dirty, dsw->sw.num_pending_dirty); - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - } else { - if (!dsw->sw.big_pixmap || dsw->sw.minimal_drawing) { - /* Intersect the current drawing area to the window to start */ - ConvertToPS(dsw, 0 + DELTA, - dsw->sw.drawing_area->core.height - DELTA, r, r+1); - ConvertToPS(dsw, dsw->sw.drawing_area->core.width - DELTA, - 0 + DELTA, r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - IntersectRects(&dsw->sw.current_drawing, - &dsw->sw.current_drawing_size, - &dsw->sw.num_current_drawing, r, 1); - } - } - - if (dsw->sw.num_current_drawing == 0 && !dsw->sw.watch_progress) { - dsw->sw.drawing_stage = DSWFinished; - dsw->sw.num_dirty_areas = 0; - return; - } - - dsw->sw.drawing_stage = DSWStart; - if (!DoDrawing((XtPointer) dsw)) { - dsw->sw.work = - XtAppAddWorkProc(XtWidgetToApplicationContext((Widget) dsw), - DoDrawing, (XtPointer) dsw); - } -} - -static void RedisplaySliver(DPSScrolledWindowWidget dsw, int deltaX, int deltaY) -{ - float r[8]; - int xr[8]; - int n; - int xllx, xlly, xurx, xury; - float llx, lly, urx, ury; - - /* If one of the deltas is 0, then the area to update is just a - single rectangle. */ - if (deltaX == 0 || deltaY == 0) { - if (deltaX == 0) { - /* Just a single horizontal rectangle */ - - xllx = 0; - xurx = dsw->sw.drawing_area->core.width; - if (deltaY > 0) { - xlly = dsw->sw.drawing_area->core.height; - xury = dsw->sw.drawing_area->core.height - deltaY; - } else { - xlly = -deltaY; - xury = 0; - } - - } else if (deltaY == 0) { - /* Just a single vertical rectangle */ - xlly = dsw->sw.drawing_area->core.height; - xury = 0; - if (deltaX > 0) { - xllx = dsw->sw.drawing_area->core.width - deltaX; - xurx = dsw->sw.drawing_area->core.width; - } else { - xllx = 0; - xurx = -deltaX; - } - } - /* Convert the rectangle into PS coordinates */ - ConvertToPS(dsw, xllx + DELTA, xlly - DELTA, &llx, &lly); - ConvertToPS(dsw, xurx - DELTA, xury + DELTA, &urx, &ury); - r[0] = llx; - r[1] = lly; - r[2] = urx - llx; - r[3] = ury - lly; - xr[0] = xllx; - xr[1] = xury; - xr[2] = xurx - xllx; - xr[3] = xlly - xury; - n = 1; - - } else { - /* Scrolling in both directions, so there are two rectangles. - It's easiest to do if we let them overlap; fortunately that is - legal! First do the horizontal rectangle. */ - xllx = 0; - xurx = dsw->sw.drawing_area->core.width; - if (deltaY > 0) { - xlly = dsw->sw.drawing_area->core.height; - xury = dsw->sw.drawing_area->core.height - deltaY; - } else { - xlly = -deltaY; - xury = 0; - } - ConvertToPS(dsw, xllx + DELTA, xlly - DELTA, &llx, &lly); - ConvertToPS(dsw, xurx - DELTA, xury + DELTA, &urx, &ury); - - /* Store in point array */ - r[0] = llx; - r[1] = lly; - r[2] = urx - llx; - r[3] = ury - lly; - xr[0] = xllx; - xr[1] = xury; - xr[2] = xurx - xllx; - xr[3] = xlly - xury; - - /* Now do vertical rectangle and store in point array */ - xlly = dsw->sw.drawing_area->core.height; - xury = 0; - if (deltaX > 0) { - xllx = dsw->sw.drawing_area->core.width - deltaX; - xurx = dsw->sw.drawing_area->core.width; - } else { - xllx = 0; - xurx = -deltaX; - } - ConvertToPS(dsw, xllx + DELTA, xlly - DELTA, &llx, &lly); - ConvertToPS(dsw, xurx - DELTA, xury + DELTA, &urx, &ury); - r[4] = llx; - r[5] = lly; - r[6] = urx - llx; - r[7] = ury - lly; - xr[4] = xllx; - xr[5] = xury; - xr[6] = xurx - xllx; - xr[7] = xlly - xury; - n = 2; - } - - AddRectsToDirtyArea(dsw, r, n); - AddRectsToPending(dsw, xr, n); - StartDrawing(dsw); -} - -static void SetUpInitialPixmap(DPSScrolledWindowWidget dsw) -{ - float *r = dsw->sw.dirty_areas; - int llx, lly, urx, ury; - - CreateBackingPixmap(dsw); - if (dsw->sw.backing_pixmap != None) { - XDPSSetContextDrawable(dsw->sw.context, dsw->sw.backing_pixmap, - dsw->sw.pixmap_height); - - SetPixmapOffset(dsw); - SetPixmapOrigin(dsw); - XDPSCaptureContextGState(dsw->sw.context, &dsw->sw.backing_gstate); - - if (dsw->sw.pixmap_width != CEIL(dsw->sw.drawing_width) || - dsw->sw.pixmap_height != CEIL(dsw->sw.drawing_height)) { - - /* Make the dirty area match the window */ - if (dsw->sw.pixmap_width > (int)dsw->sw.drawing_area->core.width) { - llx = dsw->sw.origin_x; - urx = llx + CEIL(dsw->sw.drawing_width); - } else { - llx = 0; - urx = dsw->sw.drawing_area->core.width; - } - if (dsw->sw.pixmap_height > - (int) dsw->sw.drawing_area->core.height) { - lly = dsw->sw.origin_y; - ury = dsw->sw.origin_y - CEIL(dsw->sw.drawing_height); - } else { - lly = dsw->sw.drawing_area->core.height; - ury = 0; - } - ConvertToPS(dsw, llx + DELTA, lly - DELTA, r, r+1); - ConvertToPS(dsw, urx - DELTA, ury + DELTA, r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - dsw->sw.num_dirty_areas = 1; - } - if (dsw->sw.doing_feedback) { - CopyRectsToCurrentDrawing(dsw, dsw->sw.dirty_areas, - dsw->sw.num_dirty_areas); - FinishDrawing(dsw); - } else if (!dsw->sw.watch_progress) StartDrawing(dsw); - } -} - -/* ARGSUSED */ - -static void TimerStart(XtPointer clientData, XtIntervalId *id) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) clientData; - - if (dsw->sw.drawing_stage == DSWStart) StartDrawing(dsw); -} - -static void SetUpInitialInformation(DPSScrolledWindowWidget dsw) -{ - int i; - float llx, lly, urx, ury; - float xScale, yScale; - XExposeEvent ev; - XStandardColormap colorCube, grayRamp; - int match; - - /* If the context's colormap matches the widget's colormap, assume that - everything is already set up right in the color cube department. This - allows an application to supply us with a custom color cube by - installing it in the context before calling us */ - - _DPSSWColormapMatch(dsw->sw.context, - dsw->sw.drawing_area->core.colormap, &match); - - if (match) { - XDPSSetContextParameters(dsw->sw.context, XtScreen(dsw), - dsw->sw.drawing_area->core.depth, - XtWindow(dsw->sw.drawing_area), - dsw->sw.drawing_area->core.height, NULL, NULL, - XDPSContextScreenDepth | XDPSContextDrawable); - } else { - grayRamp.colormap = colorCube.colormap = - dsw->sw.drawing_area->core.colormap; - - XDPSCreateStandardColormaps(XtDisplay(dsw), XtWindow(dsw), - (Visual *) NULL, 0, 0, 0, 0, - &colorCube, &grayRamp, False); - - XDPSSetContextParameters(dsw->sw.context, XtScreen(dsw), - dsw->sw.drawing_area->core.depth, - XtWindow(dsw->sw.drawing_area), - dsw->sw.drawing_area->core.height, - (XDPSStandardColormap *) &colorCube, - (XDPSStandardColormap *) &grayRamp, - XDPSContextScreenDepth | XDPSContextDrawable | - XDPSContextRGBMap | XDPSContextGrayMap); - } - - DPSinitgraphics(dsw->sw.context); - _DPSSWGetTransform(dsw->sw.context, dsw->sw.ctm, dsw->sw.orig_inv_ctm); - dsw->sw.x_offset = 0; - dsw->sw.y_offset = dsw->sw.drawing_area->core.height; - for (i = 0; i < 6; i++) dsw->sw.inv_ctm[i] = dsw->sw.orig_inv_ctm[i]; - - ConvertToPS(dsw, 0.0, 100.0, &llx, &lly); - ConvertToPS(dsw, 100.0, 0.0, &urx, &ury); - xScale = ABS(100.0 / (urx - llx)); - yScale = ABS(100.0 / (ury - lly)); - - if (dsw->sw.scale != 1.0) { - DPSscale(dsw->sw.context, dsw->sw.scale, dsw->sw.scale); - _DPSSWGetTransform(dsw->sw.context, dsw->sw.ctm, dsw->sw.inv_ctm); - } - - dsw->sw.drawing_width = dsw->sw.area_width * xScale * dsw->sw.scale; - dsw->sw.drawing_height = dsw->sw.area_height * yScale * dsw->sw.scale; - - dsw->sw.unscaled_width = dsw->sw.drawing_width / dsw->sw.scale + 1; - dsw->sw.unscaled_height = dsw->sw.drawing_height / dsw->sw.scale + 1; - - if (!dsw->sw.use_saved_scroll) { - dsw->sw.scroll_pic_x = dsw->sw.area_width / 2; - dsw->sw.scroll_pic_y = dsw->sw.area_height / 2; - dsw->sw.scroll_win_x = dsw->sw.drawing_area->core.width / 2; - dsw->sw.scroll_win_y = dsw->sw.drawing_area->core.height / 2; - } - - SetDrawingAreaPosition(dsw, dsw->sw.scroll_pic_x, dsw->sw.scroll_pic_y, - dsw->sw.scroll_win_x, dsw->sw.scroll_win_y, True); - SetOriginAndGetTransform(dsw); - XDPSCaptureContextGState(dsw->sw.context, &dsw->sw.window_gstate); - - dsw->sw.drawing_stage = DSWStart; - - if (dsw->sw.use_backing_pixmap) SetUpInitialPixmap(dsw); - - if (dsw->sw.doing_feedback) return; - - if (dsw->sw.watch_progress || dsw->sw.backing_pixmap == None) { - /* If watching progress or no pixmap, clear the window to ensure - that things get started */ - XClearArea(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), - 0, 0, 0, 0, True); - XSync(XtDisplay(dsw), False); - if (dsw->sw.watch_progress && dsw->sw.watch_progress_delay > 0) { - /* Set a timer so that we start drawing if nothing is visible */ - (void) XtAppAddTimeOut(XtWidgetToApplicationContext((Widget) dsw), - dsw->sw.watch_progress_delay, - TimerStart, (XtPointer) dsw); - } - } else { - /* Put a synthetic expose event in the pending queue */ - ev.x = ev.y = 0; - ev.width = dsw->sw.drawing_area->core.width; - ev.height = dsw->sw.drawing_area->core.height; - SplitExposeEvent(dsw, &ev); - } -} - -static void Realize( - Widget w, - XtValueMask *mask, - XSetWindowAttributes *attr) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - DSWSetupCallbackRec setup; - - /* Let my parent do all the hard work */ - (*dpsScrolledWindowClassRec.core_class.superclass->core_class.realize) - (w, mask, attr); - - /* We delay calling the setup callback so that the caller can use - XtAddCallback to add it */ - setup.context = dsw->sw.context; - XtCallCallbackList((Widget) dsw, dsw->sw.setup_callback, - (XtPointer) &setup); - - /* Now, explicitly realize my children */ - XtRealizeWidget(dsw->sw.scrolled_window); - - /* Et voila, now we have windows! */ - SetUpInitialInformation(dsw); -} - -static void AbortOrFinish(DPSScrolledWindowWidget dsw) -{ - DSWResults results; - DSWDrawableType which; - - if (dsw->sw.work != 0) { - XtRemoveWorkProc(dsw->sw.work); - dsw->sw.work = 0; - } - - switch (dsw->sw.drawing_stage) { - case DSWStart: - return; - /* break; */ - - case DSWDrawingVisible: - if (dsw->sw.watch_progress || dsw->sw.backing_pixmap == None) { - which = DSWWindow; - } else which = DSWBackingPixmap; - results = ClipAndDraw(dsw, which, DSWAbortOrFinish, False); - if (results == DSWAborted) { - dsw->sw.drawing_stage = DSWStart; - if (dsw->sw.backing_pixmap == None || dsw->sw.watch_progress) { - /* Add the current drawing area back into the pending - expose area */ - AddUserSpaceRectsToPending(dsw, dsw->sw.current_drawing, - dsw->sw.num_current_drawing); - } - return; - } - if (dsw->sw.watch_progress && dsw->sw.backing_pixmap != None) { - dsw->sw.drawing_stage = DSWDrewVisible; - CopyWindowToBackingPixmap(dsw); - if (dsw->sw.num_current_drawing != 0) { - results = ClipAndDraw(dsw, DSWBackingPixmap, - DSWAbortOrFinish, True); - } - if (results == DSWAborted) { - dsw->sw.drawing_stage = DSWStart; - return; - } - } else { - if (dsw->sw.backing_pixmap != None) { - if (dsw->sw.num_pending_expose != 0) { - CopyPendingExpose(dsw); - } - - if (dsw->sw.minimal_drawing && dsw->sw.big_pixmap) { - dsw->sw.drawing_stage = DSWDrewVisible; - SetCurrentDrawingToBackground(dsw); - results = ClipAndDraw(dsw, which, - DSWAbortOrFinish, True); - if (results == DSWAborted) { - dsw->sw.drawing_stage = DSWStart; - return; - } - } - } - } - break; - - case DSWDrewVisible: - case DSWDrawingBackground: - results = ClipAndDraw(dsw, DSWBackingPixmap, DSWAbortOrFinish, - (dsw->sw.drawing_stage == DSWDrewVisible)); - if (results == DSWAborted) { - dsw->sw.drawing_stage = DSWStart; - return; - } - break; - - case DSWDone: - break; - } - - dsw->sw.drawing_stage = DSWDone; - dsw->sw.num_dirty_areas = 0; - return; -} - -static void AbortDrawing(DPSScrolledWindowWidget dsw) -{ - DSWDrawableType which; - - if (dsw->sw.work != 0) { - XtRemoveWorkProc(dsw->sw.work); - dsw->sw.work = 0; - } - - switch (dsw->sw.drawing_stage) { - case DSWStart: - case DSWDone: - case DSWDrewVisible: - break; - - case DSWDrawingVisible: - if (dsw->sw.watch_progress || dsw->sw.backing_pixmap == None) { - which = DSWWindow; - } else which = DSWBackingPixmap; - (void) ClipAndDraw(dsw, which, DSWAbort, False); - break; - - case DSWDrawingBackground: - (void) ClipAndDraw(dsw, DSWBackingPixmap, DSWAbort, False); - break; - - } - - dsw->sw.num_pending_expose = dsw->sw.num_pending_dirty = 0; -} - -static void FinishDrawing(DPSScrolledWindowWidget dsw) -{ - DSWDrawableType which; - - if (dsw->sw.work != 0) { - XtRemoveWorkProc(dsw->sw.work); - dsw->sw.work = 0; - } - - switch (dsw->sw.drawing_stage) { - case DSWStart: - case DSWDrawingVisible: - if (dsw->sw.watch_progress || dsw->sw.backing_pixmap == None) { - which = DSWWindow; - } else which = DSWBackingPixmap; - if (dsw->sw.drawing_stage == DSWStart) { - ClipToDrawingSize(dsw, which); - if (dsw->sw.num_current_drawing == 0) return; - } - (void) ClipAndDraw(dsw, which, DSWFinish, - dsw->sw.drawing_stage == DSWStart); - if (dsw->sw.watch_progress && dsw->sw.backing_pixmap != None) { - dsw->sw.drawing_stage = DSWDrewVisible; - CopyWindowToBackingPixmap(dsw); - if (dsw->sw.num_current_drawing != 0) { - (void) ClipAndDraw(dsw, DSWBackingPixmap, DSWFinish, True); - } - } else { - if (dsw->sw.backing_pixmap != None) { - if (dsw->sw.num_pending_expose != 0) { - CopyPendingExpose(dsw); - } - - if (dsw->sw.minimal_drawing && dsw->sw.big_pixmap) { - dsw->sw.drawing_stage = DSWDrewVisible; - SetCurrentDrawingToBackground(dsw); - (void) ClipAndDraw(dsw, which, DSWFinish, True); - } - } - } - break; - - case DSWDrewVisible: - case DSWDrawingBackground: - (void) ClipAndDraw(dsw, DSWBackingPixmap, DSWFinish, - (dsw->sw.drawing_stage == DSWDrewVisible)); - break; - - case DSWDone: - break; - } - - dsw->sw.drawing_stage = DSWDone; - dsw->sw.num_dirty_areas = 0; -} - -static void DoScroll( - DPSScrolledWindowWidget dsw, - int deltaX, int deltaY) -{ - /* Set the PS origin in the X window to the new settings of - the scrollbars */ - dsw->sw.origin_x -= deltaX; - dsw->sw.origin_y -= deltaY; - - /* Update the graphics states for the window and backing pixmap to - reflect new origin */ - (void) XDPSSetContextGState(dsw->sw.context, dsw->sw.window_gstate); - SetOriginAndGetTransform(dsw); - (void) XDPSUpdateContextGState(dsw->sw.context, dsw->sw.window_gstate); - - if (dsw->sw.backing_pixmap != None && !dsw->sw.big_pixmap) { - (void) XDPSSetContextGState(dsw->sw.context, dsw->sw.backing_gstate); - SetPixmapOrigin(dsw); - (void) XDPSUpdateContextGState(dsw->sw.context, - dsw->sw.backing_gstate); - } - - /* Update the stored position of the scroll bars */ - dsw->sw.scroll_x += deltaX; - dsw->sw.scroll_y += deltaY; -} - -static void ShiftPendingExpose( - DPSScrolledWindowWidget dsw, - int deltaX, int deltaY) -{ - int i; - int *r; - - for (i = 0; i < dsw->sw.num_pending_expose; i++) { - r = dsw->sw.pending_expose + 4*i; - r[0] -= deltaX; - r[1] -= deltaY; - } -} - -static void HScrollCallback( - Widget w, - XtPointer clientData, XtPointer callData) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) clientData; - XmScrollBarCallbackStruct *sb = (XmScrollBarCallbackStruct *) callData; - - if (!dsw->sw.application_scrolling) { - dsw->sw.scroll_h_value = sb->value; - ScrollMoved(dsw); - } -} - -static void VScrollCallback( - Widget w, - XtPointer clientData, XtPointer callData) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) clientData; - XmScrollBarCallbackStruct *sb = (XmScrollBarCallbackStruct *) callData; - - if (!dsw->sw.application_scrolling) { - dsw->sw.scroll_v_value = sb->value; - ScrollMoved(dsw); - } -} - -/* ARGSUSED */ - -static void ScrollMoved(DPSScrolledWindowWidget dsw) -{ - int deltaX, deltaY; - - /* If we haven't started drawing yet, it must be because we're waiting - for GraphicsExpose events. Delay scrolling until they come in */ - if (dsw->sw.scrolling && dsw->sw.drawing_stage == DSWStart) return; - - /* Calculate the delta in the scrolling */ - deltaX = dsw->sw.scroll_h_value - dsw->sw.scroll_x; - deltaY = dsw->sw.scroll_v_value - dsw->sw.scroll_y; - - /* If there is some scrolling to do, then scroll the pixmap and - copy the pixmap to the window */ - if (deltaX == 0 && deltaY == 0) return; - - ShiftPendingExpose(dsw, deltaX, deltaY); - - AbortOrFinish(dsw); - - DoScroll(dsw, deltaX, deltaY); - - if (!dsw->sw.big_pixmap) { - /* Copy visible area to new location */ - if (dsw->sw.backing_pixmap != None) { - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - dsw->sw.backing_pixmap, dsw->sw.no_ge_gc, - deltaX, deltaY, dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - if (!dsw->sw.doing_feedback || dsw->sw.feedback_pixmap == None) { - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), dsw->sw.no_ge_gc, - 0, 0, dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - } - RedisplaySliver(dsw, deltaX, deltaY); - } else { - if (!dsw->sw.doing_feedback || dsw->sw.feedback_pixmap == None) { - XCopyArea(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), - XtWindow(dsw->sw.drawing_area), dsw->sw.ge_gc, - deltaX, deltaY, dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - } - if (dsw->sw.doing_feedback) RedisplaySliver(dsw, deltaX, deltaY); - else dsw->sw.drawing_stage = DSWStart; - } - } - - if (dsw->sw.doing_feedback) { - float *r; - - FinishDrawing(dsw); - - r = dsw->sw.prev_dirty_areas; - ConvertToPS(dsw, 0 + DELTA, dsw->sw.drawing_area->core.height - DELTA, - r, r+1); - ConvertToPS(dsw, dsw->sw.drawing_area->core.width - DELTA, 0 + DELTA, - r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - dsw->sw.num_prev_dirty_areas = 1; - - if (dsw->sw.feedback_pixmap != None) { - XDPSSetContextDrawable(dsw->sw.context, dsw->sw.feedback_pixmap, - dsw->sw.drawing_area->core.height); - SetPixmapOrigin(dsw); - XDPSCaptureContextGState(dsw->sw.context, - &dsw->sw.feedback_gstate); - - /* Initialize the feedback pixmap with a copy of the drawing */ - if (dsw->sw.backing_pixmap != None) { - CopyToFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - (void) ClipAndDraw(dsw, DSWFeedbackPixmap, DSWFinish, True); - } - if (!dsw->sw.feedback_displayed) { - XCopyArea(XtDisplay(dsw), dsw->sw.feedback_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, 0, 0, - dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - } - } - - if (dsw->sw.feedback_displayed) { - CallFeedbackCallback(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } - if (dsw->sw.feedback_pixmap != None) { - UpdateWindowFromFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - - } else { - if (dsw->sw.backing_pixmap != None && - dsw->sw.drawing_stage == DSWDone) { - ComputeOffsets(dsw, &deltaX, &deltaY); - if (!dsw->sw.big_pixmap) dsw->sw.scrolling = True; - - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), dsw->sw.no_ge_gc, - deltaX, deltaY, - dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - } else dsw->sw.scrolling = True; - } -} - -static void AddExposureToPending( - DPSScrolledWindowWidget dsw, - XExposeEvent *ev) -{ - float *f; - int *i; - - if (dsw->sw.backing_pixmap == None || dsw->sw.watch_progress || - dsw->sw.doing_feedback) { - GrowRectList(&dsw->sw.pending_dirty, &dsw->sw.pending_dirty_size, - dsw->sw.num_pending_dirty, 1, 1); - - f = dsw->sw.pending_dirty + (dsw->sw.num_pending_dirty * 4); - ConvertToPS(dsw, ev->x + DELTA, ev->y + ev->height - DELTA, f, f+1); - ConvertToPS(dsw, ev->x + ev->width - DELTA, ev->y + DELTA, f+2, f+3); - f[2] -= f[0]; - f[3] -= f[1]; - dsw->sw.num_pending_dirty++; - } - - GrowIntRectList(&dsw->sw.pending_expose, &dsw->sw.pending_expose_size, - dsw->sw.num_pending_expose, 1, 1); - - i = dsw->sw.pending_expose + (dsw->sw.num_pending_expose * 4); - i[0] = ev->x; - i[1] = ev->y; - i[2] = ev->width; - i[3] = ev->height; - dsw->sw.num_pending_expose++; -} - -static void AddRectsToPending( - DPSScrolledWindowWidget dsw, - int *newRect, - int n) -{ - int *r; - int i; - float *f; - - if (dsw->sw.backing_pixmap == None || dsw->sw.watch_progress) { - GrowRectList(&dsw->sw.pending_dirty, &dsw->sw.pending_dirty_size, - dsw->sw.num_pending_dirty, n, 1); - - for (i = 0; i < n; i++) { - f = dsw->sw.pending_dirty + (dsw->sw.num_pending_dirty * 4); - r = newRect + (i * 4); - ConvertToPS(dsw, r[0] + DELTA, r[1] + r[3] - DELTA, f, f+1); - ConvertToPS(dsw, r[0] + r[2] - DELTA, r[1] + DELTA, f+2, f+3); - f[2] -= f[0]; - f[3] -= f[1]; - dsw->sw.num_pending_dirty++; - } - } - - GrowIntRectList(&dsw->sw.pending_expose, &dsw->sw.pending_expose_size, - dsw->sw.num_pending_expose, n, 1); - - r = dsw->sw.pending_expose + (dsw->sw.num_pending_expose * 4); - for (i = 0; i < 4*n; i++) r[i] = newRect[i]; - dsw->sw.num_pending_expose += n; -} - -static void AddUserSpaceRectsToPending( - DPSScrolledWindowWidget dsw, - float *newRect, - int n) -{ - int *r; - int i; - float *f; - - if (dsw->sw.backing_pixmap == None || dsw->sw.watch_progress) { - GrowRectList(&dsw->sw.pending_dirty, &dsw->sw.pending_dirty_size, - dsw->sw.num_pending_dirty, n, 1); - - f = dsw->sw.pending_dirty + (dsw->sw.num_pending_dirty * 4); - for (i = 0; i < 4*n; i++) f[i] = newRect[i]; - dsw->sw.num_pending_dirty += n; - } - - GrowIntRectList(&dsw->sw.pending_expose, &dsw->sw.pending_expose_size, - dsw->sw.num_pending_expose, n, 1); - - for (i = 0; i < n; i++) { - r = dsw->sw.pending_expose + (dsw->sw.num_pending_expose * 4); - f = newRect + (i * 4); - ConvertToX(dsw, LEFT(f), TOP(f), r, r+1); - ConvertToX(dsw, RIGHT(f), BOTTOM(f), r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - dsw->sw.num_pending_expose++; - } -} - -static void CopyRectsToCurrentDrawing( - DPSScrolledWindowWidget dsw, - float *newRect, - int n) -{ - float *r; - int i; - - GrowRectList(&dsw->sw.current_drawing, &dsw->sw.current_drawing_size, - 0, n, 1); - - r = dsw->sw.current_drawing; - for (i = 0; i < 4*n; i++) r[i] = newRect[i]; - dsw->sw.num_current_drawing = n; -} - -static void CopyRectsToDirtyArea( - DPSScrolledWindowWidget dsw, - float *newRect, - int n) -{ - float *r; - int i; - - GrowRectList(&dsw->sw.dirty_areas, &dsw->sw.dirty_areas_size, 0, n, 1); - - r = dsw->sw.dirty_areas; - for (i = 0; i < 4*n; i++) r[i] = newRect[i]; - dsw->sw.num_dirty_areas = n; -} - -static void AddRectsToDirtyArea( - DPSScrolledWindowWidget dsw, - float *newRect, - int n) -{ - float *r; - int i; - - GrowRectList(&dsw->sw.dirty_areas, &dsw->sw.dirty_areas_size, - dsw->sw.num_dirty_areas, n, 1); - - r = dsw->sw.dirty_areas + (4 * dsw->sw.num_dirty_areas); - for (i = 0; i < 4*n; i++) r[i] = newRect[i]; - dsw->sw.num_dirty_areas += n; -} - -static void CopyRectsToPrevDirtyArea( - DPSScrolledWindowWidget dsw, - float *newRect, - int n) -{ - float *r; - int i; - - GrowRectList(&dsw->sw.prev_dirty_areas, - &dsw->sw.prev_dirty_areas_size, 0, n, 1); - - r = dsw->sw.prev_dirty_areas; - for (i = 0; i < 4*n; i++) r[i] = newRect[i]; - dsw->sw.num_prev_dirty_areas = n; -} - -/* ARGSUSED */ - -static void DrawingAreaGraphicsExpose( - Widget w, - XtPointer clientData, - XEvent *event, - Boolean *goOn) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) clientData; - XExposeEvent *ev = (XExposeEvent *) event; - - switch (event->type) { - case GraphicsExpose: - /* GraphicsExpose occur during unbuffered scrolling */ - if (dsw->sw.backing_pixmap == None && dsw->sw.scrolling) { - /* Unbuffered scrolling case */ - AddExposureToPending(dsw, ev); - - if (ev->count == 0) { - AddRectsToDirtyArea(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - StartDrawing(dsw); - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - } - } - break; - } -} - -static Boolean MoreExposes(Widget w) -{ - XEvent event; - - if (XPending(XtDisplay(w)) > 0) { - if (XCheckTypedWindowEvent(XtDisplay(w), XtWindow(w), - Expose, &event)) { - XPutBackEvent(XtDisplay(w), &event); - return True;; - } - } - return False; -} - -static void DrawingAreaExpose( - Widget w, - XtPointer clientData, XtPointer callData) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) clientData; - XmDrawingAreaCallbackStruct *d = (XmDrawingAreaCallbackStruct *) callData; - XExposeEvent *ev = (XExposeEvent *) d->event; - int dx, dy; - - if (dsw->sw.doing_feedback) { - if (dsw->sw.feedback_pixmap != None) { - XCopyArea(XtDisplay(dsw), dsw->sw.feedback_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, - ev->x, ev->y, ev->width, ev->height, ev->x, ev->y); - } else { - if (dsw->sw.backing_pixmap != None) { - ComputeOffsets(dsw, &dx, &dy); - - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, ev->x + dx, ev->y + dy, - ev->width, ev->height, ev->x, ev->y); - } - AddExposureToPending(dsw, ev); - if (ev->count != 0 || MoreExposes(w)) return; - - if (dsw->sw.backing_pixmap == None) { - CopyRectsToCurrentDrawing(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - dsw->sw.drawing_stage = DSWStart; - FinishDrawing(dsw); - } - if (dsw->sw.feedback_displayed) { - CallFeedbackCallback(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - } - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - } - return; - } - - if (dsw->sw.backing_pixmap != None) { - if (dsw->sw.drawing_stage == DSWStart && dsw->sw.watch_progress) { - SplitExposeEvent(dsw, ev); - if (ev->count == 0) { - if (MoreExposes(w)) return; - StartDrawing(dsw); - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - } - return; - } - - if (dsw->sw.drawing_stage < DSWDrewVisible) { - SplitExposeEvent(dsw, ev); - return; - } - ComputeOffsets(dsw, &dx, &dy); - - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, - ev->x + dx, ev->y + dy, ev->width, ev->height, ev->x, ev->y); - } else { - AddExposureToPending(dsw, ev); - if (ev->count == 0) { - if (MoreExposes(w)) return; - if (dsw->sw.drawing_stage == DSWDone || - dsw->sw.drawing_stage == DSWStart) { - CopyRectsToDirtyArea(dsw, dsw->sw.pending_dirty, - dsw->sw.num_pending_dirty); - StartDrawing(dsw); - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - } - } - } -} - -static void Resize(Widget w) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - DSWResizeCallbackRec r; - float x, y; - - if (XtIsRealized(w)) (void) AbortOrFinish(dsw); - - r.oldw = dsw->sw.scrolled_window->core.width; - r.oldh = dsw->sw.scrolled_window->core.height; - r.neww = dsw->core.width; - r.newh = dsw->core.height; - r.x = r.y = 0; - - XtCallCallbackList(w, dsw->sw.resize_callback, (XtPointer) &r); - - if (XtIsRealized(w)) { - ConvertToPS(dsw, (float) r.x, (float) r.y, &x, &y); - } else if (r.x != 0 || r.y != 0) ScrollBy(w, r.x, r.y); - - XtResizeWidget(dsw->sw.scrolled_window, w->core.width, w->core.height, 0); - - if (!XtIsRealized(w)) return; - - if (dsw->sw.backing_pixmap != None && - dsw->sw.pixmap_width == CEIL(dsw->sw.drawing_width) && - dsw->sw.pixmap_height == CEIL(dsw->sw.drawing_height) && - dsw->sw.pixmap_width >= (int) dsw->sw.drawing_area->core.width && - dsw->sw.pixmap_height >= (int) dsw->sw.drawing_area->core.width) { - - XDPSSetContextGState(dsw->sw.context, dsw->sw.window_gstate); - DPSinitclip(dsw->sw.context); - DPSinitviewclip(dsw->sw.context); - SetDrawingAreaPosition(dsw, x, y, r.x, r.y, True); - SetOriginAndGetTransform(dsw); - XDPSUpdateContextGState(dsw->sw.context, dsw->sw.window_gstate); - XClearArea(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), - 0, 0, 0, 0, True); - } else { - dsw->sw.use_saved_scroll = True; - dsw->sw.scroll_pic_x = x; - dsw->sw.scroll_pic_y = y; - dsw->sw.scroll_win_x = r.x; - dsw->sw.scroll_win_y = r.y; - - if (dsw->sw.backing_pixmap != None) { - XFreePixmap(XtDisplay(dsw), dsw->sw.backing_pixmap); - XDPSFreeContextGState(dsw->sw.context, dsw->sw.backing_gstate); - } - dsw->sw.backing_pixmap = None; - dsw->sw.big_pixmap = False; - dsw->sw.pixmap_width = dsw->sw.pixmap_height = 0; - - dsw->sw.num_dirty_areas = 1; - LEFT(dsw->sw.dirty_areas) = 0.0; - BOTTOM(dsw->sw.dirty_areas) = 0.0; - WIDTH(dsw->sw.dirty_areas) = dsw->sw.area_width; - HEIGHT(dsw->sw.dirty_areas) = dsw->sw.area_height; - - SetUpInitialInformation(dsw); - } - - if (dsw->sw.doing_feedback) { - float *r; - int dx, dy; - - CheckFeedbackPixmap(dsw); - r = dsw->sw.prev_dirty_areas; - ConvertToPS(dsw, 0 + DELTA, dsw->sw.drawing_area->core.height - DELTA, - r, r+1); - ConvertToPS(dsw, dsw->sw.drawing_area->core.width - DELTA, 0 + DELTA, - r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - dsw->sw.num_prev_dirty_areas = 1; - - if (dsw->sw.feedback_pixmap != None) { - /* Initialize the feedback pixmap with a copy of the drawing */ - if (dsw->sw.backing_pixmap != None) { - CopyToFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - (void) ClipAndDraw(dsw, DSWFeedbackPixmap, DSWFinish, True); - } - XCopyArea(XtDisplay(dsw), dsw->sw.feedback_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, 0, 0, - dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - } else { - if (dsw->sw.backing_pixmap != None) { - ComputeOffsets(dsw, &dx, &dy); - - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - XtWindow(dsw->sw.drawing_area), - dsw->sw.no_ge_gc, dx, dy, - dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height, 0, 0); - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - dsw->sw.drawing_stage = DSWStart; - FinishDrawing(dsw); - } - } - if (dsw->sw.feedback_displayed) { - CallFeedbackCallback(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } - if (dsw->sw.feedback_pixmap != None) { - UpdateWindowFromFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } - dsw->sw.num_pending_dirty = dsw->sw.num_pending_expose = 0; - } -} - -static void CheckFeedbackPixmap(DPSScrolledWindowWidget dsw) -{ - if (dsw->sw.feedback_pixmap != None && - (dsw->sw.feedback_width < (int) dsw->sw.drawing_area->core.width || - dsw->sw.feedback_height < (int) dsw->sw.drawing_area->core.height)) { - XFreePixmap(XtDisplay(dsw), dsw->sw.feedback_pixmap); - dsw->sw.feedback_pixmap = None; - dsw->sw.feedback_width = dsw->sw.feedback_height = 0; - } - if (dsw->sw.use_feedback_pixmap && dsw->sw.feedback_pixmap == None) { - dsw->sw.feedback_pixmap = - AllocPixmap(dsw, dsw->sw.drawing_area->core.width, - dsw->sw.drawing_area->core.height); - if (dsw->sw.feedback_pixmap != None) { - dsw->sw.feedback_width = dsw->sw.drawing_area->core.width; - dsw->sw.feedback_height = dsw->sw.drawing_area->core.height; - } - } - if (dsw->sw.feedback_pixmap != None) { - XDPSSetContextDrawable(dsw->sw.context, dsw->sw.feedback_pixmap, - dsw->sw.drawing_area->core.height); - SetPixmapOrigin(dsw); - XDPSCaptureContextGState(dsw->sw.context, &dsw->sw.feedback_gstate); - } -} - -static void UpdateGStates(DPSScrolledWindowWidget dsw) -{ - /* Create graphics states for the window and backing pixmap in - the new context */ - XDPSSetContextDrawable(dsw->sw.context, XtWindow(dsw->sw.drawing_area), - dsw->sw.drawing_area->core.height); - DPSinitgraphics(dsw->sw.context); - if (dsw->sw.scale != 1.0) { - DPSscale(dsw->sw.context, dsw->sw.scale, dsw->sw.scale); - } - - SetOriginAndGetTransform(dsw); - (void) XDPSCaptureContextGState(dsw->sw.context, &dsw->sw.window_gstate); - if (dsw->sw.backing_pixmap != None) { - XDPSSetContextDrawable(dsw->sw.context, dsw->sw.backing_pixmap, - dsw->sw.pixmap_height); - - SetPixmapOffset(dsw); - SetPixmapOrigin(dsw); - XDPSCaptureContextGState(dsw->sw.context, &dsw->sw.backing_gstate); - } -} - -static void CheckPixmapSize(DPSScrolledWindowWidget dsw) -{ - Boolean freeIt = False; - int w = dsw->sw.pixmap_width, h = dsw->sw.pixmap_height; - Widget wid = dsw->sw.drawing_area; - unsigned int dBytes; - - if (dsw->sw.pixmap_limit > 0) { - if (w * h > dsw->sw.pixmap_limit) freeIt = True; - } else if (dsw->sw.pixmap_limit < 0 && - w * h > dsw->sw.unscaled_width * dsw->sw.unscaled_height && - w * h > (int) wid->core.width * (int) wid->core.height) { - freeIt = True; - } - - if (dsw->sw.absolute_pixmap_limit > 0) { - dBytes = (wid->core.depth + 7) / 8; /* Convert into bytes */ - if (w * h * dBytes > (unsigned)dsw->sw.absolute_pixmap_limit * 1024) { - freeIt = True; - } - } - if (freeIt) { - XFreePixmap(XtDisplay(dsw), dsw->sw.backing_pixmap); - dsw->sw.backing_pixmap = None; - dsw->sw.big_pixmap = False; - dsw->sw.pixmap_width = dsw->sw.pixmap_height = 0; - XDPSFreeContextGState(dsw->sw.context, dsw->sw.backing_gstate); - } -} - -static void ResizeArea(DPSScrolledWindowWidget dsw) -{ - AbortDrawing(dsw); - - /* Make everything dirty */ - dsw->sw.num_dirty_areas = 1; - LEFT(dsw->sw.dirty_areas) = 0.0; - BOTTOM(dsw->sw.dirty_areas) = 0.0; - WIDTH(dsw->sw.dirty_areas) = dsw->sw.area_width; - HEIGHT(dsw->sw.dirty_areas) = dsw->sw.area_height; - - if (dsw->sw.big_pixmap) { - XFreePixmap(XtDisplay(dsw), dsw->sw.backing_pixmap); - dsw->sw.backing_pixmap = None; - dsw->sw.big_pixmap = False; - dsw->sw.pixmap_width = dsw->sw.pixmap_height = 0; - XDPSFreeContextGState(dsw->sw.context, dsw->sw.backing_gstate); - } - - if (!dsw->sw.use_saved_scroll) { - /* Keep the upper left in the same place */ - dsw->sw.scroll_win_x = 0; - dsw->sw.scroll_win_y = 0; - ConvertToPS(dsw, 0.0, 0.0, - &dsw->sw.scroll_pic_x, &dsw->sw.scroll_pic_y); - dsw->sw.use_saved_scroll = True; - } - - SetUpInitialInformation(dsw); -} - -static void ClearDirtyAreas(DPSScrolledWindowWidget dsw) -{ - int i; - float *r; - int llx, lly, urx, ury; - - for (i = 0; i < dsw->sw.num_dirty_areas; i++) { - r = dsw->sw.dirty_areas + (i * 4); - ConvertToX(dsw, LEFT(r), BOTTOM(r), &llx, &lly); - ConvertToX(dsw, RIGHT(r), TOP(r), &urx, &ury); - XClearArea(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), - llx, ury, urx-llx, lly-ury, True); - } -} - -static void HandleFeedbackPixmapChange(DPSScrolledWindowWidget dsw) -{ - if (!dsw->sw.use_feedback_pixmap) { - /* Get rid of one if we have it */ - if (dsw->sw.feedback_pixmap != None) { - XFreePixmap(XtDisplay(dsw), dsw->sw.feedback_pixmap); - dsw->sw.feedback_pixmap = None; - dsw->sw.feedback_width = dsw->sw.feedback_height = 0; - } - } else { - if (dsw->sw.doing_feedback) { - float *r; - - CheckFeedbackPixmap(dsw); - if (dsw->sw.feedback_pixmap == None) return; - - r = dsw->sw.prev_dirty_areas; - ConvertToPS(dsw, 0 + DELTA, - dsw->sw.drawing_area->core.height - DELTA, r, r+1); - ConvertToPS(dsw, dsw->sw.drawing_area->core.width - DELTA, - 0 + DELTA, r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - dsw->sw.num_prev_dirty_areas = 1; - - /* Initialize the feedback pixmap with a copy of the drawing */ - if (dsw->sw.backing_pixmap != None) { - CopyToFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - (void) ClipAndDraw(dsw, DSWFeedbackPixmap, DSWFinish, True); - } - if (dsw->sw.feedback_displayed) { - CallFeedbackCallback(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } - } - } -} - -/* ARGSUSED */ - -static Boolean SetValues( - Widget old, Widget req, Widget new, - ArgList args, - Cardinal *num_args) -{ - DPSScrolledWindowWidget olddsw = (DPSScrolledWindowWidget) old; - DPSScrolledWindowWidget newdsw = (DPSScrolledWindowWidget) new; - Bool inited; - -#define NE(field) newdsw->sw.field != olddsw->sw.field -#define DONT_CHANGE(field) \ - if (NE(field)) newdsw->sw.field = olddsw->sw.field; - - DONT_CHANGE(ctm_ptr); - DONT_CHANGE(inv_ctm_ptr); - DONT_CHANGE(backing_pixmap); - DONT_CHANGE(feedback_pixmap); - DONT_CHANGE(window_gstate); - DONT_CHANGE(backing_gstate); - DONT_CHANGE(feedback_gstate); - - if (NE(context)) { - DSWSetupCallbackRec setup; - - if (newdsw->sw.context == NULL) { - newdsw->sw.context = XDPSGetSharedContext(XtDisplay(newdsw)); - } - if (_XDPSTestComponentInitialized(newdsw->sw.context, - dps_init_bit_dsw, &inited) == - dps_status_unregistered_context) { - XDPSRegisterContext(newdsw->sw.context, False); - } - if (XtIsRealized(newdsw)) { - setup.context = newdsw->sw.context; - XtCallCallbackList((Widget) newdsw, newdsw->sw.setup_callback, - (XtPointer) &setup); - } - UpdateGStates(newdsw); - } - - /* Watch progress only works with pass-through event dispatching */ - - if (NE(watch_progress)) { - if (newdsw->sw.watch_progress && - XDPSSetEventDelivery(XtDisplay(newdsw), dps_event_query) != - dps_event_pass_through) newdsw->sw.watch_progress = False; - } - - if (NE(application_scrolling) && !newdsw->sw.application_scrolling) { - XtVaSetValues(newdsw->sw.h_scroll, XmNmaximum, newdsw->sw.scroll_h_max, - XmNvalue, newdsw->sw.scroll_h_value, - XmNsliderSize, newdsw->sw.scroll_h_size, NULL); - XtVaSetValues(newdsw->sw.v_scroll, XmNmaximum, newdsw->sw.scroll_v_max, - XmNvalue, newdsw->sw.scroll_v_value, - XmNsliderSize, newdsw->sw.scroll_v_size, NULL); - } - - if (newdsw->sw.doing_feedback) { - DONT_CHANGE(scale); - DONT_CHANGE(area_width); - DONT_CHANGE(area_height); - } - - if (NE(pixmap_limit) || NE(absolute_pixmap_limit)) CheckPixmapSize(newdsw); - - if (NE(area_width) || NE(area_height) || NE(scale)) ResizeArea(newdsw); - - /* It's too confusing to let any of these things change in the middle - of drawing */ - - if (NE(use_backing_pixmap) || NE(watch_progress) || - NE(minimal_drawing) || NE(document_size_pixmaps)) { - Boolean freeIt = False, setUp = False; - AbortOrFinish(newdsw); - if (NE(use_backing_pixmap)) { - if (newdsw->sw.use_backing_pixmap) setUp = True; - else freeIt = True; - } - if (NE(document_size_pixmaps)) { - if (newdsw->sw.backing_pixmap != None) freeIt = True; - setUp = True; - } - if (freeIt) FreeBackingPixmap(newdsw); - if (setUp) SetUpInitialPixmap(newdsw); - } - - if (NE(dirty_areas)) { - float *r = newdsw->sw.dirty_areas; - int n = newdsw->sw.num_dirty_areas; - DONT_CHANGE(dirty_areas); - DONT_CHANGE(num_dirty_areas); - AbortOrFinish(newdsw); - AddRectsToDirtyArea(newdsw, r, n); - if (newdsw->sw.watch_progress || newdsw->sw.backing_pixmap == None) { - ClearDirtyAreas(newdsw); - newdsw->sw.drawing_stage = DSWStart; - } else { - AddUserSpaceRectsToPending(newdsw, r, n); - StartDrawing(newdsw); - } - } - - if (NE(use_feedback_pixmap)) HandleFeedbackPixmapChange(newdsw); - - return False; -#undef DONT_CHANGE -} - -static XtGeometryResult GeometryManager( - Widget w, - XtWidgetGeometry *desired, XtWidgetGeometry *allowed) -{ - /* Pass geometry requests up to our parent */ - return XtMakeGeometryRequest(XtParent(w), desired, allowed); -} - -static XtGeometryResult QueryGeometry( - Widget w, - XtWidgetGeometry *desired, XtWidgetGeometry *allowed) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - /* Pass geometry requests down to our child */ - return XtQueryGeometry(dsw->sw.scrolled_window, desired, allowed); -} - -static void CopyToFeedbackPixmap( - DPSScrolledWindowWidget dsw, - float *rects, - int n) -{ - int llx, lly, urx, ury; - int dx, dy; - int i; - float *r; - - ComputeOffsets(dsw, &dx, &dy); - - for (i = 0; i < n; i++) { - r = rects + (i * 4); - ConvertToX(dsw, LEFT(r), BOTTOM(r), &llx, &lly); - ConvertToX(dsw, RIGHT(r), TOP(r), &urx, &ury); - - XCopyArea(XtDisplay(dsw), dsw->sw.backing_pixmap, - dsw->sw.feedback_pixmap, dsw->sw.no_ge_gc, - llx+dx-1, ury+dy-1, urx-llx+2, lly-ury+2, llx-1, ury-1); - } -} - -static void CallFeedbackCallback( - DPSScrolledWindowWidget dsw, - float *r, - int n) -{ - DSWFeedbackCallbackRec f; - - f.start_feedback_data = dsw->sw.start_feedback_data; - f.continue_feedback_data = dsw->sw.continue_feedback_data; - if (dsw->sw.feedback_pixmap == None) { - f.type = DSWWindow; - f.drawable = XtWindow(dsw->sw.drawing_area); - f.gstate = dsw->sw.window_gstate; - } else { - f.type = DSWFeedbackPixmap; - f.drawable = dsw->sw.feedback_pixmap; - f.gstate = dsw->sw.feedback_gstate; - } - f.context = dsw->sw.context; - f.dirty_rects = r; - f.dirty_count = n; - - XDPSSetContextGState(dsw->sw.context, f.gstate); - _DPSSWSetRectViewClip(dsw->sw.context, r, n * 4); - XtCallCallbackList((Widget) dsw, dsw->sw.feedback_callback, - (XtPointer) &f); - DPSWaitContext(dsw->sw.context); -} - -static void SetScale( - Widget w, - double scale, - long fixedX, long fixedY) -{ - float psX, psY; - - ConvertToPS((DPSScrolledWindowWidget) w, (float) fixedX, (float) fixedY, - &psX, &psY); - SetScaleAndScroll(w, scale, psX, psY, fixedX, fixedY); -} - -void DSWSetScale( - Widget w, - double scale, - long fixedX, long fixedY) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.set_scale) (w, scale, fixedX, fixedY); -} - -static void ScrollPoint( - Widget w, - double psX, double psY, - long xX, long xY) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if (!XtIsRealized(w)) { - dsw->sw.use_saved_scroll = True; - dsw->sw.scroll_pic_x = psX; - dsw->sw.scroll_pic_y = psY; - dsw->sw.scroll_win_x = xX; - dsw->sw.scroll_win_y = xY; - return; - } else { - SetDrawingAreaPosition(dsw, psX, psY, xX, xY, False); - ScrollMoved(dsw); - } -} - -void DSWScrollPoint( - Widget w, - double psX, double psY, - long xX, long xY) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.scroll_point) (w, psX, psY, xX, xY); -} - -static void ScrollBy(Widget w, long dx, long dy) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - int value; - - if (dx == 0 && dy == 0) return; - - if (!XtIsRealized(w) && dsw->sw.use_saved_scroll) { - dsw->sw.scroll_win_x += dx; - dsw->sw.scroll_win_y += dy; - } else { - value = dsw->sw.scroll_h_value + dx; - - if (value < 0) value = 0; - else if (value > dsw->sw.scroll_h_max - dsw->sw.scroll_h_size) { - value = dsw->sw.scroll_h_max - dsw->sw.scroll_h_size; - } - dsw->sw.scroll_h_value = value; - - if (!dsw->sw.application_scrolling) { - XtVaSetValues(dsw->sw.h_scroll, XmNvalue, value, NULL); - } - - value = dsw->sw.scroll_v_value + dy; - - if (value < 0) value = 0; - else if (value > dsw->sw.scroll_v_max - dsw->sw.scroll_v_size) { - value = dsw->sw.scroll_v_max - dsw->sw.scroll_v_size; - } - dsw->sw.scroll_v_value = value; - - if (!dsw->sw.application_scrolling) { - XtVaSetValues(dsw->sw.v_scroll, XmNvalue, value, NULL); - } - - ScrollMoved(dsw); - } -} - -void DSWScrollBy(Widget w, long dx, long dy) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.scroll_by) (w, dx, dy); -} - -static void ScrollTo(Widget w, long x, long y) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - int max, size; - - if (XtIsRealized(w)) { - if (x < 0) x = 0; - else if (x > dsw->sw.scroll_h_max - dsw->sw.scroll_h_size) { - x = dsw->sw.scroll_h_max - dsw->sw.scroll_h_size; - } - dsw->sw.scroll_h_value = x; - - if (y < 0) y = 0; - else if (y > dsw->sw.scroll_v_max - dsw->sw.scroll_v_size) { - y = dsw->sw.scroll_v_max - dsw->sw.scroll_v_size; - } - dsw->sw.scroll_v_value = y; - - if (!dsw->sw.application_scrolling) { - XtVaSetValues(dsw->sw.h_scroll, XmNvalue, x, NULL); - XtVaSetValues(dsw->sw.v_scroll, XmNvalue, y, NULL); - } - - ScrollMoved(dsw); - } -} - -void DSWScrollTo(Widget w, long x, long y) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.scroll_to) (w, x, y); -} - -static void SetScaleAndScroll( - Widget w, - double scale, - double psX, double psY, - long xX, long xY) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - Arg arg; - union { - int i; - float f; - } kludge; - - dsw->sw.use_saved_scroll = True; - dsw->sw.scroll_pic_x = psX; - dsw->sw.scroll_pic_y = psY; - dsw->sw.scroll_win_x = xX; - dsw->sw.scroll_win_y = xY; - - kludge.f = scale; - arg.name = XtNscale; - if (sizeof(float) > sizeof(XtArgVal)) arg.value = (XtArgVal) &kludge.f; - else arg.value = (XtArgVal) kludge.i; - XtSetValues(w, &arg, 1); -} - -void DSWSetScaleAndScroll( - Widget w, - double scale, - double psX, double psY, - long xX, long xY) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.set_scale_and_scroll) (w, scale, psX, psY, xX, xY); -} - -static void ConvertXToPS( - Widget w, - long xX, long xY, - float *psX, float *psY) -{ - ConvertToPS((DPSScrolledWindowWidget) w, (float) xX, (float) xY, psX, psY); -} - -void DSWConvertXToPS( - Widget w, - long xX, long xY, - float *psX, float *psY) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.convert_x_to_ps) (w, xX, xY, psX, psY); -} - -static void ConvertPSToX( - Widget w, - double psX, double psY, - int *xX, int *xY) -{ - ConvertToX((DPSScrolledWindowWidget) w, psX, psY, xX, xY); -} - -void DSWConvertPSToX( - Widget w, - double psX, double psY, - int *xX, int *xY) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.convert_ps_to_x) (w, psX, psY, xX, xY); -} - -static void AddToDirtyArea( - Widget w, - float *rect, - long n) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if (n == 1 && rect[0] == 0 && rect[1] == 0 && - rect[2] == -1 && rect[2] == -1) { - rect[2] = dsw->sw.area_width; - rect[3] = dsw->sw.area_height; - } - - XtVaSetValues(w, XtNdirtyAreas, rect, XtNnumDirtyAreas, n, NULL); -} - -void DSWAddToDirtyArea( - Widget w, - float *rect, - long n) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.add_to_dirty_area) (w, rect, n); -} - -static Boolean TakeFeedbackPixmap( - Widget w, - Pixmap *p, - int *width, int *height, int *depth, - Screen **screen) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if (dsw->sw.doing_feedback) return False; - - *p = dsw->sw.feedback_pixmap; - if (*p == None) { - *width = *height = *depth; - *screen = NULL; - return True; - } - - *width = dsw->sw.feedback_width; - *height = dsw->sw.feedback_height; - *depth = dsw->sw.drawing_area->core.depth; - *screen = dsw->core.screen; - - dsw->sw.feedback_pixmap = None; - dsw->sw.feedback_width = dsw->sw.feedback_height = 0; - return True; -} - -Boolean DSWTakeFeedbackPixmap( - Widget w, - Pixmap *p, - int *width, int *height, int *depth, - Screen **screen) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - return (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.take_feedback_pixmap) (w, p, width, height, - depth, screen); -} - -static void StartFeedbackDrawing( - Widget w, - XtPointer start_feedback_data) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - float *r; - - FinishDrawing(dsw); - CheckFeedbackPixmap(dsw); - if (dsw->sw.feedback_pixmap != None) { - /* Initialize the feedback pixmap with a copy of the drawing */ - GrowRectList(&dsw->sw.prev_dirty_areas, &dsw->sw.prev_dirty_areas_size, - 0, 1, 1); - r = dsw->sw.prev_dirty_areas; - ConvertToPS(dsw, 0 + DELTA, dsw->sw.drawing_area->core.height - DELTA, - r, r+1); - ConvertToPS(dsw, dsw->sw.drawing_area->core.width - DELTA, 0 + DELTA, - r+2, r+3); - r[2] -= r[0]; - r[3] -= r[1]; - dsw->sw.num_prev_dirty_areas = 1; - - if (dsw->sw.backing_pixmap != None) { - CopyToFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - (void) ClipAndDraw(dsw, DSWFeedbackPixmap, DSWFinish, True); - } - } - dsw->sw.num_prev_dirty_areas = 0; - dsw->sw.doing_feedback = True; - dsw->sw.start_feedback_data = start_feedback_data; -} - -void DSWStartFeedbackDrawing( - Widget w, - XtPointer start_feedback_data) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.start_feedback_drawing) (w, start_feedback_data); -} - -static void EndFeedbackDrawing( - Widget w, - int restore) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if (restore) { - if (dsw->sw.backing_pixmap != None) { - UpdateWindowFromBackingPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - (void) ClipAndDraw(dsw, DSWWindow, DSWFinish, True); - } - } - if (dsw->sw.feedback_gstate != 0) { - XDPSFreeContextGState(dsw->sw.context, dsw->sw.feedback_gstate); - } - dsw->sw.doing_feedback = dsw->sw.feedback_displayed = False; -} - -void DSWEndFeedbackDrawing( - Widget w, - Bool restore) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.end_feedback_drawing) (w, restore); -} - -static void SetFeedbackDirtyArea( - Widget w, - float *rects, - int count, - XtPointer continue_feedback_data) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - int i; - float *r; - - for (i = 0; i < count; i++) { - r = rects + (i * 4); - if (WIDTH(r) < 0) { - LEFT(r) += WIDTH(r); - WIDTH(r) = -WIDTH(r); - } - if (HEIGHT(r) < 0) { - BOTTOM(r) += HEIGHT(r); - HEIGHT(r) = -HEIGHT(r); - } - } - - if (dsw->sw.backing_pixmap != None) { - if (dsw->sw.feedback_pixmap != None) { - CopyToFeedbackPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } else { - UpdateWindowFromBackingPixmap(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - } - } else { - CopyRectsToCurrentDrawing(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - (void) ClipAndDraw(dsw, (dsw->sw.feedback_pixmap == None ? - DSWWindow : DSWFeedbackPixmap), - DSWFinish, True); - } - dsw->sw.continue_feedback_data = continue_feedback_data; - CallFeedbackCallback(dsw, rects, count); - - if (dsw->sw.feedback_pixmap != None) { - CopyRectsToDirtyArea(dsw, dsw->sw.prev_dirty_areas, - dsw->sw.num_prev_dirty_areas); - AddRectsToDirtyArea(dsw, rects, count); - SimplifyRects(dsw->sw.dirty_areas, &dsw->sw.num_dirty_areas); - UpdateWindowFromFeedbackPixmap(dsw, dsw->sw.dirty_areas, - dsw->sw.num_dirty_areas); - dsw->sw.num_dirty_areas = 0; - } - CopyRectsToPrevDirtyArea(dsw, rects, count); - dsw->sw.feedback_displayed = True; -} - -void DSWSetFeedbackDirtyArea( - Widget w, - float *rects, - int count, - XtPointer continue_feedback_data) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.set_feedback_dirty_area) (w, rects, count, - continue_feedback_data); -} - -static void FinishPendingDrawing(Widget w) -{ - FinishDrawing((DPSScrolledWindowWidget) w); -} - -void DSWFinishPendingDrawing(Widget w) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.finish_pending_drawing) (w); -} - -static void AbortPendingDrawing(Widget w) -{ - AbortDrawing((DPSScrolledWindowWidget) w); -} - -void DSWAbortPendingDrawing(Widget w) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.abort_pending_drawing) (w); -} - -static void UpdateDrawing( - Widget w, - float *rects, - int count) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - int i; - float *r; - int llx, lly, urx, ury; - int dx, dy; - - if (dsw->sw.backing_pixmap == None) { - AddToDirtyArea(w, rects, count); - return; - } - - ComputeOffsets(dsw, &dx, &dy); - - for (i = 0; i < count; i++) { - r = rects + (i * 4); - ConvertToX(dsw, LEFT(r), BOTTOM(r), &llx, &lly); - ConvertToX(dsw, RIGHT(r), TOP(r), &urx, &ury); - XCopyArea(XtDisplay(dsw), XtWindow(dsw->sw.drawing_area), - dsw->sw.backing_pixmap, dsw->sw.no_ge_gc, - llx-1, ury-1, urx-llx+2, lly-ury+2, llx+dx-1, ury+dy-1); - } -} - -void DSWUpdateDrawing( - Widget w, - float *rects, - int count) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.update_drawing) (w, rects, count); -} - -static void GetScrollInfo( - Widget w, - int *h_value, int *h_size, int *h_max, int *v_value, int *v_size, int *v_max) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if (h_value != NULL) *h_value = dsw->sw.scroll_h_value; - if (h_size != NULL) *h_size = dsw->sw.scroll_h_size; - if (h_max != NULL) *h_max = dsw->sw.scroll_h_max; - if (v_value != NULL) *v_value = dsw->sw.scroll_v_value; - if (v_size != NULL) *v_size = dsw->sw.scroll_v_size; - if (v_max != NULL) *v_max = dsw->sw.scroll_v_max; -} - -void DSWGetScrollInfo( - Widget w, - int *h_value, int *h_size, int *h_max, int *v_value, int *v_size, int *v_max) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.get_scroll_info) (w, h_value, h_size, h_max, - v_value, v_size, v_max); -} - -static void GetDrawingInfo( - Widget w, - DSWDrawableType *type, - Drawable *drawable, - DPSGState *gstate, - DPSContext *context) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if (dsw->sw.backing_pixmap != None) { - *type = DSWBackingPixmap; - *drawable = dsw->sw.backing_pixmap; - *gstate = dsw->sw.backing_gstate; - } else { - *type = DSWWindow; - *drawable = XtWindow(dsw->sw.drawing_area); - *gstate = dsw->sw.window_gstate; - } - *context = dsw->sw.context; -} - -void DSWGetDrawingInfo( - Widget w, - DSWDrawableType *type, - Drawable *drawable, - DPSGState *gstate, - DPSContext *context) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.get_drawing_info) (w, type, drawable, gstate, context); -} - -static Boolean GiveFeedbackPixmap( - Widget w, - Pixmap p, - int width, int height, int depth, - Screen *screen) -{ - DPSScrolledWindowWidget dsw = (DPSScrolledWindowWidget) w; - - if ((unsigned) depth != dsw->sw.drawing_area->core.depth - || screen != dsw->core.screen - || dsw->sw.feedback_pixmap != None) return False; - - dsw->sw.feedback_pixmap = p; - dsw->sw.feedback_width = width; - dsw->sw.feedback_height = height; - - return True; -} - -Boolean DSWGiveFeedbackPixmap( - Widget w, - Pixmap p, - int width, int height, int depth, - Screen *screen) -{ - XtCheckSubclass(w, dpsScrolledWindowWidgetClass, NULL); - - return (*((DPSScrolledWindowWidgetClass) XtClass(w))-> - sw_class.give_feedback_pixmap) (w, p, width, height, - depth, screen); -} - -static void ConvertToX( - DPSScrolledWindowWidget dsw, - float psX, - float psY, - int *xX, - int *xY) -{ - *xX = dsw->sw.ctm[0] * psX + dsw->sw.ctm[2] * psY + dsw->sw.ctm[4] + - dsw->sw.x_offset + 0.5; - *xY = dsw->sw.ctm[1] * psX + dsw->sw.ctm[3] * psY + dsw->sw.ctm[5] + - dsw->sw.y_offset + 0.5; -} - -static void ConvertToPS( - DPSScrolledWindowWidget dsw, - float xX, float xY, - float *psX, float *psY) -{ - xX -= dsw->sw.x_offset; - xY -= dsw->sw.y_offset; - - *psX = dsw->sw.inv_ctm[0] * xX + dsw->sw.inv_ctm[2] * xY + - dsw->sw.inv_ctm[4]; - *psY = dsw->sw.inv_ctm[1] * xX + dsw->sw.inv_ctm[3] * xY + - dsw->sw.inv_ctm[5]; -} - -static void ConvertToOrigPS( - DPSScrolledWindowWidget dsw, - int xX, int xY, - float *psX, float *psY) -{ - xX -= dsw->sw.x_offset; - xY -= dsw->sw.y_offset; - - *psX = dsw->sw.orig_inv_ctm[0] * xX + dsw->sw.orig_inv_ctm[2] * xY + - dsw->sw.orig_inv_ctm[4]; - *psY = dsw->sw.orig_inv_ctm[1] * xX + dsw->sw.orig_inv_ctm[3] * xY + - dsw->sw.orig_inv_ctm[5]; -} |