event->any.window = window->GetOwningWidget()->window;
event->any.window = owningWidget->window;
handle_gdk_event (GdkEvent *event, gpointer data){  GtkObject *eventObject = nsnull;  // set the last time that we got an event.  we need this for drag  // and drop if you can believe that.  guint32 event_time = gdk_event_get_time(event);  if (event_time)    nsWidget::SetLastEventTime(event_time);  // Get the next X event serial ID and save it for later for event  // processing.  If it stays zero then events won't be processed  // later.  We're using this as a flag too but with a number this big  // we're probably not going to overflow and even if we did there  // wouldn't be any harm.  unsigned long serial = 0;  if (XPending(GDK_DISPLAY())) {    XEvent temp_event;    XPeekEvent(GDK_DISPLAY(), &temp_event);    serial = temp_event.xany.serial - 1;  }  // try to get the user data for the event window.  if (event->any.window)    gdk_window_get_user_data (event->any.window, (void **)&eventObject);  // If there is an event object and it's a superwin then we need to  // make sure that the event either is handled locally or is passed  // on with a legitimate GtkWidget object associated with it so the  // Gtk mainloop doesn't go spastic.  if (eventObject && GDK_IS_SUPERWIN(eventObject)) {    // try to find the nsWindow object associated with this superwin    nsWindow *window = (nsWindow *)gtk_object_get_data (eventObject,                                                        "nsWindow");    // If we don't have a window here anymore, we are probably in    // the process of being or have been destroyed.  give up now.    if (!window)      goto end;    // Get the grabbing widget, if there is one.  We will need this    // later.    GtkWidget *grabWidget;    grabWidget = gtk_grab_get_current();    PRBool grabIsRegularWidget = (grabWidget && !GTK_IS_MOZAREA(grabWidget));    // There are a lot of events that are always dispatched to our    // internal handler, no matter if there is a grab or not.    switch(event->type)      {      case GDK_NOTHING:        break;      case GDK_DESTROY:      case GDK_DELETE:      case GDK_PROPERTY_NOTIFY:      case GDK_EXPOSE:      case GDK_NO_EXPOSE:      case GDK_FOCUS_CHANGE:      case GDK_CONFIGURE:      case GDK_MAP:      case GDK_UNMAP:      case GDK_SELECTION_CLEAR:      case GDK_SELECTION_REQUEST:      case GDK_SELECTION_NOTIFY:      case GDK_CLIENT_EVENT:      case GDK_VISIBILITY_NOTIFY:        dispatch_superwin_event(event, window);        break;      case GDK_BUTTON_PRESS:      case GDK_2BUTTON_PRESS:      case GDK_3BUTTON_PRESS:      case GDK_KEY_PRESS:      case GDK_KEY_RELEASE:        // Always rewrite the event to the grab widget.  If it's a        // MozArea widget, the handler will get called as normal.        if (grabWidget &&            !gdk_window_child_of_gdk_window(window->GetOwningWidget()->window,                                            grabWidget->window)) {          gdk_window_unref(event->any.window);          event->any.window = grabWidget->window;          gdk_window_ref(event->any.window);          gtk_main_do_event(event);          break;        }        // Otherwise, just send it to our event handler        dispatch_superwin_event(event, window);        break;      case GDK_MOTION_NOTIFY:      case GDK_BUTTON_RELEASE:      case GDK_PROXIMITY_IN:      case GDK_PROXIMITY_OUT:        // We only rewrite these events if the grab happens on a        // non-mozilla window.  Menus get really sad if we don't do it        // this way since they expect to get events on their native        // windows, no matter if there is a grab in effect or not.        if (grabIsRegularWidget &&            !gdk_window_child_of_gdk_window(window->GetOwningWidget()->window,                                            grabWidget->window)) {          // We rewrite the event to the nearest "real" widget so that          // the gtk mainloop doesn't get confuse-ed.          gdk_window_unref(event->any.window);          event->any.window = window->GetOwningWidget()->window;          gdk_window_ref(event->any.window);          gtk_propagate_event(grabWidget, event);          if (event->type == GDK_BUTTON_RELEASE) {            // Always clear the button motion target when sending a            // button release event to a real gtk widget, otherwise            // mozilla will still think it has the grab.  This happens            // when there's a native gtk widget popup over a Mozilla            // area.            nsWidget::DropMotionTarget();          }          break;        }        dispatch_superwin_event(event, window);        break;      case GDK_ENTER_NOTIFY:      case GDK_LEAVE_NOTIFY:        // We rewrite the event to the nearest "real" widget so that        // the gtk mainloop doesn't get confuse-ed.        if (grabWidget &&            gdk_window_child_of_gdk_window(window->GetOwningWidget()->window,                                           grabWidget->window)) {          gdk_window_unref(event->any.window);          event->any.window = window->GetOwningWidget()->window;          gdk_window_ref(event->any.window);          gtk_widget_event(grabWidget, event);          break;        }        // XXX these should track sensitivity!        dispatch_superwin_event(event, window);        break;      default:        // XXX lots of DND events not handled?  I don't think that we have to.        NS_WARNING("Odd, hit default case in handle_gdk_event()\n");        break;      }  }  else {    nsWindow  *grabbingWindow = nsWindow::GetGrabWindow();        nsCOMPtr<nsIWidget> grabbingWindowGuard(grabbingWindow);    GtkWidget *tempWidget = NULL;        if (grabbingWindow) {      // get the GdkWindow that we are grabbing on      GdkWindow *grabbingGdkWindow =        NS_STATIC_CAST(GdkWindow *,                       grabbingWindow->GetNativeData(NS_NATIVE_WINDOW));            // If the object getting the event in question is a GtkWidget      // and it's a child of the grabbing window, we need to put a      // grab on that window before dispatching the event.  We do this      // so that the gtk mainloop will recognize the widget in      // question as having the grab.  If we didn't the mainloop      // wouldn't think that the widget that got the event is the      // child of the grabbing window, due to the superwin(s) in the      // middle.      if (GTK_IS_WIDGET(eventObject)) {        tempWidget = GTK_WIDGET(eventObject);        if (gdk_window_child_of_gdk_window(tempWidget->window,                                           grabbingGdkWindow)) {          // this is so awesome.  gtk_grab_add/gtk_grab_remove don't          // have exact push and pop semantics.  if we call grab_add          // on the object and as part of the dispatching of this          // event another grab_add is called on it, we can end up          // releasing the grab early because we always call          // grab_remove on the object after dispatching the event.          // we can end up with a widget that doesn't have a grab on          // it, even though it should.  the scrollbar does this.          //          // so, what we do here is to check and see if the widget in          // question has a parent.  if it does and it's a mozbox          // object we slam a grab on that instead of the widget          // itself.  we know that no one is doing grabs on those.          if (tempWidget->parent) {            if (GTK_IS_MOZBOX(tempWidget->parent)) {              tempWidget = tempWidget->parent;            }          }          gtk_grab_add(tempWidget);        }        else  {          // if the gtk widget in question wasn't the child of the          // grabbing window then the grabbing window gets it.          dispatch_superwin_event(event, grabbingWindow);          goto end;        }      }    }    gtk_main_do_event(event);    if (tempWidget)      gtk_grab_remove(tempWidget);    if (event->type == GDK_BUTTON_RELEASE) {      // Always clear the button motion target when sending a      // button release event to a real gtk widget, otherwise      // mozilla will still think it has the grab.  This happens      // when there's a native gtk widget popup over a Mozilla      // area.      nsWidget::DropMotionTarget();    }  } end:  // use the saved serial to process any pending events, now that all  // the window events have been processed  if (serial)    nsAppShell::ProcessBeforeID(serial);}