static gboolean motion_notify_event_cb    (GtkWidget *widget, GdkEventMotion *event); static gboolean button_press_event_cb     (GtkWidget *widget, GdkEventButton *event); static gboolean button_release_event_cb   (GtkWidget *widget, GdkEventButton *event); static gboolean focus_in_event_cb         (GtkWidget *widget, GdkEventFocus *event); static gboolean focus_out_event_cb        (GtkWidget *widget, GdkEventFocus *event); static gboolean key_press_event_cb        (GtkWidget *widget, GdkEventKey *event); static gboolean key_release_event_cb      (GtkWidget *widget, GdkEventKey *event); static gboolean scroll_event_cb           (GtkWidget *widget, GdkEventScroll *event); static gboolean visibility_notify_event_cb(GtkWidget *widget, GdkEventVisibility *event);  static PRBool                 gJustGotActivate = PR_FALSE; nsCOMPtr  <nsIRollupListener> gRollupListener; nsWeakPtr                     gRollupWindow;  nsWindow::nsWindow() { mFocusChild          = nsnull; mContainer           = nsnull; mDrawingarea         = nsnull; mShell               = nsnull; mWindowGroup         = nsnull; mContainerGotFocus   = PR_FALSE; mContainerLostFocus  = PR_FALSE; mContainerBlockFocus = PR_FALSE; mHasFocus            = PR_FALSE; mInKeyRepeat         = PR_FALSE; mIsVisible           = PR_FALSE; mRetryGrab           = PR_FALSE; mTransientParent     = nsnull; mWindowType          = eWindowType_child; }  nsWindow::~nsWindow() { LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this)); Destroy(); }  NS_IMPL_ISUPPORTS_INHERITED1(nsWindow, nsCommonWidget, nsISupportsWeakReference)  NS_IMETHODIMP nsWindow::Create(nsIWidget        *aParent, const nsRect     &aRect, EVENT_CALLBACK   aHandleEventFunction, nsIDeviceContext *aContext, nsIAppShell      *aAppShell, nsIToolkit       *aToolkit, nsWidgetInitData *aInitData) { return NativeCreate(aParent, nsnull, aRect, aHandleEventFunction, aContext, aAppShell, aToolkit, aInitData); }  NS_IMETHODIMP nsWindow::Create(nsNativeWidget aParent, const nsRect     &aRect, EVENT_CALLBACK   aHandleEventFunction, nsIDeviceContext *aContext, nsIAppShell      *aAppShell, nsIToolkit       *aToolkit, nsWidgetInitData *aInitData) { return NativeCreate(nsnull, aParent, aRect, aHandleEventFunction, aContext, aAppShell, aToolkit, aInitData); }  NS_IMETHODIMP nsWindow::Destroy(void) { if (mIsDestroyed) return NS_OK;  LOG(("nsWindow::Destroy [%p]\n", (void *)this)); mIsDestroyed = PR_TRUE;   nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow); if (NS_STATIC_CAST(nsIWidget *, this) == rollupWidget.get()) { if (gRollupListener) gRollupListener->Rollup(); gRollupWindow = nsnull; gRollupListener = nsnull; }  NativeShow(PR_FALSE);   nsCOMPtr<nsIEnumerator> children = dont_AddRef(GetChildren()); if (children) { nsCOMPtr<nsISupports> isupp; nsCOMPtr<nsIWidget> child; while (NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(isupp)) && isupp)) { child = do_QueryInterface(isupp); if (child) { child->Destroy(); }  if (NS_FAILED(children->Next())) break; } }   if (mHasFocus) { LOG(("automatically losing focus...\n")); mHasFocus = PR_FALSE;   nsWindow *owningWindow = get_owning_window_for_gdk_window(mDrawingarea->inner_window); owningWindow->mFocusChild = nsnull; }      mWindowGroup = nsnull;  if (mShell) { gtk_widget_destroy(mShell); mShell = nsnull; }  mContainer = nsnull;  if (mDrawingarea) { g_object_unref(mDrawingarea); mDrawingarea = nsnull; }  OnDestroy();  return NS_OK; }  NS_IMETHODIMP nsWindow::SetModal(PRBool aModal) { LOG(("nsWindow::SetModal [%p] %d\n", (void *)this, aModal));   GtkWidget *grabWidget = nsnull;  GetToplevelWidget(&grabWidget);  if (!grabWidget) return NS_ERROR_FAILURE;  if (aModal) gtk_grab_add(grabWidget); else gtk_grab_remove(grabWidget);  return NS_OK; }  NS_IMETHODIMP nsWindow::IsVisible(PRBool & aState) { aState = mIsVisible; return NS_OK; }  NS_IMETHODIMP nsWindow::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::Move(PRInt32 aX, PRInt32 aY) { if (aX == mBounds.x && aY == mBounds.y) return NS_OK;  LOG(("nsWindow::Move [%p] %d %d\n", (void *)this, aX, aY));  mBounds.x = aX; mBounds.y = aY;  if (mIsTopLevel) { if (mParent && mWindowType == eWindowType_popup) { nsRect oldrect, newrect; oldrect.x = aX; oldrect.y = aY; mParent->WidgetToScreen(oldrect, newrect); gtk_window_move(GTK_WINDOW(mShell), newrect.x, newrect.y); } else { gtk_window_move(GTK_WINDOW(mShell), aX, aY); } } else { moz_drawingarea_move(mDrawingarea, aX, aY); }  return NS_OK; }  NS_IMETHODIMP nsWindow::PlaceBehind(nsIWidget *aWidget, PRBool     aActivate) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::Enable(PRBool aState) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::SetFocus(PRBool aRaise) {    LOG(("SetFocus [%p]\n", (void *)this)); gpointer user_data = NULL; gdk_window_get_user_data(mDrawingarea->inner_window, &user_data); if (!user_data) return NS_ERROR_FAILURE;  GtkWidget *owningWidget = GTK_WIDGET(user_data); nsWindow  *owningWindow = get_window_for_gtk_widget(owningWidget); if (!owningWindow) return NS_ERROR_FAILURE;  if (!GTK_WIDGET_HAS_FOCUS(owningWidget)) {  LOG(("grabbing focus for the toplevel\n")); owningWindow->mContainerBlockFocus = PR_TRUE; gtk_widget_grab_focus(owningWidget); owningWindow->mContainerBlockFocus = PR_FALSE;  DispatchGotFocusEvent();   if (gJustGotActivate) { gJustGotActivate = PR_FALSE; DispatchActivateEvent(); }  return NS_OK; }       if (mHasFocus) { LOG(("already have focus...\n")); return NS_OK; }    if (owningWindow->mFocusChild) { LOG(("removing focus child %p\n", (void *)owningWindow->mFocusChild)); owningWindow->mFocusChild->LoseFocus(); }    owningWindow->mFocusChild = this; mHasFocus = PR_TRUE;  DispatchGotFocusEvent();   if (gJustGotActivate) { gJustGotActivate = PR_FALSE; DispatchActivateEvent(); }  return NS_OK; }  NS_IMETHODIMP nsWindow::GetScreenBounds(nsRect &aRect) { nsRect origin(0, 0, mBounds.width, mBounds.height); WidgetToScreen(origin, aRect); LOG(("GetScreenBounds %d %d | %d %d | %d %d\n", aRect.x, aRect.y, mBounds.width, mBounds.height, aRect.width, aRect.height)); return NS_OK; }  NS_IMETHODIMP nsWindow::SetForegroundColor(const nscolor &aColor) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::SetBackgroundColor(const nscolor &aColor) { return NS_ERROR_NOT_IMPLEMENTED; }  nsIFontMetrics* nsWindow::GetFont(void) { return nsnull; }  NS_IMETHODIMP nsWindow::SetFont(const nsFont &aFont) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::SetCursor(nsCursor aCursor) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::Validate() {   GdkRegion *region = gdk_window_get_update_area(mDrawingarea->inner_window);  if (region) gdk_region_destroy(region);  return NS_OK; }  NS_IMETHODIMP nsWindow::Invalidate(PRBool aIsSynchronous) { GdkRectangle rect;  rect.x = mBounds.x; rect.y = mBounds.y; rect.width = mBounds.width; rect.height = mBounds.height;  gdk_window_invalidate_rect(mDrawingarea->inner_window, &rect, TRUE); if (aIsSynchronous) gdk_window_process_updates(mDrawingarea->inner_window, TRUE);  return NS_OK; }  NS_IMETHODIMP nsWindow::Invalidate(const nsRect &aRect, PRBool        aIsSynchronous) { GdkRectangle rect;  rect.x = aRect.x; rect.y = aRect.y; rect.width = aRect.width; rect.height = aRect.height;  gdk_window_invalidate_rect(mDrawingarea->inner_window, &rect, TRUE); if (aIsSynchronous) gdk_window_process_updates(mDrawingarea->inner_window, TRUE);  return NS_OK; }  NS_IMETHODIMP nsWindow::InvalidateRegion(const nsIRegion* aRegion, PRBool           aIsSynchronous) { GdkRegion *region = nsnull; aRegion->GetNativeRegion((void *)region);  if (region) gdk_window_invalidate_region(mDrawingarea->inner_window, region, TRUE);  return NS_OK; }  NS_IMETHODIMP nsWindow::Update() { gdk_window_process_updates(mDrawingarea->inner_window, TRUE); return NS_OK; }  NS_IMETHODIMP nsWindow::SetColorMap(nsColorMap *aColorMap) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::Scroll(PRInt32  aDx, PRInt32  aDy, nsRect  *aClipRect) { moz_drawingarea_scroll(mDrawingarea, aDx, aDy);   nsCOMPtr<nsIEnumerator> children = dont_AddRef(GetChildren()); if (children) { nsCOMPtr<nsISupports> isupp; nsCOMPtr<nsIWidget> child; while (NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(isupp)) && isupp)) { child = do_QueryInterface(isupp); if (child) { nsRect bounds; child->GetBounds(bounds); bounds.x += aDx; bounds.y += aDy; NS_STATIC_CAST(nsBaseWidget*, (nsIWidget*)child)->SetBounds(bounds); }  if (NS_FAILED(children->Next())) break; } }   gdk_window_process_all_updates(); return NS_OK; }  NS_IMETHODIMP nsWindow::ScrollWidgets(PRInt32 aDx, PRInt32 aDy) { moz_drawingarea_scroll(mDrawingarea, aDx, aDy); return NS_OK; }  NS_IMETHODIMP nsWindow::ScrollRect(nsRect  &aSrcRect, PRInt32  aDx, PRInt32  aDy) { return NS_ERROR_NOT_IMPLEMENTED; }  void* nsWindow::GetNativeData(PRUint32 aDataType) { switch (aDataType) { case NS_NATIVE_WINDOW: case NS_NATIVE_WIDGET: return mDrawingarea->inner_window; break;  case NS_NATIVE_PLUGIN_PORT: NS_WARNING("nsWindow::GetNativeData plugin port not supported yet"); return nsnull; break;  case NS_NATIVE_DISPLAY: return GDK_DISPLAY(); break;  case NS_NATIVE_GRAPHIC: NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC"); return (void *)NS_STATIC_CAST(nsToolkit *, mToolkit)->GetSharedGC(); break;  default: NS_WARNING("nsWindow::GetNativeData called with bad value"); return nsnull; } }  NS_IMETHODIMP nsWindow::SetBorderStyle(nsBorderStyle aBorderStyle) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::SetTitle(const nsString& aTitle) { if (!mShell) return NS_OK;   NS_ConvertUCS2toUTF8 utf8title(aTitle); gtk_window_set_title(GTK_WINDOW(mShell), (const char *)utf8title.get());  return NS_OK; }  NS_IMETHODIMP nsWindow::SetIcon(const nsAReadableString& anIconSpec) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::SetMenuBar(nsIMenuBar * aMenuBar) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::ShowMenuBar(PRBool aShow) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect) { gint x, y = 0;  if (mContainer) { gdk_window_get_root_origin(GTK_WIDGET(mContainer)->window, &x, &y); LOG(("WidgetToScreen (container) %d %d\n", x, y)); } else { gdk_window_get_origin(mDrawingarea->inner_window, &x, &y); LOG(("WidgetToScreen (drawing) %d %d\n", x, y)); }  aNewRect.x = x + aOldRect.x; aNewRect.y = y + aOldRect.y; aNewRect.width = aOldRect.width; aNewRect.height = aOldRect.height;  return NS_OK; }  NS_IMETHODIMP nsWindow::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::BeginResizingChildren(void) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::EndResizingChildren(void) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::EnableDragDrop(PRBool aEnable) { return NS_ERROR_NOT_IMPLEMENTED; }  void nsWindow::ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY) { }  NS_IMETHODIMP nsWindow::PreCreateWidget(nsWidgetInitData *aWidgetInitData) { if (nsnull != aWidgetInitData) { mWindowType = aWidgetInitData->mWindowType; mBorderStyle = aWidgetInitData->mBorderStyle; return NS_OK; } return NS_ERROR_FAILURE; }  NS_IMETHODIMP nsWindow::CaptureMouse(PRBool aCapture) { return NS_ERROR_NOT_IMPLEMENTED; }  NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener *aListener, PRBool             aDoCapture, PRBool             aConsumeRollupEvent) { if (aDoCapture) { gRollupListener = aListener; gRollupWindow = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWidget*,this))); NativeGrab(PR_TRUE); } else { NativeGrab(PR_FALSE); gRollupListener = nsnull; gRollupWindow = nsnull; }  return NS_OK; }  NS_IMETHODIMP nsWindow::GetAttention() { LOG(("nsWindow::GetAttention [%p]\n", (void *)this)); return NS_OK; }  void nsWindow::LoseFocus(void) {  mHasFocus = PR_FALSE;    mInKeyRepeat = PR_FALSE;   DispatchLostFocusEvent(); }  gboolean nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent) { if (mIsDestroyed) { LOG(("Expose event on destroyed window [%p] window %p\n", (void *)this, (void *)aEvent->window)); return NS_OK; }   if (aEvent->window != mDrawingarea->inner_window) return FALSE;  LOG(("sending expose event [%p] %p 0x%lx\n\t%d %d %d %d\n", (void *)this, (void *)aEvent->window, GDK_WINDOW_XWINDOW(aEvent->window), aEvent->area.x, aEvent->area.y, aEvent->area.width, aEvent->area.height));    nsRect rect(aEvent->area.x, aEvent->area.y, aEvent->area.width, aEvent->area.height); nsPaintEvent event;  InitPaintEvent(event);  event.point.x = aEvent->area.x; event.point.y = aEvent->area.y; event.rect = &rect;  event.region = nsnull;  event.renderingContext = GetRenderingContext();  nsEventStatus status; DispatchEvent(&event, status);  NS_RELEASE(event.renderingContext);   return TRUE; }  gboolean nsWindow::OnConfigureEvent(GtkWidget *aWidget, GdkEventConfigure *aEvent) { LOG(("configure event [%p] %d %d %d %d\n", (void *)this, aEvent->x, aEvent->y, aEvent->width, aEvent->height));   if (mBounds.x == aEvent->x && mBounds.y == aEvent->y) return FALSE;  nsGUIEvent event; InitGUIEvent(event, NS_MOVE);  event.point.x = aEvent->x; event.point.y = aEvent->y;    nsEventStatus status; DispatchEvent(&event, status);  return FALSE; }  void nsWindow::OnSizeAllocate(GtkWidget *aWidget, GtkAllocation *aAllocation) { LOG(("size_allocate [%p] %d %d %d %d\n", (void *)this, aAllocation->x, aAllocation->y, aAllocation->width, aAllocation->height));  nsRect rect(aAllocation->x, aAllocation->y, aAllocation->width, aAllocation->height);  mBounds.width = rect.width; mBounds.height = rect.height;  moz_drawingarea_resize (mDrawingarea, rect.width, rect.height);  nsEventStatus status; DispatchResizeEvent (rect, status); }  void nsWindow::OnDeleteEvent(GtkWidget *aWidget, GdkEventAny *aEvent) { nsGUIEvent event;  InitGUIEvent(event, NS_XUL_CLOSE);  event.point.x = 0; event.point.y = 0;  nsEventStatus status; DispatchEvent(&event, status); }  void nsWindow::OnEnterNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent) { nsMouseEvent event; InitMouseEvent(event, NS_MOUSE_ENTER);  event.point.x = nscoord(aEvent->x); event.point.y = nscoord(aEvent->y);  nsEventStatus status; DispatchEvent(&event, status); }  void nsWindow::OnLeaveNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent) { nsMouseEvent event; InitMouseEvent(event, NS_MOUSE_EXIT);  event.point.x = nscoord(aEvent->x); event.point.y = nscoord(aEvent->y);  nsEventStatus status; DispatchEvent(&event, status); }  void nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent) {   XEvent xevent; PRPackedBool synthEvent = PR_FALSE; while (XCheckWindowEvent(GDK_WINDOW_XDISPLAY(aEvent->window), GDK_WINDOW_XWINDOW(aEvent->window), ButtonMotionMask, &xevent)) { synthEvent = PR_TRUE; }  nsMouseEvent event; InitMouseEvent(event, NS_MOUSE_MOVE);  if (synthEvent) { event.point.x = nscoord(xevent.xmotion.x); event.point.y = nscoord(xevent.xmotion.y);  event.isShift   = (xevent.xmotion.state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE; event.isControl = (xevent.xmotion.state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE; event.isAlt     = (xevent.xmotion.state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE; } else { event.point.x = nscoord(aEvent->x); event.point.y = nscoord(aEvent->y);  event.isShift   = (aEvent->state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE; event.isControl = (aEvent->state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE; event.isAlt     = (aEvent->state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE; }  nsEventStatus status; DispatchEvent(&event, status); }  void nsWindow::OnButtonPressEvent(GtkWidget *aWidget, GdkEventButton *aEvent) { nsMouseEvent  event; PRUint32      eventType; nsEventStatus status;  switch (aEvent->button) { case 2: eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN; break; case 3: eventType = NS_MOUSE_RIGHT_BUTTON_DOWN; break; default: eventType = NS_MOUSE_LEFT_BUTTON_DOWN; break; }  InitButtonEvent(event, eventType, aEvent);  DispatchEvent(&event, status);   if (eventType == NS_MOUSE_RIGHT_BUTTON_DOWN) { InitButtonEvent(event, NS_CONTEXTMENU, aEvent); DispatchEvent(&event, status); } }  void nsWindow::OnButtonReleaseEvent(GtkWidget *aWidget, GdkEventButton *aEvent) { nsMouseEvent  event; PRUint32      eventType;  switch (aEvent->button) { case 2: eventType = NS_MOUSE_MIDDLE_BUTTON_UP; break; case 3: eventType = NS_MOUSE_RIGHT_BUTTON_UP; break;  case 4: case 5: return; break;  default: eventType = NS_MOUSE_LEFT_BUTTON_UP; break; }  InitButtonEvent(event, eventType, aEvent);  nsEventStatus status; DispatchEvent(&event, status); }  void nsWindow::OnContainerFocusInEvent(GtkWidget *aWidget, GdkEventFocus *aEvent) {    if (mContainerBlockFocus) return;  if (mIsTopLevel) gJustGotActivate = PR_TRUE;   DispatchGotFocusEvent(); }  void nsWindow::OnContainerFocusOutEvent(GtkWidget *aWidget, GdkEventFocus *aEvent) {  if (mFocusChild) { mFocusChild->LoseFocus(); mFocusChild->DispatchDeactivateEvent(); mFocusChild = nsnull; } }  gboolean nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent) {  if (aEvent->keyval == GDK_Tab) if (aEvent->state & GDK_CONTROL_MASK) if (aEvent->state & GDK_MOD1_MASK) return FALSE;   if (aEvent->keyval == GDK_Shift_L || aEvent->keyval == GDK_Shift_R || aEvent->keyval == GDK_Control_L || aEvent->keyval == GDK_Control_R || aEvent->keyval == GDK_Alt_L || aEvent->keyval == GDK_Alt_R) return TRUE;        nsEventStatus status; nsKeyEvent event;  if (!mInKeyRepeat) { mInKeyRepeat = PR_TRUE;  InitKeyEvent(event, aEvent, NS_KEY_DOWN); DispatchEvent(&event, status); }  InitKeyEvent(event, aEvent, NS_KEY_PRESS); event.charCode = nsConvertCharCodeToUnicode(aEvent); if (event.charCode) { event.keyCode = 0;     if (!event.isControl && !event.isAlt && !event.isMeta) event.isShift = PR_FALSE; }   DispatchEvent(&event, status); return TRUE; }  gboolean nsWindow::OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent) {  mInKeyRepeat = PR_FALSE;    if (aEvent->keyval == GDK_Shift_L || aEvent->keyval == GDK_Shift_R || aEvent->keyval == GDK_Control_L || aEvent->keyval == GDK_Control_R || aEvent->keyval == GDK_Alt_L || aEvent->keyval == GDK_Alt_R) return TRUE;  nsKeyEvent event; InitKeyEvent(event, aEvent, NS_KEY_UP);  nsEventStatus status; DispatchEvent(&event, status);  return TRUE; }  void nsWindow::OnScrollEvent(GtkWidget *aWidget, GdkEventScroll *aEvent) { nsMouseScrollEvent event; InitMouseScrollEvent(event, aEvent, NS_MOUSE_SCROLL);  nsEventStatus status; DispatchEvent(&event, status); }  void nsWindow::OnVisibilityNotifyEvent(GtkWidget *aWidget, GdkEventVisibility *aEvent) { switch (aEvent->state) { case GDK_VISIBILITY_UNOBSCURED: case GDK_VISIBILITY_PARTIAL: mIsVisible = PR_TRUE;  if (mRetryGrab) NativeGrab(PR_TRUE); break; default: mIsVisible = PR_FALSE; break; } }  nsresult nsWindow::NativeCreate(nsIWidget        *aParent, nsNativeWidget    aNativeParent, const nsRect     &aRect, EVENT_CALLBACK    aHandleEventFunction, nsIDeviceContext *aContext, nsIAppShell      *aAppShell, nsIToolkit       *aToolkit, nsWidgetInitData *aInitData) {   nsIWidget *baseParent = aInitData && (aInitData->mWindowType == eWindowType_dialog || aInitData->mWindowType == eWindowType_toplevel) ? nsnull : aParent;   BaseCreate(baseParent, aRect, aHandleEventFunction, aContext, aAppShell, aToolkit, aInitData);   CommonCreate(aParent, aNativeParent);   mBounds = aRect;   MozDrawingarea *parentArea = nsnull; MozContainer   *parentContainer = nsnull; GtkWindow      *topLevelParent = nsnull; if (aParent || aNativeParent) { GdkWindow *parentWindow;  if (aParent) parentWindow = GDK_WINDOW(aParent->GetNativeData(NS_NATIVE_WINDOW)); else parentWindow = GDK_WINDOW(aNativeParent);   gpointer user_data = nsnull; user_data = g_object_get_data(G_OBJECT(parentWindow), "mozdrawingarea"); parentArea = MOZ_DRAWINGAREA(user_data);  NS_ASSERTION(parentArea, "no drawingarea for parent widget!\n"); if (!parentArea) return NS_ERROR_FAILURE;   user_data = nsnull; gdk_window_get_user_data(parentArea->inner_window, &user_data); NS_ASSERTION(user_data, "no user data for parentArea\n"); if (!user_data) return NS_ERROR_FAILURE;   parentContainer = MOZ_CONTAINER(user_data); NS_ASSERTION(parentContainer, "owning widget is not a mozcontainer!\n"); if (!parentContainer) return NS_ERROR_FAILURE;    topLevelParent = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(parentContainer))); }   switch (mWindowType) { case eWindowType_dialog: case eWindowType_popup: case eWindowType_toplevel: { mIsTopLevel = PR_TRUE; if (mWindowType == eWindowType_dialog) { mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_type_hint(GTK_WINDOW(mShell), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent); mTransientParent = topLevelParent;  if (parentArea) { nsWindow *parentnsWindow = get_window_for_gdk_window(parentArea->inner_window); NS_ASSERTION(parentnsWindow, "no nsWindow for parentArea!"); if (parentnsWindow && parentnsWindow->mWindowGroup) { gtk_window_group_add_window(parentnsWindow->mWindowGroup, GTK_WINDOW(mShell));  mWindowGroup = parentnsWindow->mWindowGroup; LOG(("adding window %p to group %p\n", (void *)mShell, (void *)mWindowGroup)); } } } else if (mWindowType == eWindowType_popup) { mShell = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent); mTransientParent = topLevelParent; } else { mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);  mWindowGroup = gtk_window_group_new();  LOG(("adding window %p to new group %p\n", (void *)mShell, (void *)mWindowGroup)); gtk_window_group_add_window(mWindowGroup, GTK_WINDOW(mShell)); }   mContainer = MOZ_CONTAINER(moz_container_new()); gtk_container_add(GTK_CONTAINER(mShell), GTK_WIDGET(mContainer)); gtk_widget_realize(GTK_WIDGET(mContainer));   gtk_window_set_focus(GTK_WINDOW(mShell), GTK_WIDGET(mContainer));   mDrawingarea = moz_drawingarea_new(nsnull, mContainer); } break; case eWindowType_child: { mDrawingarea = moz_drawingarea_new(parentArea, parentContainer); } break; default: break; }    g_object_set_data(G_OBJECT(mDrawingarea->clip_window), "nsWindow", this); g_object_set_data(G_OBJECT(mDrawingarea->inner_window), "nsWindow", this);  g_object_set_data(G_OBJECT(mDrawingarea->clip_window), "mozdrawingarea", mDrawingarea); g_object_set_data(G_OBJECT(mDrawingarea->inner_window), "mozdrawingarea", mDrawingarea);  if (mContainer) g_object_set_data(G_OBJECT(mContainer), "nsWindow", this);  if (mShell) g_object_set_data(G_OBJECT(mShell), "nsWindow", this);   if (mShell) { g_signal_connect(G_OBJECT(mShell), "configure_event", G_CALLBACK(configure_event_cb), NULL); g_signal_connect(G_OBJECT(mShell), "delete_event", G_CALLBACK(delete_event_cb), NULL); } if (mContainer) { g_signal_connect_after(G_OBJECT(mContainer), "size_allocate", G_CALLBACK(size_allocate_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "expose_event", G_CALLBACK(expose_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "enter_notify_event", G_CALLBACK(enter_notify_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "leave_notify_event", G_CALLBACK(leave_notify_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "motion_notify_event", G_CALLBACK(motion_notify_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "button_press_event", G_CALLBACK(button_press_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "button_release_event", G_CALLBACK(button_release_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "focus_in_event", G_CALLBACK(focus_in_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "focus_out_event", G_CALLBACK(focus_out_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "key_press_event", G_CALLBACK(key_press_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "key_release_event", G_CALLBACK(key_release_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "scroll_event", G_CALLBACK(scroll_event_cb), NULL); g_signal_connect(G_OBJECT(mContainer), "visibility_notify_event", G_CALLBACK(visibility_notify_event_cb), NULL); }  LOG(("nsWindow [%p]\n", (void *)this)); if (mShell) { LOG(("\tmShell %p %p %lx\n", (void *)mShell, (void *)mShell->window, GDK_WINDOW_XWINDOW(mShell->window))); } if (mContainer) { LOG(("\tmContainer %p %p %lx\n", (void *)mContainer, (void *)GTK_WIDGET(mContainer)->window, GDK_WINDOW_XWINDOW(GTK_WIDGET(mContainer)->window))); } if (mDrawingarea) { LOG(("\tmDrawingarea %p %p %p %lx %lx\n", (void *)mDrawingarea, (void *)mDrawingarea->clip_window, (void *)mDrawingarea->inner_window, GDK_WINDOW_XWINDOW(mDrawingarea->clip_window), GDK_WINDOW_XWINDOW(mDrawingarea->inner_window))); }   Resize(mBounds.width, mBounds.height, PR_FALSE);  return NS_OK; }  void nsWindow::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool  aRepaint) { LOG(("nsWindow::NativeResize [%p] %d %d\n", (void *)this, aWidth, aHeight));   mNeedsResize = PR_FALSE;  if (mIsTopLevel) gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);  moz_drawingarea_resize (mDrawingarea, aWidth, aHeight); }  void nsWindow::NativeResize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool  aRepaint) { mNeedsResize = PR_FALSE;  LOG(("nsWindow::NativeResize [%p] %d %d %d %d\n", (void *)this, aX, aY, aWidth, aHeight));  if (mIsTopLevel) { if (mParent && mWindowType == eWindowType_popup) { nsRect oldrect, newrect; oldrect.x = aX; oldrect.y = aY; mParent->WidgetToScreen(oldrect, newrect); moz_drawingarea_resize(mDrawingarea, aWidth, aHeight); gtk_window_move(GTK_WINDOW(mShell), newrect.x, newrect.y); gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight); } else { gtk_window_move(GTK_WINDOW(mShell), aX, aY); gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight); moz_drawingarea_resize(mDrawingarea, aWidth, aHeight); } } else { moz_drawingarea_move_resize(mDrawingarea, aX, aY, aWidth, aHeight); } }  void nsWindow::NativeShow (PRBool  aAction) { if (aAction) {  mNeedsShow = PR_FALSE;  if (mIsTopLevel) { moz_drawingarea_set_visibility(mDrawingarea, aAction); gtk_widget_show(GTK_WIDGET(mContainer)); gtk_widget_show(mShell);  } else { moz_drawingarea_set_visibility(mDrawingarea, aAction); } } else { if (mIsTopLevel) { gtk_widget_hide(GTK_WIDGET(mShell)); gtk_widget_hide(GTK_WIDGET(mContainer)); } moz_drawingarea_set_visibility(mDrawingarea, aAction); } }  void nsWindow::NativeGrab(PRBool aGrab) { LOG(("NativeGrab aGrab %d mRetryGrab %d\n", aGrab, mRetryGrab));    mRetryGrab = PR_FALSE;  if (aGrab) {    PRBool visibility = PR_TRUE; IsVisible(visibility); if (!visibility) { LOG(("window not visible\n")); mRetryGrab = PR_TRUE; return; }  GdkCursor *cursor = gdk_cursor_new(GDK_ARROW);  gint retval; retval = gdk_pointer_grab(mDrawingarea->inner_window, PR_TRUE, (GdkEventMask)(GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK), (GdkWindow *)NULL, cursor, GDK_CURRENT_TIME);   gdk_cursor_destroy(cursor);  if (retval != GDK_GRAB_SUCCESS) { LOG(("pointer grab failed\n")); mRetryGrab = PR_TRUE; return; }  GdkWindow *grabWindow;     if (mTransientParent) grabWindow = GTK_WIDGET(mTransientParent)->window; else grabWindow = mDrawingarea->inner_window;  retval = gdk_keyboard_grab(grabWindow, PR_TRUE, GDK_CURRENT_TIME);  if (retval != GDK_GRAB_SUCCESS) { LOG(("keyboard grab failed %d\n", retval)); gdk_pointer_ungrab(GDK_CURRENT_TIME); mRetryGrab = PR_TRUE; return; } } else { gdk_pointer_ungrab(GDK_CURRENT_TIME); gdk_keyboard_ungrab(GDK_CURRENT_TIME); } }  void nsWindow::GetToplevelWidget(GtkWidget **aWidget) { *aWidget = nsnull;  if (mShell) { *aWidget = mShell; return; }  gpointer user_data = nsnull; gdk_window_get_user_data(mDrawingarea->inner_window, &user_data); NS_ASSERTION(user_data, "no user data for parentArea\n");  if (!user_data) return;  *aWidget = gtk_widget_get_toplevel(GTK_WIDGET(user_data)); }   nsWindow * get_window_for_gtk_widget(GtkWidget *widget) { gpointer user_data; user_data = g_object_get_data(G_OBJECT(widget), "nsWindow");  if (!user_data) return nsnull;  return NS_STATIC_CAST(nsWindow *, user_data); }   nsWindow * get_window_for_gdk_window(GdkWindow *window) { gpointer user_data; user_data = g_object_get_data(G_OBJECT(window), "nsWindow");  if (!user_data) return nsnull;  return NS_STATIC_CAST(nsWindow *, user_data); }   nsWindow * get_owning_window_for_gdk_window(GdkWindow *window) { gpointer user_data; gdk_window_get_user_data(window, &user_data);  if (!user_data) return nsnull;  GtkWidget *owningWidget = GTK_WIDGET(user_data);  if (!owningWidget) return nsnull;  user_data = NULL; user_data = g_object_get_data(G_OBJECT(owningWidget), "nsWindow");  if (!user_data) return nsnull;  return (nsWindow *)user_data; }     gboolean expose_event_cb(GtkWidget *widget, GdkEventExpose *event) { nsWindow *window = get_window_for_gdk_window(event->window); if (!window) return FALSE;          window->OnExposeEvent(widget, event); return FALSE; }   gboolean configure_event_cb(GtkWidget *widget, GdkEventConfigure *event) { nsWindow *window = get_window_for_gtk_widget(widget); if (!window) return FALSE;  return window->OnConfigureEvent(widget, event); }   void size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation) { nsWindow *window = get_window_for_gtk_widget(widget); if (!window) return;  window->OnSizeAllocate(widget, allocation); }   gboolean delete_event_cb(GtkWidget *widget, GdkEventAny *event) { nsWindow *window = get_window_for_gtk_widget(widget); if (!window) return FALSE;  window->OnDeleteEvent(widget, event);  return TRUE; }   gboolean enter_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event) { nsWindow *window = get_window_for_gdk_window(event->window); if (!window) return TRUE;  window->OnEnterNotifyEvent(widget, event);  return TRUE; }   gboolean leave_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event) { nsWindow *window = get_window_for_gdk_window(event->window); if (!window) return TRUE;  window->OnLeaveNotifyEvent(widget, event);  return TRUE; }   gboolean
static gboolean motion_notify_event_cb    (GtkWidget *widget,					   GdkEventMotion *event);static gboolean button_press_event_cb     (GtkWidget *widget,					   GdkEventButton *event);static gboolean button_release_event_cb   (GtkWidget *widget,					   GdkEventButton *event);static gboolean focus_in_event_cb         (GtkWidget *widget,					   GdkEventFocus *event);static gboolean focus_out_event_cb        (GtkWidget *widget,					   GdkEventFocus *event);static gboolean key_press_event_cb        (GtkWidget *widget,					   GdkEventKey *event);static gboolean key_release_event_cb      (GtkWidget *widget,					   GdkEventKey *event);static gboolean scroll_event_cb           (GtkWidget *widget,					   GdkEventScroll *event);static gboolean visibility_notify_event_cb(GtkWidget *widget,					   GdkEventVisibility *event);static PRBool                 gJustGotActivate = PR_FALSE;nsCOMPtr  <nsIRollupListener> gRollupListener;nsWeakPtr                     gRollupWindow;nsWindow::nsWindow(){  mFocusChild          = nsnull;  mContainer           = nsnull;  mDrawingarea         = nsnull;  mShell               = nsnull;  mWindowGroup         = nsnull;  mContainerGotFocus   = PR_FALSE;  mContainerLostFocus  = PR_FALSE;  mContainerBlockFocus = PR_FALSE;  mHasFocus            = PR_FALSE;  mInKeyRepeat         = PR_FALSE;  mIsVisible           = PR_FALSE;  mRetryGrab           = PR_FALSE;  mTransientParent     = nsnull;  mWindowType          = eWindowType_child;}nsWindow::~nsWindow(){  LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this));  Destroy();}NS_IMPL_ISUPPORTS_INHERITED1(nsWindow, nsCommonWidget,			     nsISupportsWeakReference)NS_IMETHODIMPnsWindow::Create(nsIWidget        *aParent,		 const nsRect     &aRect,		 EVENT_CALLBACK   aHandleEventFunction,		 nsIDeviceContext *aContext,		 nsIAppShell      *aAppShell,		 nsIToolkit       *aToolkit,		 nsWidgetInitData *aInitData){  return NativeCreate(aParent, nsnull, aRect, aHandleEventFunction,		      aContext, aAppShell, aToolkit, aInitData);}NS_IMETHODIMPnsWindow::Create(nsNativeWidget aParent,		 const nsRect     &aRect,		 EVENT_CALLBACK   aHandleEventFunction,		 nsIDeviceContext *aContext,		 nsIAppShell      *aAppShell,		 nsIToolkit       *aToolkit,		 nsWidgetInitData *aInitData){  return NativeCreate(nsnull, aParent, aRect, aHandleEventFunction,		      aContext, aAppShell, aToolkit, aInitData);}NS_IMETHODIMPnsWindow::Destroy(void){  if (mIsDestroyed)    return NS_OK;  LOG(("nsWindow::Destroy [%p]\n", (void *)this));  mIsDestroyed = PR_TRUE;  // ungrab if required  nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);  if (NS_STATIC_CAST(nsIWidget *, this) == rollupWidget.get()) {    if (gRollupListener)      gRollupListener->Rollup();    gRollupWindow = nsnull;    gRollupListener = nsnull;  }  NativeShow(PR_FALSE);  // walk the list of children and call destroy on them.  nsCOMPtr<nsIEnumerator> children = dont_AddRef(GetChildren());  if (children) {    nsCOMPtr<nsISupports> isupp;    nsCOMPtr<nsIWidget> child;    while (NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(isupp))			&& isupp)) {      child = do_QueryInterface(isupp);      if (child) {	child->Destroy();      }      if (NS_FAILED(children->Next()))        break;    }  }  // make sure that we remove ourself as the focus window  if (mHasFocus) {    LOG(("automatically losing focus...\n"));    mHasFocus = PR_FALSE;    // get the owning gtk widget and the nsWindow for that widget and    // remove ourselves as the focus widget tracked in that window    nsWindow *owningWindow =      get_owning_window_for_gdk_window(mDrawingarea->inner_window);    owningWindow->mFocusChild = nsnull;  }  // Remove our reference to the window group.  If there was a window  // group destroying the widget will have automatically unreferenced  // the group, destroying it if necessary.  And, if we're a child  // window this isn't going to harm anything.  mWindowGroup = nsnull;  if (mShell) {    gtk_widget_destroy(mShell);    mShell = nsnull;  }  mContainer = nsnull;  if (mDrawingarea) {    g_object_unref(mDrawingarea);    mDrawingarea = nsnull;  }  OnDestroy();  return NS_OK;}NS_IMETHODIMPnsWindow::SetModal(PRBool aModal){  LOG(("nsWindow::SetModal [%p] %d\n", (void *)this, aModal));  // find the toplevel window and add it to the grab list  GtkWidget *grabWidget = nsnull;  GetToplevelWidget(&grabWidget);    if (!grabWidget)    return NS_ERROR_FAILURE;  if (aModal)    gtk_grab_add(grabWidget);  else    gtk_grab_remove(grabWidget);  return NS_OK;}NS_IMETHODIMPnsWindow::IsVisible(PRBool & aState){  aState = mIsVisible;  return NS_OK;}NS_IMETHODIMPnsWindow::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY){  return NS_ERROR_NOT_IMPLEMENTED; }NS_IMETHODIMPnsWindow::Move(PRInt32 aX, PRInt32 aY){  if (aX == mBounds.x && aY == mBounds.y)    return NS_OK;  LOG(("nsWindow::Move [%p] %d %d\n", (void *)this,       aX, aY));  mBounds.x = aX;  mBounds.y = aY;  if (mIsTopLevel) {    if (mParent && mWindowType == eWindowType_popup) {      nsRect oldrect, newrect;      oldrect.x = aX;      oldrect.y = aY;      mParent->WidgetToScreen(oldrect, newrect);      gtk_window_move(GTK_WINDOW(mShell), newrect.x, newrect.y);    }    else {      gtk_window_move(GTK_WINDOW(mShell), aX, aY);    }  }  else {    moz_drawingarea_move(mDrawingarea, aX, aY);  }    return NS_OK;}NS_IMETHODIMPnsWindow::PlaceBehind(nsIWidget *aWidget,		      PRBool     aActivate){  return NS_ERROR_NOT_IMPLEMENTED; }NS_IMETHODIMPnsWindow::Enable(PRBool aState){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::SetFocus(PRBool aRaise){  // Make sure that our owning widget has focus.  If it doesn't try to  // grab it.  Note that we don't set our focus flag in this case.    LOG(("SetFocus [%p]\n", (void *)this));  gpointer user_data = NULL;  gdk_window_get_user_data(mDrawingarea->inner_window, &user_data);  if (!user_data)    return NS_ERROR_FAILURE;  GtkWidget *owningWidget = GTK_WIDGET(user_data);  nsWindow  *owningWindow = get_window_for_gtk_widget(owningWidget);  if (!owningWindow)    return NS_ERROR_FAILURE;  if (!GTK_WIDGET_HAS_FOCUS(owningWidget)) {    LOG(("grabbing focus for the toplevel\n"));    owningWindow->mContainerBlockFocus = PR_TRUE;    gtk_widget_grab_focus(owningWidget);    owningWindow->mContainerBlockFocus = PR_FALSE;    DispatchGotFocusEvent();    // unset the activate flag    if (gJustGotActivate) {      gJustGotActivate = PR_FALSE;      DispatchActivateEvent();    }    return NS_OK;  }  // Raise the window if someone passed in PR_TRUE and the prefs are  // set properly.  // XXX do this  // If this is the widget that already has focus, return.  if (mHasFocus) {    LOG(("already have focus...\n"));    return NS_OK;  }    // If there is already a focued child window, dispatch a LOSTFOCUS  // event from that widget and unset its got focus flag.  if (owningWindow->mFocusChild) {    LOG(("removing focus child %p\n", (void *)owningWindow->mFocusChild));    owningWindow->mFocusChild->LoseFocus();  }  // Set this window to be the focused child window, update our has  // focus flag and dispatch a GOTFOCUS event.  owningWindow->mFocusChild = this;  mHasFocus = PR_TRUE;  DispatchGotFocusEvent();  // make sure to unset the activate flag and send an activate event  if (gJustGotActivate) {    gJustGotActivate = PR_FALSE;    DispatchActivateEvent();  }    return NS_OK;}NS_IMETHODIMPnsWindow::GetScreenBounds(nsRect &aRect){  nsRect origin(0, 0, mBounds.width, mBounds.height);  WidgetToScreen(origin, aRect);  LOG(("GetScreenBounds %d %d | %d %d | %d %d\n",       aRect.x, aRect.y,       mBounds.width, mBounds.height,       aRect.width, aRect.height));  return NS_OK;}NS_IMETHODIMPnsWindow::SetForegroundColor(const nscolor &aColor){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::SetBackgroundColor(const nscolor &aColor){  return NS_ERROR_NOT_IMPLEMENTED;}nsIFontMetrics*nsWindow::GetFont(void){  return nsnull;}NS_IMETHODIMPnsWindow::SetFont(const nsFont &aFont){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::SetCursor(nsCursor aCursor){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::Validate(){  // Get the update for this window and, well, just drop it on the  // floor.  GdkRegion *region = gdk_window_get_update_area(mDrawingarea->inner_window);  if (region)    gdk_region_destroy(region);  return NS_OK;}NS_IMETHODIMPnsWindow::Invalidate(PRBool aIsSynchronous){  GdkRectangle rect;  rect.x = mBounds.x;  rect.y = mBounds.y;  rect.width = mBounds.width;  rect.height = mBounds.height;  gdk_window_invalidate_rect(mDrawingarea->inner_window,			     &rect, TRUE);  if (aIsSynchronous)    gdk_window_process_updates(mDrawingarea->inner_window, TRUE);    return NS_OK;}NS_IMETHODIMPnsWindow::Invalidate(const nsRect &aRect,		     PRBool        aIsSynchronous){  GdkRectangle rect;  rect.x = aRect.x;  rect.y = aRect.y;  rect.width = aRect.width;  rect.height = aRect.height;  gdk_window_invalidate_rect(mDrawingarea->inner_window,			     &rect, TRUE);  if (aIsSynchronous)    gdk_window_process_updates(mDrawingarea->inner_window, TRUE);  return NS_OK;}NS_IMETHODIMPnsWindow::InvalidateRegion(const nsIRegion* aRegion,			   PRBool           aIsSynchronous){  GdkRegion *region = nsnull;  aRegion->GetNativeRegion((void *)region);  if (region)    gdk_window_invalidate_region(mDrawingarea->inner_window,				 region, TRUE);    return NS_OK;}NS_IMETHODIMPnsWindow::Update(){  gdk_window_process_updates(mDrawingarea->inner_window, TRUE);  return NS_OK;}NS_IMETHODIMPnsWindow::SetColorMap(nsColorMap *aColorMap){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::Scroll(PRInt32  aDx,		 PRInt32  aDy,		 nsRect  *aClipRect){  moz_drawingarea_scroll(mDrawingarea, aDx, aDy);  // Update bounds on our child windows  nsCOMPtr<nsIEnumerator> children = dont_AddRef(GetChildren());  if (children) {    nsCOMPtr<nsISupports> isupp;    nsCOMPtr<nsIWidget> child;    while (NS_SUCCEEDED(children->CurrentItem(getter_AddRefs(isupp))			&& isupp)) {      child = do_QueryInterface(isupp);      if (child) {        nsRect bounds;        child->GetBounds(bounds);        bounds.x += aDx;        bounds.y += aDy;        NS_STATIC_CAST(nsBaseWidget*, (nsIWidget*)child)->SetBounds(bounds);      }      if (NS_FAILED(children->Next()))        break;    }  }  // Process all updates so that everything is drawn.  gdk_window_process_all_updates();  return NS_OK;}NS_IMETHODIMPnsWindow::ScrollWidgets(PRInt32 aDx,			PRInt32 aDy){  moz_drawingarea_scroll(mDrawingarea, aDx, aDy);  return NS_OK;}NS_IMETHODIMPnsWindow::ScrollRect(nsRect  &aSrcRect,		     PRInt32  aDx,		     PRInt32  aDy){  return NS_ERROR_NOT_IMPLEMENTED;}void*nsWindow::GetNativeData(PRUint32 aDataType){  switch (aDataType) {  case NS_NATIVE_WINDOW:  case NS_NATIVE_WIDGET:    return mDrawingarea->inner_window;    break;  case NS_NATIVE_PLUGIN_PORT:    NS_WARNING("nsWindow::GetNativeData plugin port not supported yet");    return nsnull;    break;  case NS_NATIVE_DISPLAY:    return GDK_DISPLAY();    break;  case NS_NATIVE_GRAPHIC:    NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC");    return (void *)NS_STATIC_CAST(nsToolkit *, mToolkit)->GetSharedGC();    break;  default:    NS_WARNING("nsWindow::GetNativeData called with bad value");    return nsnull;  }}NS_IMETHODIMPnsWindow::SetBorderStyle(nsBorderStyle aBorderStyle){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::SetTitle(const nsString& aTitle){  if (!mShell)    return NS_OK;  // convert the string into utf8 and set the title.  NS_ConvertUCS2toUTF8 utf8title(aTitle);  gtk_window_set_title(GTK_WINDOW(mShell), (const char *)utf8title.get());  return NS_OK;}NS_IMETHODIMPnsWindow::SetIcon(const nsAReadableString& anIconSpec){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::SetMenuBar(nsIMenuBar * aMenuBar){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::ShowMenuBar(PRBool aShow){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::WidgetToScreen(const nsRect& aOldRect, nsRect& aNewRect){  gint x, y = 0;  if (mContainer) {    gdk_window_get_root_origin(GTK_WIDGET(mContainer)->window,			       &x, &y);    LOG(("WidgetToScreen (container) %d %d\n", x, y));  }  else {    gdk_window_get_origin(mDrawingarea->inner_window, &x, &y);    LOG(("WidgetToScreen (drawing) %d %d\n", x, y));  }  aNewRect.x = x + aOldRect.x;  aNewRect.y = y + aOldRect.y;  aNewRect.width = aOldRect.width;  aNewRect.height = aOldRect.height;  return NS_OK;}NS_IMETHODIMPnsWindow::ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::BeginResizingChildren(void){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::EndResizingChildren(void){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::EnableDragDrop(PRBool aEnable){  return NS_ERROR_NOT_IMPLEMENTED;}   voidnsWindow::ConvertToDeviceCoordinates(nscoord &aX,				     nscoord &aY){}NS_IMETHODIMPnsWindow::PreCreateWidget(nsWidgetInitData *aWidgetInitData){  if (nsnull != aWidgetInitData) {    mWindowType = aWidgetInitData->mWindowType;    mBorderStyle = aWidgetInitData->mBorderStyle;    return NS_OK;  }  return NS_ERROR_FAILURE;}  NS_IMETHODIMPnsWindow::CaptureMouse(PRBool aCapture){  return NS_ERROR_NOT_IMPLEMENTED;}NS_IMETHODIMPnsWindow::CaptureRollupEvents(nsIRollupListener *aListener,			      PRBool             aDoCapture,			      PRBool             aConsumeRollupEvent){  if (aDoCapture) {    gRollupListener = aListener;    gRollupWindow =      getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWidget*,this)));    NativeGrab(PR_TRUE);  }  else {    NativeGrab(PR_FALSE);    gRollupListener = nsnull;    gRollupWindow = nsnull;  }  return NS_OK;}NS_IMETHODIMPnsWindow::GetAttention(){  LOG(("nsWindow::GetAttention [%p]\n", (void *)this));  return NS_OK;}voidnsWindow::LoseFocus(void){  // we don't have focus  mHasFocus = PR_FALSE;  // make sure that we reset our repeat counter so the next keypress  // for this widget will get the down event  mInKeyRepeat = PR_FALSE;  // Dispatch a lostfocus event  DispatchLostFocusEvent();}gbooleannsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent){  if (mIsDestroyed) {    LOG(("Expose event on destroyed window [%p] window %p\n",	 (void *)this, (void *)aEvent->window));    return NS_OK;  }  // handle exposes for the inner window only  if (aEvent->window != mDrawingarea->inner_window)    return FALSE;  LOG(("sending expose event [%p] %p 0x%lx\n\t%d %d %d %d\n",       (void *)this,       (void *)aEvent->window,       GDK_WINDOW_XWINDOW(aEvent->window),       aEvent->area.x, aEvent->area.y,       aEvent->area.width, aEvent->area.height));  // ok, send out the paint event  // XXX figure out the region/rect stuff!  nsRect rect(aEvent->area.x, aEvent->area.y,	      aEvent->area.width, aEvent->area.height);  nsPaintEvent event;  InitPaintEvent(event);  event.point.x = aEvent->area.x;  event.point.y = aEvent->area.y;  event.rect = &rect;  // XXX fix this!  event.region = nsnull;  // XXX fix this!  event.renderingContext = GetRenderingContext();  nsEventStatus status;  DispatchEvent(&event, status);  NS_RELEASE(event.renderingContext);  // check the return value!  return TRUE;}gbooleannsWindow::OnConfigureEvent(GtkWidget *aWidget, GdkEventConfigure *aEvent){  LOG(("configure event [%p] %d %d %d %d\n", (void *)this,       aEvent->x, aEvent->y, aEvent->width, aEvent->height));  // can we shortcut?  if (mBounds.x == aEvent->x &&      mBounds.y == aEvent->y)    return FALSE;  nsGUIEvent event;  InitGUIEvent(event, NS_MOVE);  event.point.x = aEvent->x;  event.point.y = aEvent->y;  // XXX mozilla will invalidate the entire window after this move  // complete.  wtf?  nsEventStatus status;  DispatchEvent(&event, status);  return FALSE;}voidnsWindow::OnSizeAllocate(GtkWidget *aWidget, GtkAllocation *aAllocation){  LOG(("size_allocate [%p] %d %d %d %d\n",       (void *)this, aAllocation->x, aAllocation->y,       aAllocation->width, aAllocation->height));    nsRect rect(aAllocation->x, aAllocation->y,	      aAllocation->width, aAllocation->height);  mBounds.width = rect.width;  mBounds.height = rect.height;  moz_drawingarea_resize (mDrawingarea, rect.width, rect.height);  nsEventStatus status;  DispatchResizeEvent (rect, status);}voidnsWindow::OnDeleteEvent(GtkWidget *aWidget, GdkEventAny *aEvent){  nsGUIEvent event;  InitGUIEvent(event, NS_XUL_CLOSE);  event.point.x = 0;  event.point.y = 0;  nsEventStatus status;  DispatchEvent(&event, status);}voidnsWindow::OnEnterNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent){  nsMouseEvent event;  InitMouseEvent(event, NS_MOUSE_ENTER);  event.point.x = nscoord(aEvent->x);  event.point.y = nscoord(aEvent->y);  nsEventStatus status;  DispatchEvent(&event, status);}voidnsWindow::OnLeaveNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent){  nsMouseEvent event;  InitMouseEvent(event, NS_MOUSE_EXIT);  event.point.x = nscoord(aEvent->x);  event.point.y = nscoord(aEvent->y);  nsEventStatus status;  DispatchEvent(&event, status);}voidnsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent){  // see if we can compress this event  XEvent xevent;  PRPackedBool synthEvent = PR_FALSE;  while (XCheckWindowEvent(GDK_WINDOW_XDISPLAY(aEvent->window),			   GDK_WINDOW_XWINDOW(aEvent->window),			   ButtonMotionMask, &xevent)) {    synthEvent = PR_TRUE;  }  nsMouseEvent event;  InitMouseEvent(event, NS_MOUSE_MOVE);   if (synthEvent) {    event.point.x = nscoord(xevent.xmotion.x);    event.point.y = nscoord(xevent.xmotion.y);    event.isShift   = (xevent.xmotion.state & GDK_SHIFT_MASK)      ? PR_TRUE : PR_FALSE;    event.isControl = (xevent.xmotion.state & GDK_CONTROL_MASK)      ? PR_TRUE : PR_FALSE;    event.isAlt     = (xevent.xmotion.state & GDK_MOD1_MASK)      ? PR_TRUE : PR_FALSE;  }  else {    event.point.x = nscoord(aEvent->x);    event.point.y = nscoord(aEvent->y);    event.isShift   = (aEvent->state & GDK_SHIFT_MASK)      ? PR_TRUE : PR_FALSE;    event.isControl = (aEvent->state & GDK_CONTROL_MASK)      ? PR_TRUE : PR_FALSE;    event.isAlt     = (aEvent->state & GDK_MOD1_MASK)      ? PR_TRUE : PR_FALSE;  }  nsEventStatus status;  DispatchEvent(&event, status);}voidnsWindow::OnButtonPressEvent(GtkWidget *aWidget, GdkEventButton *aEvent){  nsMouseEvent  event;  PRUint32      eventType;  nsEventStatus status;  switch (aEvent->button) {  case 2:    eventType = NS_MOUSE_MIDDLE_BUTTON_DOWN;    break;  case 3:    eventType = NS_MOUSE_RIGHT_BUTTON_DOWN;    break;  default:    eventType = NS_MOUSE_LEFT_BUTTON_DOWN;    break;  }  InitButtonEvent(event, eventType, aEvent);    DispatchEvent(&event, status);  // right menu click on linux should also pop up a context menu  if (eventType == NS_MOUSE_RIGHT_BUTTON_DOWN) {    InitButtonEvent(event, NS_CONTEXTMENU, aEvent);    DispatchEvent(&event, status);  }}voidnsWindow::OnButtonReleaseEvent(GtkWidget *aWidget, GdkEventButton *aEvent){  nsMouseEvent  event;  PRUint32      eventType;  switch (aEvent->button) {  case 2:    eventType = NS_MOUSE_MIDDLE_BUTTON_UP;    break;  case 3:    eventType = NS_MOUSE_RIGHT_BUTTON_UP;    break;    // don't send events for these types  case 4:  case 5:    return;    break;    // default including button 1 is left button up  default:    eventType = NS_MOUSE_LEFT_BUTTON_UP;    break;  }  InitButtonEvent(event, eventType, aEvent);  nsEventStatus status;  DispatchEvent(&event, status);}voidnsWindow::OnContainerFocusInEvent(GtkWidget *aWidget, GdkEventFocus *aEvent){  // Return if someone has blocked events for this widget.  This will  // happen if someone has called gtk_widget_grab_focus() from  // nsWindow::SetFocus() and will prevent recursion.  if (mContainerBlockFocus)    return;  if (mIsTopLevel)    gJustGotActivate = PR_TRUE;  // dispatch a got focus event  DispatchGotFocusEvent();}voidnsWindow::OnContainerFocusOutEvent(GtkWidget *aWidget, GdkEventFocus *aEvent){  // send a lost focus event for the child window  if (mFocusChild) {    mFocusChild->LoseFocus();    mFocusChild->DispatchDeactivateEvent();    mFocusChild = nsnull;  }}gbooleannsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent){  // work around for annoying things.  if (aEvent->keyval == GDK_Tab)    if (aEvent->state & GDK_CONTROL_MASK)      if (aEvent->state & GDK_MOD1_MASK)        return FALSE;  // Don't pass shift, control and alt as key press events  if (aEvent->keyval == GDK_Shift_L      || aEvent->keyval == GDK_Shift_R      || aEvent->keyval == GDK_Control_L      || aEvent->keyval == GDK_Control_R      || aEvent->keyval == GDK_Alt_L      || aEvent->keyval == GDK_Alt_R)    return TRUE;  // If the key repeat flag isn't set then set it so we don't send  // another key down event on the next key press -- DOM events are  // key down, key press and key up.  X only has key press and key  // release.  gtk2 already filters the extra key release events for  // us.  nsEventStatus status;  nsKeyEvent event;  if (!mInKeyRepeat) {    mInKeyRepeat = PR_TRUE;    // send the key down event    InitKeyEvent(event, aEvent, NS_KEY_DOWN);    DispatchEvent(&event, status);  }    InitKeyEvent(event, aEvent, NS_KEY_PRESS);  event.charCode = nsConvertCharCodeToUnicode(aEvent);  if (event.charCode) {    event.keyCode = 0;    // if the control, meta, or alt key is down, then we should leave    // the isShift flag alone (probably not a printable character)    // if none of the other modifier keys are pressed then we need to    // clear isShift so the character can be inserted in the editor    if (!event.isControl && !event.isAlt && !event.isMeta)      event.isShift = PR_FALSE;  }  // send the key press event  DispatchEvent(&event, status);  return TRUE;}gbooleannsWindow::OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent){  // unset the repeat flag  mInKeyRepeat = PR_FALSE;  // send the key event as a key up event  // Don't pass shift, control and alt as key press events  if (aEvent->keyval == GDK_Shift_L      || aEvent->keyval == GDK_Shift_R      || aEvent->keyval == GDK_Control_L      || aEvent->keyval == GDK_Control_R      || aEvent->keyval == GDK_Alt_L      || aEvent->keyval == GDK_Alt_R)    return TRUE;  nsKeyEvent event;  InitKeyEvent(event, aEvent, NS_KEY_UP);  nsEventStatus status;  DispatchEvent(&event, status);  return TRUE;}voidnsWindow::OnScrollEvent(GtkWidget *aWidget, GdkEventScroll *aEvent){  nsMouseScrollEvent event;  InitMouseScrollEvent(event, aEvent, NS_MOUSE_SCROLL);  nsEventStatus status;  DispatchEvent(&event, status);}voidnsWindow::OnVisibilityNotifyEvent(GtkWidget *aWidget,				  GdkEventVisibility *aEvent){  switch (aEvent->state) {  case GDK_VISIBILITY_UNOBSCURED:  case GDK_VISIBILITY_PARTIAL:    mIsVisible = PR_TRUE;    // if we have to retry the grab, retry it.    if (mRetryGrab)      NativeGrab(PR_TRUE);    break;  default: // includes GDK_VISIBILITY_FULLY_OBSCURED    mIsVisible = PR_FALSE;    break;  }}nsresultnsWindow::NativeCreate(nsIWidget        *aParent,		       nsNativeWidget    aNativeParent,		       const nsRect     &aRect,		       EVENT_CALLBACK    aHandleEventFunction,		       nsIDeviceContext *aContext,		       nsIAppShell      *aAppShell,		       nsIToolkit       *aToolkit,		       nsWidgetInitData *aInitData){  // only set the base parent if we're going to be a dialog or a  // toplevel  nsIWidget *baseParent = aInitData &&    (aInitData->mWindowType == eWindowType_dialog ||     aInitData->mWindowType == eWindowType_toplevel) ?    nsnull : aParent;  // initialize all the common bits of this class  BaseCreate(baseParent, aRect, aHandleEventFunction, aContext,	     aAppShell, aToolkit, aInitData);    // and do our common creation  CommonCreate(aParent, aNativeParent);  // save our bounds  mBounds = aRect;  // figure out our parent window  MozDrawingarea *parentArea = nsnull;  MozContainer   *parentContainer = nsnull;  GtkWindow      *topLevelParent = nsnull;  if (aParent || aNativeParent) {    GdkWindow *parentWindow;    // get the drawing area and the container from the parent    if (aParent)      parentWindow = GDK_WINDOW(aParent->GetNativeData(NS_NATIVE_WINDOW));    else      parentWindow = GDK_WINDOW(aNativeParent);    // find the mozarea on that window    gpointer user_data = nsnull;    user_data = g_object_get_data(G_OBJECT(parentWindow), "mozdrawingarea");    parentArea = MOZ_DRAWINGAREA(user_data);    NS_ASSERTION(parentArea, "no drawingarea for parent widget!\n");    if (!parentArea)      return NS_ERROR_FAILURE;    // get the user data for the widget - it should be a container    user_data = nsnull;    gdk_window_get_user_data(parentArea->inner_window, &user_data);    NS_ASSERTION(user_data, "no user data for parentArea\n");    if (!user_data)      return NS_ERROR_FAILURE;    // XXX support generic containers here for embedding!    parentContainer = MOZ_CONTAINER(user_data);    NS_ASSERTION(parentContainer, "owning widget is not a mozcontainer!\n");    if (!parentContainer)      return NS_ERROR_FAILURE;    // get the toplevel window just in case someone needs to use it    // for setting transients or whatever.    topLevelParent =      GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(parentContainer)));  }  // ok, create our windows  switch (mWindowType) {  case eWindowType_dialog:  case eWindowType_popup:  case eWindowType_toplevel:    {      mIsTopLevel = PR_TRUE;      if (mWindowType == eWindowType_dialog) {	mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);	gtk_window_set_type_hint(GTK_WINDOW(mShell),				 GDK_WINDOW_TYPE_HINT_DIALOG);	gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);	mTransientParent = topLevelParent;	// add ourselves to the parent window's window group	if (parentArea) {	  nsWindow *parentnsWindow =	    get_window_for_gdk_window(parentArea->inner_window);	  NS_ASSERTION(parentnsWindow, "no nsWindow for parentArea!");	  if (parentnsWindow && parentnsWindow->mWindowGroup) {	    gtk_window_group_add_window(parentnsWindow->mWindowGroup,					GTK_WINDOW(mShell));	    // store this in case any children are created	    mWindowGroup = parentnsWindow->mWindowGroup;	    LOG(("adding window %p to group %p\n",		 (void *)mShell, (void *)mWindowGroup));	  }	}      }      else if (mWindowType == eWindowType_popup) {	mShell = gtk_window_new(GTK_WINDOW_POPUP);	gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);	mTransientParent = topLevelParent;      }      else { // must be eWindowType_toplevel	mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);	// each toplevel window gets its own window group	mWindowGroup = gtk_window_group_new();	// and add ourselves to the window group	LOG(("adding window %p to new group %p\n",	     (void *)mShell, (void *)mWindowGroup));	gtk_window_group_add_window(mWindowGroup, GTK_WINDOW(mShell));      }      // create our container      mContainer = MOZ_CONTAINER(moz_container_new());      gtk_container_add(GTK_CONTAINER(mShell), GTK_WIDGET(mContainer));      gtk_widget_realize(GTK_WIDGET(mContainer));      // make sure this is the focus widget in the container      gtk_window_set_focus(GTK_WINDOW(mShell), GTK_WIDGET(mContainer));      // and the drawing area      mDrawingarea = moz_drawingarea_new(nsnull, mContainer);    }    break;  case eWindowType_child:    {      mDrawingarea = moz_drawingarea_new(parentArea, parentContainer);    }    break;  default:    break;  }  // label the drawing area with this object so we can find our way  // home  g_object_set_data(G_OBJECT(mDrawingarea->clip_window), "nsWindow",		    this);  g_object_set_data(G_OBJECT(mDrawingarea->inner_window), "nsWindow",		    this);  g_object_set_data(G_OBJECT(mDrawingarea->clip_window), "mozdrawingarea",		    mDrawingarea);  g_object_set_data(G_OBJECT(mDrawingarea->inner_window), "mozdrawingarea",		    mDrawingarea);  if (mContainer)    g_object_set_data(G_OBJECT(mContainer), "nsWindow", this);  if (mShell)    g_object_set_data(G_OBJECT(mShell), "nsWindow", this);  // attach listeners for events  if (mShell) {    g_signal_connect(G_OBJECT(mShell), "configure_event",		     G_CALLBACK(configure_event_cb), NULL);    g_signal_connect(G_OBJECT(mShell), "delete_event",		     G_CALLBACK(delete_event_cb), NULL);  }  if (mContainer) {    g_signal_connect_after(G_OBJECT(mContainer), "size_allocate",			   G_CALLBACK(size_allocate_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "expose_event",		     G_CALLBACK(expose_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "enter_notify_event",		     G_CALLBACK(enter_notify_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "leave_notify_event",		     G_CALLBACK(leave_notify_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "motion_notify_event",		     G_CALLBACK(motion_notify_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "button_press_event",		     G_CALLBACK(button_press_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "button_release_event",		     G_CALLBACK(button_release_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "focus_in_event",		     G_CALLBACK(focus_in_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "focus_out_event",		     G_CALLBACK(focus_out_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "key_press_event",		     G_CALLBACK(key_press_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "key_release_event",		     G_CALLBACK(key_release_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "scroll_event",		     G_CALLBACK(scroll_event_cb), NULL);    g_signal_connect(G_OBJECT(mContainer), "visibility_notify_event",		     G_CALLBACK(visibility_notify_event_cb), NULL);  }  LOG(("nsWindow [%p]\n", (void *)this));  if (mShell) {    LOG(("\tmShell %p %p %lx\n", (void *)mShell, (void *)mShell->window,	 GDK_WINDOW_XWINDOW(mShell->window)));  }  if (mContainer) {    LOG(("\tmContainer %p %p %lx\n", (void *)mContainer,	 (void *)GTK_WIDGET(mContainer)->window,	 GDK_WINDOW_XWINDOW(GTK_WIDGET(mContainer)->window)));  }  if (mDrawingarea) {    LOG(("\tmDrawingarea %p %p %p %lx %lx\n", (void *)mDrawingarea,	 (void *)mDrawingarea->clip_window,	 (void *)mDrawingarea->inner_window,	 GDK_WINDOW_XWINDOW(mDrawingarea->clip_window),	 GDK_WINDOW_XWINDOW(mDrawingarea->inner_window)));  }  // resize so that everything is set to the right dimensions  Resize(mBounds.width, mBounds.height, PR_FALSE);  return NS_OK;}voidnsWindow::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool  aRepaint){  LOG(("nsWindow::NativeResize [%p] %d %d\n", (void *)this,       aWidth, aHeight));  // clear our resize flag  mNeedsResize = PR_FALSE;  if (mIsTopLevel)    gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);    moz_drawingarea_resize (mDrawingarea, aWidth, aHeight);}voidnsWindow::NativeResize(PRInt32 aX, PRInt32 aY,		       PRInt32 aWidth, PRInt32 aHeight,		       PRBool  aRepaint){  mNeedsResize = PR_FALSE;    LOG(("nsWindow::NativeResize [%p] %d %d %d %d\n", (void *)this,       aX, aY, aWidth, aHeight));    if (mIsTopLevel) {    if (mParent && mWindowType == eWindowType_popup) {      nsRect oldrect, newrect;      oldrect.x = aX;      oldrect.y = aY;      mParent->WidgetToScreen(oldrect, newrect);      moz_drawingarea_resize(mDrawingarea, aWidth, aHeight);      gtk_window_move(GTK_WINDOW(mShell), newrect.x, newrect.y);      gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);    }    else {      gtk_window_move(GTK_WINDOW(mShell), aX, aY);      gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);      moz_drawingarea_resize(mDrawingarea, aWidth, aHeight);    }  }  else {    moz_drawingarea_move_resize(mDrawingarea, aX, aY, aWidth, aHeight);  }}voidnsWindow::NativeShow (PRBool  aAction){  if (aAction) {    // unset our flag now that our window has been shown    mNeedsShow = PR_FALSE;        if (mIsTopLevel) {      moz_drawingarea_set_visibility(mDrawingarea, aAction);      gtk_widget_show(GTK_WIDGET(mContainer));      gtk_widget_show(mShell);          }    else {      moz_drawingarea_set_visibility(mDrawingarea, aAction);    }  }  else {    if (mIsTopLevel) {      gtk_widget_hide(GTK_WIDGET(mShell));      gtk_widget_hide(GTK_WIDGET(mContainer));    }    moz_drawingarea_set_visibility(mDrawingarea, aAction);  }}voidnsWindow::NativeGrab(PRBool aGrab){  LOG(("NativeGrab aGrab %d mRetryGrab %d\n", aGrab, mRetryGrab));  // Clear the retry flag.  It doesn't matter if it's being released  // or grabbed.  mRetryGrab = PR_FALSE;  if (aGrab) {    // If the window isn't visible, just set the flag to retry the    // grab.  When this window becomes visible, the grab will be    // retried.    PRBool visibility = PR_TRUE;    IsVisible(visibility);    if (!visibility) {      LOG(("window not visible\n"));      mRetryGrab = PR_TRUE;      return;    }    GdkCursor *cursor = gdk_cursor_new(GDK_ARROW);        gint retval;    retval = gdk_pointer_grab(mDrawingarea->inner_window, PR_TRUE,			      (GdkEventMask)(GDK_BUTTON_PRESS_MASK |					     GDK_BUTTON_RELEASE_MASK |					     GDK_ENTER_NOTIFY_MASK |					     GDK_LEAVE_NOTIFY_MASK |					     GDK_POINTER_MOTION_MASK),			      (GdkWindow *)NULL, cursor, GDK_CURRENT_TIME);    // now that we're done with the cursor, destroy it    gdk_cursor_destroy(cursor);    if (retval != GDK_GRAB_SUCCESS) {      LOG(("pointer grab failed\n"));      mRetryGrab = PR_TRUE;      return;    }    GdkWindow *grabWindow;    // we need to grab the keyboard on the transient parent so that we    // don't end up with any focus events that end up on the parent    // window that will cause the popup to go away    if (mTransientParent)      grabWindow = GTK_WIDGET(mTransientParent)->window;    else      grabWindow = mDrawingarea->inner_window;    retval = gdk_keyboard_grab(grabWindow, PR_TRUE, GDK_CURRENT_TIME);    if (retval != GDK_GRAB_SUCCESS) {      LOG(("keyboard grab failed %d\n", retval));      gdk_pointer_ungrab(GDK_CURRENT_TIME);      mRetryGrab = PR_TRUE;      return;    }  }  else {    gdk_pointer_ungrab(GDK_CURRENT_TIME);    gdk_keyboard_ungrab(GDK_CURRENT_TIME);  }}voidnsWindow::GetToplevelWidget(GtkWidget **aWidget){  *aWidget = nsnull;  if (mShell) {    *aWidget = mShell;    return;  }  gpointer user_data = nsnull;  gdk_window_get_user_data(mDrawingarea->inner_window, &user_data);  NS_ASSERTION(user_data, "no user data for parentArea\n");    if (!user_data)    return;    *aWidget = gtk_widget_get_toplevel(GTK_WIDGET(user_data));}/* static */nsWindow *get_window_for_gtk_widget(GtkWidget *widget){  gpointer user_data;  user_data = g_object_get_data(G_OBJECT(widget), "nsWindow");  if (!user_data)    return nsnull;  return NS_STATIC_CAST(nsWindow *, user_data);}/* static */nsWindow *get_window_for_gdk_window(GdkWindow *window){  gpointer user_data;  user_data = g_object_get_data(G_OBJECT(window), "nsWindow");  if (!user_data)    return nsnull;    return NS_STATIC_CAST(nsWindow *, user_data);}/* static */nsWindow *get_owning_window_for_gdk_window(GdkWindow *window){  gpointer user_data;  gdk_window_get_user_data(window, &user_data);  if (!user_data)    return nsnull;  GtkWidget *owningWidget = GTK_WIDGET(user_data);    if (!owningWidget)    return nsnull;  user_data = NULL;  user_data = g_object_get_data(G_OBJECT(owningWidget), "nsWindow");    if (!user_data)    return nsnull;  return (nsWindow *)user_data;}// gtk callbacks/* static */gbooleanexpose_event_cb(GtkWidget *widget, GdkEventExpose *event){  nsWindow *window = get_window_for_gdk_window(event->window);  if (!window)    return FALSE;  // XXX We are so getting lucky here.  We are doing all of  // mozilla's painting and then allowing default processing to occur.  // This means that Mozilla paints in all of it's stuff and then  // NO_WINDOW widgets (like scrollbars, for example) are painted by  // Gtk on top of what we painted.  // This return window->OnExposeEvent(widget, event); */  window->OnExposeEvent(widget, event);  return FALSE;}/* static */gbooleanconfigure_event_cb(GtkWidget *widget,		   GdkEventConfigure *event){  nsWindow *window = get_window_for_gtk_widget(widget);  if (!window)    return FALSE;    return window->OnConfigureEvent(widget, event);}/* static */voidsize_allocate_cb (GtkWidget *widget, GtkAllocation *allocation){  nsWindow *window = get_window_for_gtk_widget(widget);  if (!window)    return;  window->OnSizeAllocate(widget, allocation);}/* static */gbooleandelete_event_cb(GtkWidget *widget, GdkEventAny *event){  nsWindow *window = get_window_for_gtk_widget(widget);  if (!window)    return FALSE;  window->OnDeleteEvent(widget, event);  return TRUE;}/* static */gbooleanenter_notify_event_cb (GtkWidget *widget,				GdkEventCrossing *event){  nsWindow *window = get_window_for_gdk_window(event->window);  if (!window)    return TRUE;    window->OnEnterNotifyEvent(widget, event);  return TRUE;}/* static */gbooleanleave_notify_event_cb (GtkWidget *widget,		       GdkEventCrossing *event){  nsWindow *window = get_window_for_gdk_window(event->window);  if (!window)    return TRUE;    window->OnLeaveNotifyEvent(widget, event);  return TRUE;}/* static */gbooleanmotion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event){  nsWindow *window = get_window_for_gdk_window(event->window);  if (!window)    return TRUE;  window->OnMotionNotifyEvent(widget, event);  return TRUE;}