/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org Code. * * The Initial Developer of the Original Code is * Owen Taylor and Christopher Blizzard * . * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "gtkmozbox.h" #include #include static void gtk_mozbox_class_init (GtkMozBoxClass *klass); static void gtk_mozbox_init (GtkMozBox *mozbox); static void gtk_mozbox_realize (GtkWidget *widget); static void gtk_mozbox_set_focus (GtkWindow *window, GtkWidget *focus); static gint gtk_mozbox_key_press_event (GtkWidget *widget, GdkEventKey *event); static GdkFilterReturn gtk_mozbox_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data); static GtkWindow * gtk_mozbox_get_parent_gtkwindow (GtkMozBox *mozbox); void (*parent_class_set_focus)(GtkWindow *, GtkWidget *); GtkType gtk_mozbox_get_type (void) { static GtkType mozbox_type = 0; if (!mozbox_type) { static const GtkTypeInfo mozbox_info = { "GtkMozBox", sizeof (GtkMozBox), sizeof (GtkMozBoxClass), (GtkClassInitFunc) gtk_mozbox_class_init, (GtkObjectInitFunc) gtk_mozbox_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL }; mozbox_type = gtk_type_unique (GTK_TYPE_WINDOW, &mozbox_info); } return mozbox_type; } static void gtk_mozbox_class_init (GtkMozBoxClass *klass) { GtkWidgetClass *widget_class; GtkWindowClass *window_class; widget_class = GTK_WIDGET_CLASS (klass); window_class = GTK_WINDOW_CLASS (klass); widget_class->realize = gtk_mozbox_realize; widget_class->key_press_event = gtk_mozbox_key_press_event; /* save the parent class' set_focus method */ parent_class_set_focus = window_class->set_focus; window_class->set_focus = gtk_mozbox_set_focus; } static void gtk_mozbox_init (GtkMozBox *mozbox) { mozbox->parent_window = NULL; mozbox->x = 0; mozbox->y = 0; } static void gtk_mozbox_realize (GtkWidget *widget) { GdkWindowAttr attributes; gint attributes_mask; GtkMozBox *mozbox; g_return_if_fail (GTK_IS_MOZBOX (widget)); mozbox = GTK_MOZBOX (widget); /* GtkWindow checks against premature realization here. Just * don't do it. */ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); attributes.window_type = GDK_WINDOW_CHILD; attributes.x = mozbox->x; attributes.y = mozbox->y; attributes.width = widget->allocation.width; attributes.height = widget->allocation.height; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); attributes.event_mask |= GDK_EXPOSURE_MASK; attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; widget->window = gdk_window_new (mozbox->parent_window, &attributes, attributes_mask); /* set the back pixmap to None so that you don't end up with the gtk default which is BlackPixel */ gdk_window_set_back_pixmap (widget->window, NULL, FALSE); gdk_window_set_user_data (widget->window, mozbox); widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); gdk_window_add_filter (widget->window, gtk_mozbox_filter, mozbox); } static void gtk_mozbox_set_focus (GtkWindow *window, GtkWidget *focus) { GtkMozBox *mozbox; GdkWindow *tmpWindow; GtkWindow *parentGtkWindow; g_return_if_fail(window != NULL); g_return_if_fail(GTK_IS_MOZBOX(window)); mozbox = GTK_MOZBOX(window); parentGtkWindow = gtk_mozbox_get_parent_gtkwindow (mozbox); if (parentGtkWindow) { parent_class_set_focus(parentGtkWindow, focus); return; } /* as a fall back just hand it off to our parent class */ parent_class_set_focus(window, focus); } static gint gtk_mozbox_key_press_event (GtkWidget *widget, GdkEventKey *event) { GtkWindow *window; GtkMozBox *mozbox; GtkWindow *parentWindow; gboolean handled = FALSE; window = GTK_WINDOW (widget); mozbox = GTK_MOZBOX (widget); parentWindow = gtk_mozbox_get_parent_gtkwindow(mozbox); /* give the focus window the chance to handle the event first. */ if (parentWindow && parentWindow->focus_widget) { handled = gtk_widget_event (parentWindow->focus_widget, (GdkEvent*) event); } /* pass it off to the parent widget */ if (!handled) { gdk_window_unref(event->window); event->window = mozbox->parent_window; gdk_window_ref(event->window); gdk_event_put((GdkEvent *)event); } return TRUE; } static GdkFilterReturn gtk_mozbox_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) { XEvent *xev = xevent; GtkWidget *widget = data; switch (xev->xany.type) { case ConfigureNotify: event->configure.type = GDK_CONFIGURE; event->configure.window = widget->window; event->configure.x = 0; event->configure.y = 0; event->configure.width = xev->xconfigure.width; event->configure.height = xev->xconfigure.height; return GDK_FILTER_TRANSLATE; default: return GDK_FILTER_CONTINUE; } } static GtkWindow * gtk_mozbox_get_parent_gtkwindow (GtkMozBox *mozbox) { GdkWindow *tmpWindow; /* look for a parent GtkWindow in the heirarchy */ tmpWindow = mozbox->parent_window; while (tmpWindow) { gpointer data = NULL; gdk_window_get_user_data(tmpWindow, &data); if (data && GTK_IS_WINDOW(data)) { return GTK_WINDOW(data); } tmpWindow = gdk_window_get_parent(tmpWindow); } return NULL; } GtkWidget* gtk_mozbox_new (GdkWindow *parent_window) { GtkMozBox *mozbox; mozbox = gtk_type_new (GTK_TYPE_MOZBOX); mozbox->parent_window = parent_window; return GTK_WIDGET (mozbox); } void gtk_mozbox_set_position (GtkMozBox *mozbox, gint x, gint y) { mozbox->x = x; mozbox->y = y; if (GTK_WIDGET_REALIZED (mozbox)) gdk_window_move (GTK_WIDGET (mozbox)->window, x, y); }