From cdecbbf5c5113ad8bd0418b6112a8011d338467d Mon Sep 17 00:00:00 2001 From: rods Date: Tue, 16 Jun 1998 23:51:44 +0000 Subject: [PATCH] trying to fix scrollbar and exposure --- widget/src/motif/nsScrollbar.cpp | 23 ++-- widget/src/motif/nsWindow.cpp | 46 +++++-- widget/src/motif/nsXtEventHandler.cpp | 176 +++++++++++++++++++++++++- widget/src/motif/nsXtEventHandler.h | 1 + 4 files changed, 220 insertions(+), 26 deletions(-) diff --git a/widget/src/motif/nsScrollbar.cpp b/widget/src/motif/nsScrollbar.cpp index 34a2520ee3c8..15add540755b 100644 --- a/widget/src/motif/nsScrollbar.cpp +++ b/widget/src/motif/nsScrollbar.cpp @@ -54,13 +54,6 @@ void nsScrollbar::Create(nsIWidget *aParent, nsWidgetInitData *aInitData) { Widget parentWidget = nsnull; - printf("===============\n"); - printf("===============\n"); - printf("===============\n"); - printf("===============\n"); - printf("===============\n"); - printf("===============\n"); - printf("Scrollbar this 0x%x\n", this); strcpy(gInstanceClassName, "nsScrollbar"); if (aParent) { @@ -169,9 +162,8 @@ void nsScrollbar::SetMaxRange(PRUint32 aEndRange) { int max = aEndRange; XtVaGetValues(mWidget, XmNmaximum, &max, nsnull); + if (DBG) printf("SetMaxRange %d\n", max); - max = aEndRange; - XtVaSetValues(mWidget, XmNmaximum, max, nsnull); } @@ -197,6 +189,7 @@ void nsScrollbar::SetPosition(PRUint32 aPos) { int pos = aPos; XtVaSetValues(mWidget, XmNvalue, pos, nsnull); + if (DBG) printf("SetPosition %d\n", pos); } @@ -222,6 +215,7 @@ PRUint32 nsScrollbar::GetPosition() void nsScrollbar::SetThumbSize(PRUint32 aSize) { XtVaSetValues(mWidget, XmNpageIncrement, (int)aSize, nsnull); + if (DBG) printf("SetThumbSize %d\n", aSize); } @@ -244,9 +238,12 @@ PRUint32 nsScrollbar::GetThumbSize() // Set the line increment for this scrollbar // //------------------------------------------------------------------------- -void nsScrollbar::SetLineIncrement(PRUint32 aSize) +void nsScrollbar::SetLineIncrement(PRUint32 aLineIncrement) { - mLineIncrement = aSize; + mLineIncrement = aLineIncrement; + XtVaSetValues(mWidget, XmNincrement, aLineIncrement, nsnull); + + if (DBG) printf("SetLineIncrement %d\n", aLineIncrement); } @@ -273,11 +270,13 @@ void nsScrollbar::SetParameters(PRUint32 aMaxRange, PRUint32 aThumbSize, XtVaSetValues(mWidget, XmNincrement, aLineIncrement, XmNmaximum, aMaxRange, XmNminimum, 0, - XmNpageIncrement, aThumbSize, + XmNsliderSize, aThumbSize, XmNvalue, aPosition, nsnull); mLineIncrement = aLineIncrement; + if (DBG) printf("SetParameters %d %d %d %d \n", aMaxRange, aThumbSize, + aPosition, aLineIncrement); } diff --git a/widget/src/motif/nsWindow.cpp b/widget/src/motif/nsWindow.cpp index 6a696376a8e4..df0bed409ba2 100644 --- a/widget/src/motif/nsWindow.cpp +++ b/widget/src/motif/nsWindow.cpp @@ -40,7 +40,7 @@ #include "stdio.h" -#define DBG 1 +#define DBG 0 static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); @@ -326,10 +326,10 @@ void nsWindow::CreateWindow(nsNativeWindow aNativeParent, nsXtWidget_Resize_Callback, this); - XtAddCallback(mWidget, + /*XtAddCallback(mWidget, XmNexposeCallback, - nsXtWidget_Resize_Callback, - this); + nsXtWidget_Expose_Callback, + this);*/ } @@ -383,7 +383,7 @@ void nsWindow::InitCallbacks(char * aName) XtAddEventHandler(mWidget, ExposureMask, - PR_FALSE, + PR_TRUE, nsXtWidget_ExposureMask_EventHandler, this); @@ -517,8 +517,8 @@ void nsWindow::Move(PRUint32 aX, PRUint32 aY) //------------------------------------------------------------------------- void nsWindow::Resize(PRUint32 aWidth, PRUint32 aHeight, PRBool aRepaint) { - // if (DBG) - printf("$$$$$$$$$ %s::Resize %d %d Repaint: %s\n", gInstanceClassName, aWidth, aHeight, (aRepaint?"true":"false")); + if (DBG) printf("$$$$$$$$$ %s::Resize %d %d Repaint: %s\n", + gInstanceClassName, aWidth, aHeight, (aRepaint?"true":"false")); mBounds.width = aWidth; mBounds.height = aHeight; XtVaSetValues(mWidget, XmNwidth, aWidth, XmNheight, aHeight, nsnull); @@ -538,7 +538,6 @@ void nsWindow::Resize(PRUint32 aX, PRUint32 aY, PRUint32 aWidth, PRUint32 aHeigh mBounds.height = aHeight; XtVaSetValues(mWidget, XmNx, aX, XmNy, aY, XmNwidth, aWidth, XmNheight, aHeight, nsnull); - printf("$$$$$$$$$ %s::Resize %d %d Repaint: %s\n", gInstanceClassName, aWidth, aHeight, (aRepaint?"true":"false")); } @@ -580,7 +579,6 @@ void nsWindow::SetBounds(const nsRect &aRect) void nsWindow::GetBounds(nsRect &aRect) { - printf("$$$$$$$$$ %s::GetBounds 0x%x\n", gInstanceClassName, this); /*XWindowAttributes attrs ; Window w = nsnull; @@ -803,6 +801,32 @@ nsIDeviceContext* nsWindow::GetDeviceContext() //------------------------------------------------------------------------- void nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect) { + if (mWidget == nsnull) { + return; + } + + Window win = XtWindow(mWidget); + Display *display = XtDisplay(mWidget); + + XCopyArea(display, win, win, XDefaultGC(display, 0), + aClipRect->x, aClipRect->y, + aClipRect->XMost(), aClipRect->YMost(), aDx, aDy); + + printf("Clipping %d %d %d %d\n", aClipRect->x, aClipRect->y,aClipRect->XMost(), aClipRect->YMost()); + printf("Forcing repaint %d %d %d %d\n", mBounds.x, mBounds.y, mBounds.width, mBounds.height); + XEvent evt; + evt.xgraphicsexpose.type = GraphicsExpose; + evt.xgraphicsexpose.send_event = False; + evt.xgraphicsexpose.display = display; + evt.xgraphicsexpose.drawable = win; + evt.xgraphicsexpose.x = mBounds.x; + evt.xgraphicsexpose.y = mBounds.y; + evt.xgraphicsexpose.width = mBounds.width; + evt.xgraphicsexpose.height = mBounds.height; + evt.xgraphicsexpose.count = 0; + //XSendEvent(display, win, False, ExposureMask, &evt); + //XFlush(display); + } @@ -933,11 +957,11 @@ PRBool nsWindow::DispatchMouseEvent(nsMouseEvent aEvent) GetBounds(rect); if (rect.Contains(event.point.x, event.point.y)) { if (mCurrentWindow == NULL || mCurrentWindow != this) { - printf("Mouse enter"); + //printf("Mouse enter"); mCurrentWindow = this; } } else { - printf("Mouse exit"); + //printf("Mouse exit"); } } break; diff --git a/widget/src/motif/nsXtEventHandler.cpp b/widget/src/motif/nsXtEventHandler.cpp index e8d3cc389779..3e8503b23dae 100644 --- a/widget/src/motif/nsXtEventHandler.cpp +++ b/widget/src/motif/nsXtEventHandler.cpp @@ -26,7 +26,7 @@ #include "stdio.h" -#define DBG 0 +#define DBG 1 //============================================================== void nsXtWidget_InitNSEvent(XEvent * anXEv, @@ -64,21 +64,125 @@ void nsXtWidget_InitNSMouseEvent(XEvent * anXEv, } +//============================================================== +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#define INTERSECTS(r1_x1,r1_x2,r1_y1,r1_y2,r2_x1,r2_x2,r2_y1,r2_y2) \ + !((r2_x2 <= r1_x1) ||\ + (r2_y2 <= r1_y1) ||\ + (r2_x1 >= r1_x2) ||\ + (r2_y1 >= r1_y2)) + +//============================================================== +typedef struct COLLAPSE_INFO { + Window win; + nsRect *r; +} CollapseInfo; + +//============================================================== +static void expandDamageRect(nsRect *drect, XEvent *xev, Boolean debug, char*str) +{ + int x1 = xev->xexpose.x; + int y1 = xev->xexpose.y; + int x2 = x1 + xev->xexpose.width; + int y2 = y1 + xev->xexpose.height; + + if (debug) { + printf(" %s: collapsing (%d,%d %dx%d) into (%d,%d %dx%d) ->>", + str, x1, y1, xev->xexpose.width, xev->xexpose.height, + drect->x, drect->y, drect->width - drect->x, drect->height - drect->y); + } + + drect->x = MIN(x1, drect->x); + drect->y = MIN(y1, drect->y); + drect->width = MAX(x2, drect->width); + drect->height = MAX(y2, drect->height); + + if (debug) { + printf("(%d,%d %dx%d) %s\n", + drect->x, drect->y, drect->width - drect->x, drect->height - drect->y); + } +} + +//============================================================== +static Bool checkForExpose(Display *dpy, XEvent *evt, XtPointer client_data) +{ + CollapseInfo *cinfo = (CollapseInfo*)client_data; + + if ((evt->type == Expose && evt->xexpose.window == cinfo->win && + INTERSECTS(cinfo->r->x, cinfo->r->width, cinfo->r->y, cinfo->r->height, + evt->xexpose.x, evt->xexpose.y, + evt->xexpose.x + evt->xexpose.width, + evt->xexpose.y + evt->xexpose.height)) || + (evt->type == GraphicsExpose && evt->xgraphicsexpose.drawable == cinfo->win && + INTERSECTS(cinfo->r->x, cinfo->r->width, cinfo->r->y, cinfo->r->height, + evt->xgraphicsexpose.x, evt->xgraphicsexpose.y, + evt->xgraphicsexpose.x + evt->xgraphicsexpose.width, + evt->xgraphicsexpose.y + evt->xgraphicsexpose.height))) { + + return True; + } + return False; +} + + //============================================================== void nsXtWidget_ExposureMask_EventHandler(Widget w, XtPointer p, XEvent * event, Boolean * b) { + if (DBG) fprintf(stderr, "In nsXtWidget_ExposureMask_EventHandler\n"); - nsPaintEvent pevent ; nsWindow * widgetWindow = (nsWindow *) p ; + nsPaintEvent pevent; + nsRect rect; + nsXtWidget_InitNSEvent(event, p, pevent, NS_PAINT); + + pevent.rect = (nsRect *)▭ +printf("Count %d\n", event->xexpose.count); if (event->xexpose.count != 0) return ; - nsXtWidget_InitNSEvent(event, p, pevent, NS_PAINT); + /* Only post Expose/Repaint if we know others arn't following + * directly in the queue. + */ + if (event->xexpose.count == 0) { + Boolean debug = PR_TRUE; + int count = 0; + CollapseInfo cinfo; + + cinfo.win = XtWindow(w); + cinfo.r = pevent.rect; + + rect.x = event->xexpose.x; + rect.y = event->xexpose.y; + rect.width = event->xexpose.width; + rect.height = event->xexpose.height; +printf("Before %d %d %d %d\n", rect.x, rect.y, rect.width, rect.height); + /* Do a little more inspecting and collapse further if there + * are additional expose events pending on this window where + * the damage rects intersect with the current exposeRect. + */ + while (1) { + XEvent xev; + + if (XCheckIfEvent(XtDisplay(w), &xev, checkForExpose, (XtPointer)&cinfo)) { + printf("]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"); + count = xev.xexpose.count; + expandDamageRect(&rect, &xev, debug, "2"); + + } else /* XCheckIfEvent Failed. */ + break; + } +printf("After %d %d %d %d\n", rect.x, rect.y, rect.width, rect.height); + } widgetWindow->OnPaint(pevent); if (DBG) fprintf(stderr, "Out nsXtWidget_ExposureMask_EventHandler\n"); + } //============================================================== @@ -244,6 +348,69 @@ void nsXtWidget_Scrollbar_Callback(Widget w, XtPointer p, XtPointer call_data) +//============================================================== +void nsXtWidget_Expose_Callback(Widget w, XtPointer p, XtPointer call_data) +{ + + //if (DBG) +//fprintf(stderr, "In nsXtWidget_Resize_Callback 0x%x", p); + nsWindow * widgetWindow = (nsWindow *) p ; + if (widgetWindow == nsnull) { + return; + } + + XmDrawingAreaCallbackStruct * cbs = (XmDrawingAreaCallbackStruct *)call_data; + XEvent * event = cbs->event; + nsPaintEvent pevent; + nsRect rect; + nsXtWidget_InitNSEvent(event, p, pevent, NS_PAINT); + + pevent.rect = (nsRect *)▭ +printf("Count %d\n", event->xexpose.count); + if (event->xexpose.count != 0) + return ; + + /* Only post Expose/Repaint if we know others arn't following + * directly in the queue. + */ + if (event->xexpose.count == 0) { + Boolean debug = PR_TRUE; + int count = 0; + CollapseInfo cinfo; + + cinfo.win = XtWindow(w); + cinfo.r = pevent.rect; + + rect.x = event->xexpose.x; + rect.y = event->xexpose.y; + rect.width = event->xexpose.width; + rect.height = event->xexpose.height; +printf("Before %d %d %d %d\n", rect.x, rect.y, rect.width, rect.height); + /* Do a little more inspecting and collapse further if there + * are additional expose events pending on this window where + * the damage rects intersect with the current exposeRect. + */ + while (1) { + XEvent xev; + + if (XCheckIfEvent(XtDisplay(w), &xev, checkForExpose, (XtPointer)&cinfo)) { + printf("]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\n"); + count = xev.xexpose.count; + expandDamageRect(&rect, &xev, debug, "2"); + + } else /* XCheckIfEvent Failed. */ + break; + } +printf("After %d %d %d %d\n", rect.x, rect.y, rect.width, rect.height); + } + + widgetWindow->OnPaint(pevent); + + if (DBG) fprintf(stderr, "Out nsXtWidget_ExposureMask_EventHandler\n"); + + +} + //============================================================== void nsXtWidget_Resize_Callback(Widget w, XtPointer p, XtPointer call_data) { @@ -316,7 +483,10 @@ void nsXtWidget_Resize_Callback(Widget w, XtPointer p, XtPointer call_data) rect.height = attrs.height; doResize = PR_TRUE; } + //printf("doResize %s %d %d %d %d rect %d %d\n", (doResize ?"true":"false"), + //attrs.x, attrs.y, attrs.width, attrs.height, rect.width, rect.height); + //doResize = PR_TRUE; if (doResize) { //printf("??????????????????????????????? Doing Resize\n"); widgetWindow->SetBounds(rect); // This needs to be done inside OnResize diff --git a/widget/src/motif/nsXtEventHandler.h b/widget/src/motif/nsXtEventHandler.h index cc2f32d26fd7..b53b7651dd0f 100644 --- a/widget/src/motif/nsXtEventHandler.h +++ b/widget/src/motif/nsXtEventHandler.h @@ -41,6 +41,7 @@ void nsXtWidget_Toggle_DisArmCallback(Widget w, XtPointer p, XtPointer call_data void nsXtWidget_Text_Callback(Widget w, XtPointer p, XtPointer call_data); void nsXtWidget_Resize_Callback(Widget w, XtPointer p, XtPointer call_data); +void nsXtWidget_Expose_Callback(Widget w, XtPointer p, XtPointer call_data); #endif // __nsXtEventHandler.h