home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- /*
- scroll.c --- managing the scrolled area
- Created: Jamie Zawinski <jwz@netscape.com>, 23-Jul-94.
- */
-
-
- #include "mozilla.h"
- #include "xfe.h"
- #include "scroller.h"
- #include "scrollerP.h"
- #include "new_manage.h"
- #include "new_manageP.h"
-
- /* for XP_GetString() */
- #include <xpgetstr.h>
-
- extern int XFE_SCROLL_WINDOW_GRAVITY_WARNING;
-
- /* C entry point to XFE_HTMLDrag class in xfe/src/HTMLDrag.cpp */
- extern void XFE_HTMLDragCreate(Widget,MWContext*);
-
- #ifdef EDITOR
- #include "xeditor.h"
- extern void fe_EditorReload(MWContext* context, Boolean super_reload);
- #endif /*EDITOR*/
-
- /* Layering support - LO_RefreshArea is called through compositor */
- #include "layers.h"
-
- void fe_find_scrollbar_sizes(MWContext *context); /* in xfe.h */
-
- static void fe_expose_eh (Widget, XtPointer, XEvent *);
- /* static void fe_expose_cb (Widget, XtPointer, XtPointer); */
- static void fe_scroll_cb (Widget, XtPointer, XtPointer);
-
- #ifdef RESIZE_CALLBACK_WORKS
- static void fe_resize_cb (Widget, XtPointer, XtPointer);
- #else
- static void fe_scroller_resize (Widget, XtPointer);
- #endif
-
- static void guffaw (MWContext *context);
- static void unguffaw (MWContext *context);
-
- void
- fe_InitScrolling (MWContext *context)
- {
- if (CONTEXT_DATA (context)->drawing_area == NULL) return;
- /*
- * Guffaws has 3 states now. If 0 it is just off. If 1 it uses
- * static gravity, if 2 it uses a combination of N, S, E, W gravities.
- * Any method that uses gravity needs the configure handler. Only
- * static uses the guffaw function.
- */
- if (fe_globalData.fe_guffaw_scroll > 0)
- {
- XtAddEventHandler (CONTEXT_DATA (context)->drawing_area,
- StructureNotifyMask, FALSE,
- (XtEventHandler)fe_config_eh, context);
- }
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- guffaw (context);
- }
- fe_NukeBackingStore (CONTEXT_DATA (context)->drawing_area);
- }
-
-
- /*
- * Reverse the actions of fe_InitScrolling(). For when a normal
- * document context is turned into a FRAME parent context.
- */
- void
- fe_DisableScrolling (MWContext *context)
- {
- if (CONTEXT_DATA (context)->drawing_area == NULL) return;
- /*
- * Turn off guffaws for a context's drawing area.
- */
- if (fe_globalData.fe_guffaw_scroll > 0)
- {
- XtRemoveEventHandler (CONTEXT_DATA (context)->drawing_area,
- StructureNotifyMask, FALSE,
- (XtEventHandler)fe_config_eh, context);
- }
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- unguffaw (context);
- }
- }
-
-
- Widget
- fe_MakeScrolledWindow (MWContext *context, Widget parent, const char *name)
- {
- Widget scroller, drawing_area, hscroll, vscroll;
- Arg av [20];
- int ac = 0;
-
- ac = 0;
- XtSetArg (av[ac], XmNscrollingPolicy, XmAPPLICATION_DEFINED); ac++;
- /* The background of this widget is the color that shows up in the square
- at the bottom right where the horizontal and vertical scrollbars come
- together, and of the "pad" border between the scrollbars and the document
- area (which we'd like to be of size 0, see below.) This should be in the
- background color of the widgets, not the background color of the document.
- */
- XtSetArg (av[ac], XmNbackground, parent->core.background_pixel); ac++;
- /* scroller = XmCreateScrolledWindow (parent, name, av, ac);*/
- scroller = XtCreateWidget((char *) name, scrollerClass, parent, av, ac);
- #ifndef RESIZE_CALLBACK_WORKS
- ((Scroller) scroller)->scroller.resize_arg = (void *) context;
- ((Scroller) scroller)->scroller.resize_hook = fe_scroller_resize;
- #endif
-
- /* This is a kludge - there ought to be a resource to control this, but
- I can't find it. This controls the extra space between the scrollbars
- and the area being scrolled. If this isn't 0, then there's a 4-pixel
- border between the document background and the scrollbar, which ends
- up in the user's background instead, which looks stupid.
- */
- ((Scroller) scroller)->swindow.pad = 0;
-
- ac = 0;
- XtSetArg (av[ac], XmNminimum, 0); ac++;
- XtSetArg (av[ac], XmNmaximum, 1); ac++;
- XtSetArg (av[ac], XmNorientation, XmHORIZONTAL); ac++;
- hscroll = XmCreateScrollBar (scroller, "hscroll", av, ac);
- ac = 0;
- XtSetArg (av[ac], XmNminimum, 0); ac++;
- XtSetArg (av[ac], XmNmaximum, 1); ac++;
- XtSetArg (av[ac], XmNorientation, XmVERTICAL); ac++;
- vscroll = XmCreateScrollBar (scroller, "vscroll", av, ac);
- ac = 0;
-
- /* The drawing area we're about to create is the actual document window,
- so its background should be the document background pixel. */
- XtSetArg (av[ac], XmNbackground,
- CONTEXT_DATA (context)->default_bg_pixel); ac++;
- /*
- XtSetArg (av[ac], XmNautoUnmanage, FALSE); ac++;
- XtSetArg (av[ac], XmNdefaultPosition, FALSE); ac++;
- XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_WORK_AREA); ac++;
- XtSetArg (av[ac], XmNmarginHeight, 0); ac++;
- XtSetArg (av[ac], XmNmarginWidth, 0); ac++;
- */
- #ifdef EDITOR
- if (EDT_IS_EDITOR(context)) {
- /* Let's try using the managed widget */
- drawing_area = XtCreateWidget("editorDrawingArea", newManageClass,
- scroller, av, ac);
- }
- else
- #endif /* EDITOR */
- drawing_area = XtCreateWidget("drawingArea", newManageClass, scroller, av, ac);
-
- /*
- drawing_area = XtCreateWidget("drawingArea", xmManagerWidgetClass, scroller, av, ac);
- drawing_area = XtCreateWidget("drawingArea", xmBulletinBoardWidgetClass, scroller, av, ac);
- */
- /* XtAddCallback (drawing_area, XmNexposeCallback, fe_expose_cb, context); */
- XtAddEventHandler(drawing_area, ExposureMask, FALSE,
- (XtEventHandler)fe_expose_eh, context);
- /* This is now added later in xfe.c, because we don't know fe_guffaw_scroll
- * yet.
- if (fe_globalData.fe_guffaw_scroll)
- {
- XtAddEventHandler(drawing_area, StructureNotifyMask, FALSE,
- (XtEventHandler)fe_config_eh, context);
- }
- */
- #ifdef RESIZE_CALLBACK_WORKS
- XtAddCallback (drawing_area, XmNresizeCallback, fe_resize_cb, context);
- #endif
-
- XtManageChild (drawing_area);
- SCROLLER_SET_AREAS (scroller, hscroll, vscroll, drawing_area);
-
- XtAddCallback (hscroll, XmNvalueChangedCallback, fe_scroll_cb, context);
- XtAddCallback (vscroll, XmNvalueChangedCallback, fe_scroll_cb, context);
- XtAddCallback (hscroll, XmNdragCallback, fe_scroll_cb, context);
- XtAddCallback (vscroll, XmNdragCallback, fe_scroll_cb, context);
-
- CONTEXT_DATA (context)->scrolled = scroller;
- CONTEXT_DATA (context)->drawing_area = drawing_area;
- CONTEXT_DATA (context)->hscroll = hscroll;
- CONTEXT_DATA (context)->vscroll = vscroll;
-
- XtManageChild (hscroll);
- XtManageChild (vscroll);
-
- /* add drag source via C API */
- XFE_HTMLDragCreate(drawing_area,context);
-
- return scroller;
- }
-
- static void
- guffaw (MWContext *context)
- {
- Widget widget = CONTEXT_DATA (context)->drawing_area;
- XSetWindowAttributes attr;
- unsigned long valuemask;
- valuemask = CWBitGravity | CWWinGravity;
- attr.win_gravity = StaticGravity;
- attr.bit_gravity = StaticGravity;
- if (! XtWindow (widget)) abort ();
- XChangeWindowAttributes (XtDisplay (widget), XtWindow (widget),
- valuemask, &attr);
- }
-
- static void
- unguffaw (MWContext *context)
- {
- Widget widget = CONTEXT_DATA (context)->drawing_area;
- XSetWindowAttributes attr;
- unsigned long valuemask;
- valuemask = CWBitGravity | CWWinGravity;
- attr.win_gravity = NorthWestGravity;
- attr.bit_gravity = NorthWestGravity;
- if (! XtWindow (widget)) abort ();
- XChangeWindowAttributes (XtDisplay (widget), XtWindow (widget),
- valuemask, &attr);
- }
-
- /*
- * Toggle on and off the bit and window gravity effects
- * of guffaws scrolling.
- */
- void
- fe_SetGuffaw(MWContext *context, Boolean on)
- {
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- if (on)
- guffaw (context);
- else
- unguffaw (context);
- }
- }
-
- static void
- fe_scroll_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- MWContext *context = (MWContext *) closure;
- XmScrollBarCallbackStruct *cb = (XmScrollBarCallbackStruct *) call_data;
- Widget da = CONTEXT_DATA (context)->drawing_area;
- int scroll_slop_hack =
- ((Scroller) CONTEXT_DATA (context)->scrolled)->swindow.pad;
- unsigned long lh = CONTEXT_DATA (context)->line_height;
- unsigned long old_x = CONTEXT_DATA (context)->document_x;
- unsigned long old_y = CONTEXT_DATA (context)->document_y;
- unsigned long new_x = old_x;
- unsigned long new_y = old_y;
- Dimension w = 0, h = 0;
- Boolean horiz_p;
- XGCValues gcv;
- GC gc;
-
- fe_UserActivity (context);
- if (widget == CONTEXT_DATA (context)->hscroll)
- new_x = cb->value;
- else if (widget == CONTEXT_DATA (context)->vscroll)
- new_y = cb->value;
- else
- abort ();
- horiz_p = (new_x != old_x);
-
- fe_SetDocPosition (context, new_x, new_y);
-
- /* XtVaGetValues (da, XmNwidth, &w, XmNheight, &h, 0); */
- w = da->core.width;
- h = da->core.height;
-
- memset (&gcv, ~0, sizeof (gcv));
- gcv.function = GXcopy;
- gc = fe_GetGC (da, GCFunction, &gcv);
-
- if (horiz_p)
- {
- if (new_x >= old_x)
- {
- int shift = (new_x - old_x);
- int sb_w = CONTEXT_DATA (context)->sb_w;
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- XResizeWindow(XtDisplay(da), XtWindow(da),
- (w + shift + scroll_slop_hack), h);
- XMoveWindow(XtDisplay(da), XtWindow(da), (x - shift), y);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da), x, y, w, h);
- fe_GravityCorrectForms (context, -shift, 0);
- }
- else if (fe_globalData.fe_guffaw_scroll == 2)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- fe_SetFormsGravity(context, WestGravity);
- XResizeWindow(XtDisplay(da), XtWindow(da),
- (w + shift), h);
- XMoveWindow(XtDisplay(da), XtWindow(da), (x - shift), y);
- fe_SetFormsGravity(context, EastGravity);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da), x, y, w, h);
- fe_SetFormsGravity(context, NorthWestGravity);
- fe_GravityCorrectForms (context, -shift, 0);
- }
- else
- {
- XCopyArea (XtDisplay (da), XtWindow (da), XtWindow (da), gc,
- shift, 0,
- w - shift, h,
- 0, 0);
- fe_ScrollForms (context, old_x - new_x, old_y - new_y);
- fe_RefreshArea (context,
- new_x + w - (shift+lh+lh),
- new_y, shift+lh, h);
- }
- if (shift > w)
- {
- shift = w;
- }
-
- #ifdef DONT_rhess
- /*
- * NOTE: we always need to refresh the delta of the scrolled area...
- * [ bug: improper redisplay during scrolling ]
- */
-
- if (fe_globalData.fe_guffaw_scroll == 0)
- #endif
- fe_RefreshArea (context,
- new_x + w - sb_w - shift,
- new_y, shift + sb_w, h);
- }
- else
- {
- int shift = (old_x - new_x);
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da),
- (x - shift), y, (w + shift), h);
- XResizeWindow(XtDisplay(da), XtWindow(da), w, h);
- XMoveWindow(XtDisplay(da), XtWindow(da), x, y);
- fe_GravityCorrectForms (context, shift, 0);
- }
- else if (fe_globalData.fe_guffaw_scroll == 2)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- fe_SetFormsGravity(context, EastGravity);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da),
- (x - shift), y, (w + shift), h);
- fe_SetFormsGravity(context, WestGravity);
- XResizeWindow(XtDisplay(da), XtWindow(da), w, h);
- XMoveWindow(XtDisplay(da), XtWindow(da), x, y);
- fe_SetFormsGravity(context, NorthWestGravity);
- fe_GravityCorrectForms (context, shift, 0);
- }
- else
- {
- XCopyArea (XtDisplay (da), XtWindow (da), XtWindow (da), gc,
- 0, 0,
- w - (old_x - new_x), h,
- (old_x - new_x), 0);
- fe_ScrollForms (context, old_x - new_x, old_y - new_y);
- }
- if (shift > w)
- {
- shift = w;
- }
-
- #ifdef DONT_rhess
- if (fe_globalData.fe_guffaw_scroll == 0)
- #endif
- fe_RefreshArea (context, new_x, new_y, shift, h);
- }
- }
- else
- {
- if (new_y >= old_y)
- {
- int shift = (new_y - old_y);
- int sb_h = CONTEXT_DATA (context)->sb_h;
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- XResizeWindow(XtDisplay(da), XtWindow(da), w,
- (h + shift + scroll_slop_hack));
- XMoveWindow(XtDisplay(da), XtWindow(da), x, (y - shift));
- XMoveResizeWindow(XtDisplay(da), XtWindow(da), x, y, w, h);
- fe_GravityCorrectForms (context, 0, -shift);
- }
- else if (fe_globalData.fe_guffaw_scroll == 2)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- fe_SetFormsGravity(context, NorthGravity);
- XResizeWindow(XtDisplay(da), XtWindow(da), w,
- (h + shift));
- XMoveWindow(XtDisplay(da), XtWindow(da), x, (y - shift));
- fe_SetFormsGravity(context, SouthGravity);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da), x, y, w, h);
- fe_SetFormsGravity(context, NorthWestGravity);
- fe_GravityCorrectForms (context, 0, -shift);
- }
- else
- {
- XCopyArea (XtDisplay (da), XtWindow (da), XtWindow (da), gc,
- 0, shift,
- w, h - shift,
- 0, 0);
- fe_ScrollForms (context, old_x - new_x, old_y - new_y);
- }
- if (shift > h)
- {
- shift = h;
- }
-
- #ifdef DONT_rhess
- if (fe_globalData.fe_guffaw_scroll == 0)
- #endif
- fe_RefreshArea (context, new_x, new_y + h - sb_h - shift,
- w, shift + sb_h);
- }
- else
- {
- int shift = (old_y - new_y);
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da),
- x, (y - shift), w, (h + shift));
- XResizeWindow(XtDisplay(da), XtWindow(da), w, h);
- XMoveWindow(XtDisplay(da), XtWindow(da), x, y);
- fe_GravityCorrectForms (context, 0, shift);
- }
- else if (fe_globalData.fe_guffaw_scroll == 2)
- {
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
-
- XGetGeometry(XtDisplay(da), XtWindow(da), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- fe_SetFormsGravity(context, SouthGravity);
- XMoveResizeWindow(XtDisplay(da), XtWindow(da),
- x, (y - shift), w, (h + shift));
- fe_SetFormsGravity(context, NorthGravity);
- XResizeWindow(XtDisplay(da), XtWindow(da), w, h);
- XMoveWindow(XtDisplay(da), XtWindow(da), x, y);
- fe_SetFormsGravity(context, NorthWestGravity);
- fe_GravityCorrectForms (context, 0, shift);
- }
- else
- {
- XCopyArea (XtDisplay (da), XtWindow (da), XtWindow (da), gc,
- 0, 0,
- w, h - (old_y - new_y),
- 0, (old_y - new_y));
- fe_ScrollForms (context, old_x - new_x, old_y - new_y);
- }
- if (shift > h)
- {
- shift = h;
- }
-
- #ifdef DONT_rhess
- if (fe_globalData.fe_guffaw_scroll == 0)
- #endif
- fe_RefreshArea (context, new_x, new_y, w, shift);
- }
- }
-
- #ifdef PERFECT_SCROLL
- /*
- * In any X scrolling, there is the possibility of getting multiple
- * scrolling events before any of the exposure events they
- * generate appear. The results in improperly placed
- * exposures because the values fo document_x and document_y in the
- * context are different at the time the exposure is processed than
- * they were at the time the exposure was created.
- * The followind code elminates this. It first flushes all exposures
- * generated by this scroll event, and then removes all motion events
- * That might potentially cause another scroll to get processed before
- * these exposures. Throwing out these extra motions in theory makes
- * scrolling a little more jerky. In practice I notice no difference.
- */
- XSync(XtDisplay(widget), FALSE);
- if (cb->event)
- {
- XEvent new_event;
- while (XCheckTypedWindowEvent(XtDisplay(widget), XtWindow(widget),
- MotionNotify, &new_event) == TRUE);
- }
- #endif /* PERFECT_SCROLL */
- }
-
- void
- fe_ScrollTo (MWContext *context, unsigned long x, unsigned long y)
- {
- if (x != CONTEXT_DATA (context)->document_x)
- {
- XmScrollBarCallbackStruct cb;
- {
- int nx = x;
- int max = 0;
- int size = 0;
- XtVaGetValues (CONTEXT_DATA (context)->hscroll,
- XmNmaximum, &max, XmNsliderSize, &size, 0);
- if (nx > max - size) nx = max - size;
- if (nx < 0) nx = 0;
- XtVaSetValues (CONTEXT_DATA (context)->hscroll, XmNvalue, nx, 0);
- x = nx;
- }
- memset (&cb, 0, sizeof (cb));
- cb.value = x;
- fe_scroll_cb (CONTEXT_DATA (context)->hscroll,
- (XtPointer)context, (XtPointer)&cb);
- }
- if (y != CONTEXT_DATA (context)->document_y)
- {
- XmScrollBarCallbackStruct cb;
- {
- int ny = y;
- int max = 0;
- int size = 0;
- XtVaGetValues (CONTEXT_DATA (context)->vscroll,
- XmNmaximum, &max, XmNsliderSize, &size, 0);
- if (ny > max - size) ny = max - size;
- if (ny < 0) ny = 0;
- XtVaSetValues (CONTEXT_DATA (context)->vscroll, XmNvalue, ny, 0);
- y = ny;
- }
- memset (&cb, 0, sizeof (cb));
- cb.value = y;
- fe_scroll_cb (CONTEXT_DATA (context)->vscroll,
- (XtPointer)context, (XtPointer)&cb);
- }
- }
-
-
- /*
- * When scrolling by moving the window, some expose events are generated
- * when the window is NOT at 0,0 which need to be translated to 0,0
- * when those exposes are processed. We can locate these exposes because the
- * will have the same serial number as the configure that created them.
- * Thus we need to save that serial number and offset here.
- */
- void
- fe_config_eh (Widget widget, XtPointer closure, XEvent *event)
- {
- MWContext *context = (MWContext *) closure;
- XConfigureEvent *ce = (XConfigureEvent *) event;
-
- if (ce->type != ConfigureNotify)
- {
- return;
- }
-
- CONTEXT_DATA (context)->expose_x_offset = ce->x;
- CONTEXT_DATA (context)->expose_y_offset = ce->y;
- CONTEXT_DATA (context)->expose_serial = ce->serial;
- }
-
-
- static void
- fe_expose_eh (Widget widget, XtPointer closure, XEvent *event)
- {
- MWContext *context = (MWContext *) closure;
- XExposeEvent *ee = (XExposeEvent *) event;
- int scroll_slop_hack =
- ((Scroller) CONTEXT_DATA (context)->scrolled)->swindow.pad;
-
- if (fe_globalData.fe_guffaw_scroll)
- {
- int new_x, new_y;
- unsigned int new_width, new_height;
-
- new_x = ee->x;
- new_y = ee->y;
- new_width = ee->width;
- new_height = ee->height;
-
- /*
- * If this expose event has the same serial number as a configure
- * event that moved the window away from 0,0 we need to adjust the x,y of
- * this expose event to be in the proper location with respect to
- * its parent.
- */
- if ((CONTEXT_DATA (context)->expose_x_offset != 0)||
- (CONTEXT_DATA (context)->expose_y_offset != 0))
- {
- if (ee->serial == CONTEXT_DATA (context)->expose_serial)
- {
- new_x += CONTEXT_DATA (context)->expose_x_offset;
- new_y += CONTEXT_DATA (context)->expose_y_offset;
-
- /*
- * Correct for the presence of a horizontal or
- * vertical scrollbar.
- */
- if (CONTEXT_DATA (context)->expose_y_offset < 0)
- {
- new_y -= scroll_slop_hack;
- new_height += scroll_slop_hack;
- }
- if (CONTEXT_DATA (context)->expose_x_offset < 0)
- {
- new_x -= scroll_slop_hack;
- new_width += scroll_slop_hack;
- }
- }
- }
-
- /*
- * Because we are scrolling a window that may have many small child
- * widgets, we want to compress the many small exposes that happen around
- * those widgets. We don't want to compress discontinuous regions
- * that happened to be exposed at the same time.
- * We want to compress:
- *
- * ----- ---------
- * | |------ and | |
- * | || | ---------
- * -----| | ---------
- * ------ | |
- * ---------
- *
- * NOT
- *
- * -----
- * | |
- * -----
- *
- * -----
- * | |
- * -----
- */
-
- /*
- * Non-zero counts are parts of multi-expose blocks, and might be
- * held for later compression.
- */
- if (ee->count != 0)
- {
- /*
- * If nothng held so far, just hold this one.
- */
- if (CONTEXT_DATA (context)->held_expose == FALSE)
- {
- CONTEXT_DATA (context)->held_expose = TRUE;
- CONTEXT_DATA (context)->expose_x1 = new_x;
- CONTEXT_DATA (context)->expose_y1 = new_y;
- CONTEXT_DATA (context)->expose_x2 = new_x + new_width;
- CONTEXT_DATA (context)->expose_y2 = new_y + new_height;
- }
- else
- {
- /*
- * If we are adjacent to the held block, compress them together
- */
- if ((((new_y - 1) >= CONTEXT_DATA (context)->expose_y1)&&
- ((new_y - 1) <= CONTEXT_DATA (context)->expose_y2))||
- (((new_y + new_height + 1) >= CONTEXT_DATA (context)->expose_y1)&&
- ((new_y + new_height + 1) <= CONTEXT_DATA (context)->expose_y2))||
- ((CONTEXT_DATA (context)->expose_y1 >= (new_y - 1))&&
- (CONTEXT_DATA (context)->expose_y1 <= (new_y + new_height + 1))))
- {
- if (new_x < CONTEXT_DATA (context)->expose_x1)
- CONTEXT_DATA (context)->expose_x1 = new_x;
- if (new_y < CONTEXT_DATA (context)->expose_y1)
- CONTEXT_DATA (context)->expose_y1 = new_y;
- if ((new_x + (int)new_width) > CONTEXT_DATA (context)->expose_x2)
- CONTEXT_DATA (context)->expose_x2 = new_x + (int)new_width;
- if ((new_y + (int)new_height) > CONTEXT_DATA (context)->expose_y2)
- CONTEXT_DATA (context)->expose_y2 = new_y + (int)new_height;
- }
- /*
- * We weren't adjacent. Display the held block, and hold
- * the new one.
- */
- else
- {
- unsigned int hold_width, hold_height;
-
- if (CONTEXT_DATA (context)->expose_x2
- > CONTEXT_DATA (context)->scrolled_width)
- CONTEXT_DATA (context)->expose_x2
- = CONTEXT_DATA (context)->scrolled_width;
- if (CONTEXT_DATA (context)->expose_y2
- > CONTEXT_DATA (context)->scrolled_height)
- CONTEXT_DATA (context)->expose_y2
- = CONTEXT_DATA (context)->scrolled_height;
- hold_width = (CONTEXT_DATA (context)->expose_x2 -
- CONTEXT_DATA (context)->expose_x1);
- hold_height = (CONTEXT_DATA (context)->expose_y2 -
- CONTEXT_DATA (context)->expose_y1);
- if (hold_width < 1)
- hold_width = 1;
- if (hold_height < 1)
- hold_height = 1;
-
-
- fe_RefreshArea (context,
- (CONTEXT_DATA (context)->expose_x1 +
- CONTEXT_DATA (context)->document_x),
- (CONTEXT_DATA (context)->expose_y1 +
- CONTEXT_DATA (context)->document_y),
- hold_width, hold_height);
- CONTEXT_DATA (context)->expose_x1 = new_x;
- CONTEXT_DATA (context)->expose_y1 = new_y;
- CONTEXT_DATA (context)->expose_x2 = new_x + new_width;
- CONTEXT_DATA (context)->expose_y2 = new_y + new_height;
- }
- }
- }
- /*
- * count = 0 is either a standalone expose, or part of a multipart
- * expose.
- */
- else
- {
- /*
- * If nothing held this is just a standalone expose, display it.
- */
- if (CONTEXT_DATA (context)->held_expose == FALSE)
- {
- if ((new_x + new_width) > CONTEXT_DATA (context)->scrolled_width)
- new_width = CONTEXT_DATA (context)->scrolled_width - new_x;
- if ((new_y + new_height) > CONTEXT_DATA (context)->scrolled_height)
- new_height = CONTEXT_DATA (context)->scrolled_height - new_y;
- if (new_width < 1)
- new_width = 1;
- if (new_height < 1)
- new_height = 1;
-
- fe_RefreshArea (context,
- new_x + CONTEXT_DATA (context)->document_x,
- new_y + CONTEXT_DATA (context)->document_y,
- new_width, new_height);
- }
- else
- {
- CONTEXT_DATA (context)->held_expose = FALSE;
- /*
- * If we are adjacent to the held block, compress them together
- * and display the combined chunk.
- */
- if ((((new_y - 1) >= CONTEXT_DATA (context)->expose_y1)&&
- ((new_y - 1) <= CONTEXT_DATA (context)->expose_y2))||
- (((new_y + new_height + 1) >= CONTEXT_DATA (context)->expose_y1)&&
- ((new_y + new_height + 1) <= CONTEXT_DATA (context)->expose_y2))||
- ((CONTEXT_DATA (context)->expose_y1 >= (new_y - 1))&&
- (CONTEXT_DATA (context)->expose_y1 <= (new_y + new_height + 1))))
- {
- if (new_x < CONTEXT_DATA (context)->expose_x1)
- CONTEXT_DATA (context)->expose_x1 = new_x;
- if (new_y < CONTEXT_DATA (context)->expose_y1)
- CONTEXT_DATA (context)->expose_y1 = new_y;
- if ((new_x + new_width) > CONTEXT_DATA (context)->expose_x2)
- CONTEXT_DATA (context)->expose_x2 = new_x + new_width;
- if ((new_y + new_height) > CONTEXT_DATA (context)->expose_y2)
- CONTEXT_DATA (context)->expose_y2 = new_y + new_height;
-
- if (CONTEXT_DATA (context)->expose_x2
- > CONTEXT_DATA (context)->scrolled_width)
- CONTEXT_DATA (context)->expose_x2
- = CONTEXT_DATA (context)->scrolled_width;
- if (CONTEXT_DATA (context)->expose_y2
- > CONTEXT_DATA (context)->scrolled_height)
- CONTEXT_DATA (context)->expose_y2
- = CONTEXT_DATA (context)->scrolled_height;
- new_width = (CONTEXT_DATA (context)->expose_x2 -
- CONTEXT_DATA (context)->expose_x1);
- new_height = (CONTEXT_DATA (context)->expose_y2 -
- CONTEXT_DATA (context)->expose_y1);
- if (new_width < 1)
- new_width = 1;
- if (new_height < 1)
- new_height = 1;
-
- fe_RefreshArea (context,
- (CONTEXT_DATA (context)->expose_x1 +
- CONTEXT_DATA (context)->document_x),
- (CONTEXT_DATA (context)->expose_y1 +
- CONTEXT_DATA (context)->document_y),
- new_width, new_height);
- }
- /*
- * Else display the held block and this expose separately.
- */
- else
- {
- unsigned int hold_width, hold_height;
-
- if (CONTEXT_DATA (context)->expose_x2
- > CONTEXT_DATA (context)->scrolled_width)
- CONTEXT_DATA (context)->expose_x2
- = CONTEXT_DATA (context)->scrolled_width;
- if (CONTEXT_DATA (context)->expose_y2
- > CONTEXT_DATA (context)->scrolled_height)
- CONTEXT_DATA (context)->expose_y2
- = CONTEXT_DATA (context)->scrolled_height;
- hold_width = (CONTEXT_DATA (context)->expose_x2 -
- CONTEXT_DATA (context)->expose_x1);
- hold_height = (CONTEXT_DATA (context)->expose_y2 -
- CONTEXT_DATA (context)->expose_y1);
- if (hold_width < 1)
- hold_width = 1;
- if (hold_height < 1)
- hold_height = 1;
-
- fe_RefreshArea (context,
- (CONTEXT_DATA (context)->expose_x1 +
- CONTEXT_DATA (context)->document_x),
- (CONTEXT_DATA (context)->expose_y1 +
- CONTEXT_DATA (context)->document_y),
- hold_width, hold_height);
-
- if ((new_x + new_width) > CONTEXT_DATA (context)->scrolled_width)
- new_width = CONTEXT_DATA (context)->scrolled_width - new_x;
- if ((new_y + new_height) > CONTEXT_DATA (context)->scrolled_height)
- new_height = CONTEXT_DATA (context)->scrolled_height - new_y;
- if (new_width < 1)
- new_width = 1;
- if (new_height < 1)
- new_height = 1;
-
- fe_RefreshArea (context,
- new_x + CONTEXT_DATA (context)->document_x,
- new_y + CONTEXT_DATA (context)->document_y,
- new_width, new_height);
- }
- }
- }
- }
- else
- {
- fe_RefreshArea (context,
- ee->x + CONTEXT_DATA (context)->document_x,
- ee->y + CONTEXT_DATA (context)->document_y,
- ee->width, ee->height);
- }
- }
-
- void
- fe_SyncExposures(MWContext* context)
- {
- XEvent event;
- Widget drawing_area = CONTEXT_DATA(context)->drawing_area;
- Display* display = XtDisplay(drawing_area);
- Window window = XtWindow(drawing_area);
-
- XSync(display, FALSE);
-
- while (XCheckTypedWindowEvent(display, window, Expose, &event) == TRUE) {
- fe_expose_eh(drawing_area, (XtPointer)context, &event);
- }
-
- /*
- * Force compositor to sync.
- */
- if (context->compositor)
- CL_CompositeNow(context->compositor);
- }
-
- static void
- fe_hack_scrollbar (Widget sb, int max, int inc, int page_inc,
- int slider_size, int value)
- {
- if (value + slider_size > max)
- value = max - slider_size;
- if (value < 0)
- value = 0;
- if (inc < 1)
- inc = 1;
- if (page_inc < inc)
- page_inc = inc;
- XtVaSetValues (sb,
- XmNmaximum, max,
- XmNincrement, inc,
- XmNpageIncrement, page_inc,
- XmNsliderSize, slider_size,
- XmNvalue, value,
- 0);
- }
-
-
- void
- fe_SetDocPosition (MWContext *context, unsigned long x, unsigned long y)
- {
- unsigned long w = CONTEXT_DATA (context)->document_width;
- unsigned long h = CONTEXT_DATA (context)->document_height;
- unsigned long lh = CONTEXT_DATA (context)->line_height;
- Dimension ww = 0, wh = 0;
- XP_Bool are_scrollbars_active;
- XP_Bool frame_scrolling_yes = False;
-
-
- if (x >= w + 100) x = 0;
- if (y >= h + lh) y = ((h > lh) ? h - lh : 0);
-
- if (context->is_grid_cell &&
- CONTEXT_DATA (context)->grid_scrolling == LO_SCROLL_NO) {
- /* We're done */
- CONTEXT_DATA (context)->document_x = x;
- CONTEXT_DATA (context)->document_y = y;
-
- return;
- }
-
- XP_ASSERT (CONTEXT_DATA (context)->drawing_area);
- if (!CONTEXT_DATA (context)->drawing_area) return;
-
- XtVaGetValues (CONTEXT_DATA (context)->drawing_area,
- XmNwidth, &ww, XmNheight, &wh, 0);
-
- /*
- * Fix for 4.0 bug 55350 (reported by ebina)
- *
- * <frame scrolling=yes> doesn't always have scrollbars.
- *
- * If grid_scrolling == LO_SCROLL_YES, then we force
- * both scrollbars to be on regardless of whether they
- * are needed or not.
- *
- * -ramiro
- */
- if (context->is_grid_cell &&
- CONTEXT_DATA (context)->grid_scrolling == LO_SCROLL_YES)
- {
- frame_scrolling_yes = True;
- }
-
- are_scrollbars_active = CONTEXT_DATA(context)->are_scrollbars_active;
-
- if ( (h <= wh) || (are_scrollbars_active == FALSE) )
- {
- if (!frame_scrolling_yes)
- {
- y = 0;
- XtUnmanageChild (CONTEXT_DATA (context)->vscroll);
- fe_hack_scrollbar (CONTEXT_DATA (context)->vscroll,
- 1, 1, 1, 1, 0);
- }
- }
- else
- {
- fe_hack_scrollbar (CONTEXT_DATA (context)->vscroll,
- h, /* max */
- lh, /* inc */
- wh - lh, /* page_inc */
- wh, /* slider_size */
- y /* value */
- );
- XtManageChild (CONTEXT_DATA (context)->vscroll);
- }
-
- if ( (w <= ww) || (are_scrollbars_active == FALSE) )
- {
- if (!frame_scrolling_yes)
- {
- x = 0;
- XtUnmanageChild (CONTEXT_DATA (context)->hscroll);
- fe_hack_scrollbar (CONTEXT_DATA (context)->hscroll,
- 1, 1, 1, 1, 0);
- }
- }
- else
- {
- fe_hack_scrollbar (CONTEXT_DATA (context)->hscroll,
- w, /* max */
- lh, /* inc */
- ww - lh, /* page_inc */
- ww, /* slider_size */
- x /* value */
- );
- XtManageChild (CONTEXT_DATA (context)->hscroll);
- }
-
- if (frame_scrolling_yes)
- {
- XtManageChild (CONTEXT_DATA (context)->vscroll);
- XtManageChild (CONTEXT_DATA (context)->hscroll);
- }
-
- fe_find_scrollbar_sizes(context);
-
- CONTEXT_DATA (context)->document_x = x;
- CONTEXT_DATA (context)->document_y = y;
-
- if (context->compositor)
- CL_ScrollCompositorWindow(context->compositor, x, y);
- }
-
- void
- FE_ScrollDocBy (MWContext *context, int iLocation, int32 deltax, int32 deltay)
- {
- int32 x;
- int32 y;
- XFE_GetDocPosition (context, iLocation, &x, &y);
- x += deltax;
- y += deltay;
- fe_ScrollTo (context, x, y);
- }
-
- void
- FE_ScrollDocTo (MWContext *context, int iLocation, int32 x, int32 y)
- {
- fe_ScrollTo (context, x, y);
- }
-
- void
- XFE_GetDocPosition (MWContext *context, int iLocation,
- int32 *iX, int32 *iY)
- {
- *iX = (int32)CONTEXT_DATA (context)->document_x;
- *iY = (int32)CONTEXT_DATA (context)->document_y;
- }
-
- void
- XFE_SetDocPosition (MWContext *context, int iLocation, int32 x, int32 y)
- {
- #if 0
- #ifdef EDITOR
- if (EDT_IS_EDITOR(context)) {
- fe_ScrollTo (context, x, y);
- }
- else
- #endif
- {
- fe_SetDocPosition (context, x, y);
- }
- #else
- /*
- * In WinFE (the standard), XFE_SetDocPosition() and FE_ScrollDocTo()
- * do the same thing (one calls the other). We seem to have a number
- * of bugs that are fixed by emulating WinFE's semantics, so our
- * feeling is that the back-end is now weighted in that way.
- * SO, rather than fight a losing battle, we think we'll just make
- * this change and hope that nothing new breaks. For Bug #77767.
- * - djw, vidur, mcafee, brendan (shared blame) July/20/1997.
- */
- fe_ScrollTo (context, x, y);
- #endif
- }
-
- void
- XFE_SetDocDimension (MWContext *context,
- int iLocation, int32 iWidth, int32 iLength)
- {
- Widget widget = CONTEXT_DATA (context)->drawing_area;
- #ifdef EDITOR
- unsigned long win_h;
- unsigned long old_h;
- #endif
- unsigned long w, h;
- time_t now = time ((time_t) 0);
-
- if (! widget) abort ();
- w = iWidth;
- h = iLength;
- if (w < 1) w = 1;
- if (h < 1) h = 1;
-
- #ifdef EDITOR
- win_h = CONTEXT_DATA (context)->scrolled_height;
- old_h = CONTEXT_DATA (context)->document_height;
- #endif
-
- CONTEXT_DATA (context)->document_width = w;
- CONTEXT_DATA (context)->document_height = h;
-
- /* Only actually resize the window once a second, to avoid thrashing. */
- if (now <= CONTEXT_DATA (context)->doc_size_last_update_time)
- return;
-
- /* We just need to update the scrollbars; nothing visible has changed. */
- fe_SetDocPosition (context,
- CONTEXT_DATA (context)->document_x,
- CONTEXT_DATA (context)->document_y);
-
- CONTEXT_DATA (context)->doc_size_last_update_time = now;
-
- #ifdef EDITOR
- /*
- * NOTE: fix for redisplay bugs... [ 73704, 73705, 73688 ]
- *
- */
- if (EDT_IS_EDITOR(context)) {
- if (h < old_h) {
- /*
- * NOTE: need to force a refresh if the we lost the scrollbars
- * in the process of shrinking the document size...
- *
- */
- if (h < win_h && old_h > win_h) {
- #ifdef DEBUG_rhess
- fprintf(stderr, "ForceRefresh::[ %d, %d ][ %d ][ %d ]\n",
- w, h, old_h, win_h);
- #endif
- fe_RefreshArea(context, 0, 0, w, h);
- }
- }
- }
- #endif
- }
-
-
- #ifdef RESIZE_CALLBACK_WORKS
-
- static void
- fe_resize_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- XmDrawingAreaCallbackStruct *cb = (XmDrawingAreaCallbackStruct *) call_data;
-
- #else
-
- static void
- fe_scroller_resize (Widget widget, XtPointer closure)
- {
- #endif
-
- MWContext *context = (MWContext *) closure;
- fe_ContextData *fep = CONTEXT_DATA(context);
- MWContextType type = context->type;
-
- /* I question the wisdom of having to do a reload every time the window
- size changes... */
- Dimension w = 0, h = 0;
- Boolean relayout_p = False;
-
- XtVaGetValues (widget, XmNwidth, &w, XmNheight, &h, 0);
-
- relayout_p = ((Dimension) fep->scrolled_width) != w;
-
- /*
- * Inside FRAMES (and eventually elsewhere?) we DO want to reload, even if
- * just the height has changed.
- */
- if ((!relayout_p)&&(context->is_grid_cell ||
- (context->grid_children &&
- XP_ListTopObject (context->grid_children))))
- {
- relayout_p = ((Dimension) fep->scrolled_height) != h;
- }
-
- /* Well this is kinda bogus; don't do a relayout if we're displaying one
- of the magic internal-external images, since we know no wrapping can
- occur. */
- if (relayout_p)
- {
- History_entry *h = SHIST_GetCurrent (&context->hist);
- if (h && h->is_binary)
- relayout_p = False;
- }
-
- /* If we have just an image and we resize such that either the width
- * or the height of the window is bigger than the image, and we had
- * scrolled off from the left,top edge, then we will need to refresh
- * the entire image. If this doesn't happen, then in the exposed parts
- * the image that is repainted is off the document_x, document_y.
- */
- if (
- /* If there is a real resize going on */
- (fep->scrolled_height != h || fep->scrolled_width != w) &&
- /* and if either of width or height spans the full document */
- (h >= fep->document_height || w >= fep->document_width) &&
- /* and if the document is not at its (0,0) origin */
- (fep->document_x != 0 || fep->document_y != 0)) {
- relayout_p = True;
- }
-
- /* Fullpage plugins need be told about size changes. */
- if (CONTEXT_DATA(context)->is_fullpage_plugin)
- {
- fe_RefreshArea (context,
- CONTEXT_DATA (context)->document_x,
- CONTEXT_DATA (context)->document_y,
- 1, 1);
- relayout_p = False;
- }
-
- if (! XtIsRealized (widget))
- /* I'm not sure this is right, but otherwise layout happens while a
- new window is still getting created... */
- relayout_p = False;
-
- if (relayout_p)
- {
- /* If a document is currently being laid out, just update the
- scrollbars and flag it as needing to be re-figured at the end.
- Otherwise, re-lay out the document with the new width.
- Note: don't use CONTEXT_DATA (context)->active_url_count
- here, that only counts foreground transfers, not images.
- */
- if (XP_IsContextBusy (context)) {
- CONTEXT_DATA (context)->relayout_required = True;
- } else {
-
- /* This is unset in XFE_LayoutNewDocument. */
- CONTEXT_DATA (context)->is_resizing = TRUE;
-
- /*
- * Need to update these before calling relayout, because the BE
- * is going to ask us this stuff in FE_GetDocAndWindowPosition().
- * Seems obvious I guess. Bug #27455.
- *
- * I moved this out of the next EDT_IS_EDITOR if, since
- * for the new relayout stuff, grid edges don't get moved
- * if their x or y is greater than the window width and
- * height. I honestly can't imagine why you wouldn't
- * want the size change reflected as early as possible
- * anyway -- toshok
- */
- CONTEXT_DATA(context)->scrolled_width = (unsigned long)w;
- CONTEXT_DATA(context)->scrolled_height = (unsigned long)h;
-
- #ifdef EDITOR
- /*
- * This edit_view_source_hack is so completely bogus,
- * but it seems to only be edit for the editor view
- * source window. Do this for bug #23375. djw 96/06/15.
- */
- if (EDT_IS_EDITOR(context) || context->edit_view_source_hack) {
-
- fe_EditorRefresh(context);
- }
- else
- #endif /*EDITOR*/
-
- #ifdef ENABLE_MARINER
- {
- int32 margin_w, margin_h;
-
- fe_GetMargin(context, &margin_w, &margin_h);
-
- LO_RelayoutOnResize(context, w, h, margin_w, margin_h);
- }
- #else
- /* As vidur suggested in Bug 59214: because JS generated content
- was not put into wysiwyg, hence this source was not be shown on a resize.
- The fix was to make the reload policy for Mail/News contexts NET_NORMAL_RELOAD */
- if ( (type == MWContextNews) || (type == MWContextMail)
- || (type == MWContextNewsMsg) || (type == MWContextMailMsg) )
- fe_ReLayout (context, NET_NORMAL_RELOAD);
- else
- fe_ReLayout (context, NET_RESIZE_RELOAD);
- #endif
- }
- }
- /* We just need to update the scrollbars; the other expose events
- which are coming will take care of repainting the text. */
- fe_SetDocPosition (context,
- CONTEXT_DATA (context)->document_x,
- CONTEXT_DATA (context)->document_y);
-
- /*
- ** this is wretched and gross. the assignments below are exactly the same as the ones
- ** about 20 lines above. Why do I duplicate them here, you may ask. Well, for some
- ** reason someplace in between the assignments above and the ones here (probably in
- ** fe_SetDocPosition), something happens to set the scrolled_width and scrolled_height
- ** to smaller values.
- ** this results in a band along the bottom and right hand sides of the document, where the
- ** scrollbars would normally be.
- **
- ** I am thoroughly disgusted.
- **
- ** - toshok
- */
- CONTEXT_DATA(context)->scrolled_width = (unsigned long)w;
- CONTEXT_DATA(context)->scrolled_height = (unsigned long)h;
-
- /* We only need the composited area without the scrollbars. However,
- since the scrollbars can become managed and then unmanaged during
- layout, it is not worth the effort of keeping track of when they
- are visible. Instead we make the compositor the size of the drawing
- area and just let the scrollbars clip the background layer. */
- if (context->compositor)
- CL_ResizeCompositorWindow(context->compositor, w, h);
- }
-
-
- Boolean
- fe_TestGravity (Widget widget)
- {
- Widget area, element;
- Arg arg[10];
- Cardinal argcnt;
- int shift;
- int orig_x, orig_y;
- int x, y;
- unsigned int w, h, d1, d2;
- Window dummy;
- XSetWindowAttributes set_attr;
- unsigned long valuemask;
- Boolean works;
- Visual *v = 0;
- Colormap cmap = 0;
- Cardinal depth = 0;
-
- /*
- * OW 3.4 has some horrid bug so that it tests OK for
- * guffaws scrolling, but then when the user resizes the
- * window, it crashes the X server. Sigh.
- */
- if ((!strcmp(XServerVendor(XtDisplay(widget)), "Sun Microsystems, Inc."))&&
- (VendorRelease(XtDisplay(widget)) == 3400))
- {
- return(False);
- }
-
- XtVaGetValues (widget, XtNvisual, &v, XtNcolormap, &cmap,
- XtNdepth, &depth, 0);
-
- shift = 10;
-
- argcnt = 0;
- XtSetArg(arg[argcnt], XmNvisual, v); argcnt++;
- XtSetArg(arg[argcnt], XmNcolormap, cmap); argcnt++;
- XtSetArg(arg[argcnt], XmNdepth, depth); argcnt++;
- XtSetArg(arg[argcnt], XtNwidth, 200); argcnt++;
- XtSetArg(arg[argcnt], XtNheight, 200); argcnt++;
- XtSetArg(arg[argcnt], XmNmappedWhenManaged, False); argcnt++;
- area = XmCreateDrawingArea(widget, "Area", arg, argcnt);
-
- argcnt = 0;
- XtSetArg(arg[argcnt], XmNvisual, v); argcnt++;
- XtSetArg(arg[argcnt], XmNcolormap, cmap); argcnt++;
- XtSetArg(arg[argcnt], XmNdepth, depth); argcnt++;
- XtSetArg(arg[argcnt], XtNx, 50); argcnt++;
- XtSetArg(arg[argcnt], XtNy, 80); argcnt++;
- XtSetArg(arg[argcnt], XmNmappedWhenManaged, False); argcnt++;
- element = fe_CreateTextField(area, "Element", arg, argcnt);
-
- XtManageChild(area);
- XtManageChild(element);
-
- valuemask = CWBitGravity | CWWinGravity;
- set_attr.win_gravity = StaticGravity;
- set_attr.bit_gravity = StaticGravity;
- XChangeWindowAttributes (XtDisplay(area), XtWindow(area),
- valuemask, &set_attr);
- XChangeWindowAttributes (XtDisplay(element), XtWindow(element),
- valuemask, &set_attr);
-
- XGetGeometry(XtDisplay(element), XtWindow(element), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- orig_x = x;
- orig_y = y;
-
- XGetGeometry(XtDisplay(area), XtWindow(area), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- XResizeWindow(XtDisplay(area), XtWindow(area), w, (h + shift));
- XMoveWindow(XtDisplay(area), XtWindow(area), x, (y - shift));
- XMoveResizeWindow(XtDisplay(area), XtWindow(area), x, y, w, h);
-
- XGetGeometry(XtDisplay(area), XtWindow(area), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- XResizeWindow(XtDisplay(area), XtWindow(area), w, (h + shift));
- XMoveWindow(XtDisplay(area), XtWindow(area), x, (y - shift));
- XMoveResizeWindow(XtDisplay(area), XtWindow(area), x, y, w, h);
-
- XGetGeometry(XtDisplay(element), XtWindow(element), &dummy,
- &x, &y, &w, &h, &d1, &d2);
- if (y != (orig_y - (2 * shift)))
- {
- works = False;
- }
- else
- {
- works = True;
- }
-
- XtDestroyWidget(area);
- return(works);
- }
-
-
- int
- fe_WindowGravityWorks (Widget toplevel, Widget widget)
- {
- String str = 0;
- static XtResource res = { "windowGravityWorks", XtCString, XtRString,
- sizeof (String), 0, XtRImmediate, "guess" };
- XtGetApplicationResources (toplevel, &str, &res, 1, 0, 0);
-
- if (str && (!XP_STRCASECMP(str, "yes") || !XP_STRCASECMP(str, "true")))
- {
- return 1;
- }
- else if (str && (!XP_STRCASECMP(str, "partial") || !XP_STRCASECMP(str, "kindof")))
- {
- return 2;
- }
- else if (str && (!XP_STRCASECMP(str, "no") || !XP_STRCASECMP(str, "false")))
- {
- return 0;
- }
- else
- {
- char *vendor = XServerVendor (XtDisplay (toplevel));
-
- if (str && XP_STRCASECMP(str, "guess"))
- {
- fprintf (stderr,
- XP_GetString(XFE_SCROLL_WINDOW_GRAVITY_WARNING),
- fe_progname, str);
- }
-
- /*
- * Short circuit all this other crap, and do the right thing.
- */
- if (fe_TestGravity(widget))
- {
- return 1;
- }
- else
- {
- return 2;
- }
-
- /* WindowGravity is known to be broken in the OpenWound 3.0 server
- and is known to work in the OpenWound 3.3 server.
- */
- if (!strcmp (vendor, "X11/NeWS - Sun Microsystems Inc."))
- #if 0
- return (VendorRelease (XtDisplay (toplevel)) >= 3300);
- #else
- /* Ok, all of Sun's code is just buggy as hell. There are lurking X
- server crashes that happen when we mess with window gravity on OW 2.4,
- so forget it. */
- return 0;
- #endif
- else if (!strncmp (vendor, "MacX", 4) || !strncmp (vendor, "eXodus", 6))
- /* The Mac X servers get this wrong (actually I'm not sure that both
- do, but at least one of them does.) */
- return 0;
-
- else if (!strcmp (vendor, "Sony Corporation"))
- /* Sony NEWS R4 is busted; later versions not *known* to work. */
- return (VendorRelease (XtDisplay (toplevel)) > 4);
-
- else if (!strcmp (vendor,
- "DECWINDOWS (Compatibility String) Network Computing Devices Inc."))
- /* NCD 2004 is busted; later versions not *known* to work. */
- return (VendorRelease (XtDisplay (toplevel)) > 2004);
-
- /* #### It has been suggested that all R4-based servers lose? */
-
- else
- return 1;
- }
- }
-
- void
- FE_ShowScrollBars(MWContext *context, XP_Bool show)
- {
- /* XXX implement me */
- }
-
-