diff --git a/mozilla/widget/src/gtk/nsGtkUtils.cpp b/mozilla/widget/src/gtk/nsGtkUtils.cpp index f0702fec5d3..3e4e369157b 100644 --- a/mozilla/widget/src/gtk/nsGtkUtils.cpp +++ b/mozilla/widget/src/gtk/nsGtkUtils.cpp @@ -120,92 +120,106 @@ nsGtkUtils::gtk_widget_set_color(GtkWidget * widget, } ////////////////////////////////////////////////////////////////// /* static */ void -nsGtkUtils::gdk_window_flash(GdkWindow * window, - unsigned int times, - unsigned long interval) +nsGtkUtils::gdk_window_flash(GdkWindow * aGdkWindow, + unsigned int aTimes, + unsigned long aInterval, + GdkRectangle * aArea) { - Display * display = 0; - Window root_window = 0; - Window child_window = 0; - Window xwindow = 0; - GC gc; - int x; - int y; - unsigned int width; - unsigned int height; - unsigned int border_width; - unsigned int depth; - int root_x; - int root_y; - unsigned int i; - XGCValues gcv; + Display * display = 0; + Window root_window = 0; + Window child_window = 0; + Window xwindow = 0; + GC gc; + int x; + int y; + unsigned int width; + unsigned int height; + unsigned int border_width; + unsigned int depth; + int root_x; + int root_y; + unsigned int i; + XGCValues gcv; #ifndef HAVE_USLEEP - struct timeval tv; + struct timeval tv; #endif + + display = GDK_WINDOW_XDISPLAY(aGdkWindow); + + xwindow = GDK_WINDOW_XWINDOW(aGdkWindow); + + XGetGeometry(display, + xwindow, + &root_window, + &x, + &y, + &width, + &height, + &border_width, + &depth); + + XTranslateCoordinates(display, + xwindow, + root_window, + 0, + 0, + &root_x, + &root_y, + &child_window); + + memset(&gcv, 0, sizeof(XGCValues)); + + gcv.function = GXxor; + gcv.foreground = WhitePixel(display, DefaultScreen(display)); + gcv.subwindow_mode = IncludeInferiors; + + if (gcv.foreground == 0) + gcv.foreground = 1; + + gc = XCreateGC(display, + root_window, + GCFunction | GCForeground | GCSubwindowMode, + &gcv); + + XGrabServer(display); - display = GDK_WINDOW_XDISPLAY(window); + // If an area is given, use that. Notice how out of whack coordinates + // and dimentsions are not checked!!! + if (aArea) + { + root_x += aArea->x; + root_y += aArea->y; - xwindow = GDK_WINDOW_XWINDOW(window); + width = aArea->width; + height = aArea->height; + } - XGetGeometry(display, - xwindow, - &root_window, - &x, - &y, - &width, - &height, - &border_width, - &depth); - - XTranslateCoordinates(display, - xwindow, - root_window, - 0, - 0, - &root_x, - &root_y, - &child_window); - - memset(&gcv, 0, sizeof(XGCValues)); - - gcv.function = GXxor; - gcv.foreground = WhitePixel(display, DefaultScreen(display)); - gcv.subwindow_mode = IncludeInferiors; - - if (gcv.foreground == 0) - gcv.foreground = 1; - - gc = XCreateGC(display, + // Need to do this twice so that the XOR effect can replace + // the original window contents. + for (i = 0; i < aTimes * 2; i++) + { + XFillRectangle(display, root_window, - GCFunction | GCForeground | GCSubwindowMode, - &gcv); - - XGrabServer(display); - - for (i = 0; i < times; i++) - { - XFillRectangle(display, - root_window, - gc, - root_x, - root_y, - width, - height); - - XSync(display, False); - + gc, + root_x, + root_y, + width, + height); + + XSync(display, False); + #ifdef HAVE_USLEEP - usleep(interval); + usleep(aInterval); #else - tv.tv_sec = interval / 100000; - tv.tv_usec = interval % 100000; - (void)select(0, NULL, NULL, NULL, &tv); + tv.tv_sec = aInterval / 100000; + tv.tv_usec = aInterval % 100000; + (void)select(0, NULL, NULL, NULL, &tv); #endif - } - - - XFreeGC(display, gc); - - XUngrabServer(display); + } + + + XFreeGC(display, gc); + + XUngrabServer(display); } ////////////////////////////////////////////////////////////////// diff --git a/mozilla/widget/src/gtk/nsGtkUtils.h b/mozilla/widget/src/gtk/nsGtkUtils.h index 239a75df38b..2d97ee93928 100644 --- a/mozilla/widget/src/gtk/nsGtkUtils.h +++ b/mozilla/widget/src/gtk/nsGtkUtils.h @@ -55,9 +55,19 @@ struct nsGtkUtils GtkStateType state, GdkColor * color); - static void gdk_window_flash(GdkWindow * window, - unsigned int times, /* Number of times to flash */ - unsigned long interval); /* Interval between flashes */ + /** + * Flash an area within a GDK window (or the whole window) + * + * @param aGdkWindow The GDK window to flash. + * @param aTimes Number of times to flash the area. + * @param aInterval Interval between flashes in milliseconds. + * @param aArea The area to flash. The whole window if NULL. + * + */ + static void gdk_window_flash(GdkWindow * aGdkWindow, + unsigned int aTimes, + unsigned long aInterval, + GdkRectangle * aArea); }; #endif // __nsGtkEventHandler.h diff --git a/mozilla/widget/src/gtk/nsWindow.cpp b/mozilla/widget/src/gtk/nsWindow.cpp index 3e115f5b551..9e02dd6820d 100644 --- a/mozilla/widget/src/gtk/nsWindow.cpp +++ b/mozilla/widget/src/gtk/nsWindow.cpp @@ -327,25 +327,17 @@ void nsWindow::InitCallbacks(char * aName) // Return some native data according to aDataType // //------------------------------------------------------------------------- -void *nsWindow::GetNativeData(PRUint32 aDataType) +void * nsWindow::GetNativeData(PRUint32 aDataType) { - switch(aDataType) + if (aDataType == NS_NATIVE_WINDOW) { - case NS_NATIVE_WINDOW: - return (void *)GTK_LAYOUT(mWidget)->bin_window; - case NS_NATIVE_DISPLAY: - return (void *)GDK_DISPLAY(); - case NS_NATIVE_WIDGET: - case NS_NATIVE_PLUGIN_PORT: - return (void *)mWidget; - case NS_NATIVE_GRAPHIC: - /* GetSharedGC ups the ref count on the GdkGC so make sure you release - * it afterwards. */ - return (void *)((nsToolkit *)mToolkit)->GetSharedGC(); - default: - break; + // The GTK layout widget uses a clip window to do scrolling. + // All the action happens on that window - called the 'bin_window' + if (mWidget) + return (void *) GTK_LAYOUT(mWidget)->bin_window; } - return nsnull; + + return nsWidget::GetNativeData(aDataType); } //------------------------------------------------------------------------- @@ -412,7 +404,10 @@ nsresult nsWindow::SetIcon(GdkPixmap *pixmap, return NS_OK; } +// Uncommenting this will cause OnPaint() to printf what it is doing #undef TRACE_PAINT + +// Uncommenting this will cause the OnPaint() area rect to flash #undef TRACE_PAINT_FLASH #ifdef TRACE_PAINT_FLASH @@ -464,7 +459,24 @@ PRBool nsWindow::OnPaint(nsPaintEvent &event) result = DispatchWindowEvent(&event); #ifdef TRACE_PAINT_FLASH - nsGtkUtils::gdk_window_flash(renderWindow,2,100000); + GdkRectangle ar; + GdkRectangle * area = NULL; + + if (event.rect) + { + ar.x = event.rect->x; + ar.y = event.rect->y; + + ar.width = event.rect->width; + ar.height = event.rect->height; + + area = &ar; + } + + nsGtkUtils::gdk_window_flash(renderWindow, + 1, + 100000, + area); #endif } return result; diff --git a/mozilla/widget/src/xlib/nsWidget.cpp b/mozilla/widget/src/xlib/nsWidget.cpp index 46571b8ee5c..0b7b9605dfd 100644 --- a/mozilla/widget/src/xlib/nsWidget.cpp +++ b/mozilla/widget/src/xlib/nsWidget.cpp @@ -749,7 +749,7 @@ nsWidget::DeleteWindowCallback(Window aWindow) #undef TRACE_PAINT_FLASH #ifdef TRACE_PAINT_FLASH -#include "nsXUtils.h" // for nsGtkUtils::gdk_window_flash() +#include "nsXUtils.h" // for nsXUtils::XFlashWindow() #endif PRBool @@ -798,7 +798,21 @@ nsWidget::OnPaint(nsPaintEvent &event) #endif #ifdef TRACE_PAINT_FLASH - nsXUtils::FlashWindow(mDisplay,mBaseWindow,2,100000); + XRectangle ar; + XRectangle * area = NULL; + + if (event.rect) + { + ar.x = event.rect->x; + ar.y = event.rect->y; + + ar.width = event.rect->width; + ar.height = event.rect->height; + + area = &ar; + } + + nsXUtils::XFlashWindow(mDisplay,mBaseWindow,1,100000,area); #endif } diff --git a/mozilla/widget/src/xlib/nsXUtils.cpp b/mozilla/widget/src/xlib/nsXUtils.cpp index 84f820c9f30..20abcc924ba 100644 --- a/mozilla/widget/src/xlib/nsXUtils.cpp +++ b/mozilla/widget/src/xlib/nsXUtils.cpp @@ -23,79 +23,101 @@ ////////////////////////////////////////////////////////////////// /* static */ void -nsXUtils::FlashWindow(Display * display, - Window window, - unsigned int times, /* Number of times to flash */ - unsigned long interval) /* Interval between flashes */ +nsXUtils::XFlashWindow(Display * aDisplay, + Window aWindow, + unsigned int aTimes, + unsigned long aInterval, + XRectangle * aArea) { - Window root_window; - Window child_window; - GC gc; - int x; - int y; - unsigned int width; - unsigned int height; - unsigned int border_width; - unsigned int depth; - int root_x; - int root_y; - unsigned int i; + Window root_window = 0; + Window child_window = 0; + GC gc; + int x; + int y; + unsigned int width; + unsigned int height; + unsigned int border_width; + unsigned int depth; + int root_x; + int root_y; + unsigned int i; + XGCValues gcv; +#ifndef HAVE_USLEEP + struct timeval tv; +#endif + + XGetGeometry(aDisplay, + aWindow, + &root_window, + &x, + &y, + &width, + &height, + &border_width, + &depth); + + XTranslateCoordinates(aDisplay, + aWindow, + root_window, + 0, + 0, + &root_x, + &root_y, + &child_window); + + memset(&gcv, 0, sizeof(XGCValues)); + + gcv.function = GXxor; + gcv.foreground = WhitePixel(aDisplay, DefaultScreen(aDisplay)); + gcv.subwindow_mode = IncludeInferiors; + + if (gcv.foreground == 0) + gcv.foreground = 1; + + gc = XCreateGC(aDisplay, + root_window, + GCFunction | GCForeground | GCSubwindowMode, + &gcv); + + XGrabServer(aDisplay); - XGCValues gcv; + // If an area is given, use that. Notice how out of whack coordinates + // and dimentsions are not checked!!! + if (aArea) + { + root_x += aArea->x; + root_y += aArea->y; - XGetGeometry(display, - window, - &root_window, - &x, - &y, - &width, - &height, - &border_width, - &depth); + width = aArea->width; + height = aArea->height; + } - XTranslateCoordinates(display, - window, - root_window, - 0, - 0, - &root_x, - &root_y, - &child_window); - - memset(&gcv, 0, sizeof(XGCValues)); - - gcv.function = GXxor; - gcv.foreground = WhitePixel(display, DefaultScreen(display)); - gcv.subwindow_mode = IncludeInferiors; - - if (gcv.foreground == 0) - gcv.foreground = 1; - - gc = XCreateGC(display, + // Need to do this twice so that the XOR effect can replace + // the original window contents. + for (i = 0; i < aTimes * 2; i++) + { + XFillRectangle(aDisplay, root_window, - GCFunction | GCForeground | GCSubwindowMode, - &gcv); - - XGrabServer(display); - - for (i = 0; i < times; i++) - { - XFillRectangle(display, - root_window, - gc, - root_x, - root_y, - width, - height); - - XSync(display, False); - - usleep(interval); - } - - - XFreeGC(display, gc); - - XUngrabServer(display); + gc, + root_x, + root_y, + width, + height); + + XSync(aDisplay, False); + +#ifdef HAVE_USLEEP + usleep(aInterval); +#else + tv.tv_sec = aInterval / 100000; + tv.tv_usec = aInterval % 100000; + (void)select(0, NULL, NULL, NULL, &tv); +#endif + } + + + XFreeGC(aDisplay, gc); + + XUngrabServer(aDisplay); } /*****************************************************************/ diff --git a/mozilla/widget/src/xlib/nsXUtils.h b/mozilla/widget/src/xlib/nsXUtils.h index 13b57a86d34..957133cd0b7 100644 --- a/mozilla/widget/src/xlib/nsXUtils.h +++ b/mozilla/widget/src/xlib/nsXUtils.h @@ -23,10 +23,21 @@ struct nsXUtils { - static void FlashWindow(Display * display, - Window window, - unsigned int times, /* Number of times to flash */ - unsigned long interval); /* Interval between flashes */ + /** + * Flash an area within a window (or the whole window) + * + * @param aDisplay The display. + * @param aWindow The XID of the window to flash. + * @param aTimes Number of times to flash the area. + * @param aInterval Interval between flashes in milliseconds. + * @param aArea The area to flash. The whole window if NULL. + * + */ + static void XFlashWindow(Display * aDisplay, + Window aWindow, + unsigned int aTimes, + unsigned long aInterval, + XRectangle * aArea); }; #endif // __nsXUtils_h