Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / gtk / gtk_input_event_box.cc
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/gtk/gtk_input_event_box.h"
6
7 #include <gdk/gdk.h>
8 #include <gtk/gtk.h>
9
10 G_BEGIN_DECLS
11
12 #define GTK_INPUT_EVENT_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
13                                             GTK_TYPE_INPUT_EVENT_BOX, \
14                                             GtkInputEventBoxPrivate))
15
16 typedef struct _GtkInputEventBoxPrivate GtkInputEventBoxPrivate;
17
18 struct _GtkInputEventBoxPrivate {
19   GdkWindow* event_window;
20 };
21
22 G_DEFINE_TYPE(GtkInputEventBox, gtk_input_event_box, GTK_TYPE_BIN)
23
24 static void gtk_input_event_box_realize(GtkWidget* widget);
25 static void gtk_input_event_box_unrealize(GtkWidget* widget);
26 static void gtk_input_event_box_map(GtkWidget* widget);
27 static void gtk_input_event_box_unmap(GtkWidget* widget);
28 static void gtk_input_event_box_size_allocate(GtkWidget* widget,
29                                               GtkAllocation* allocation);
30 static void gtk_input_event_box_size_request(GtkWidget* widget,
31                                              GtkRequisition* requisition);
32
33 static void gtk_input_event_box_class_init(GtkInputEventBoxClass* klass) {
34   GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass);
35   widget_class->realize = gtk_input_event_box_realize;
36   widget_class->unrealize = gtk_input_event_box_unrealize;
37   widget_class->map = gtk_input_event_box_map;
38   widget_class->unmap = gtk_input_event_box_unmap;
39   widget_class->size_allocate = gtk_input_event_box_size_allocate;
40   widget_class->size_request = gtk_input_event_box_size_request;
41
42   GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
43   g_type_class_add_private(gobject_class, sizeof(GtkInputEventBoxPrivate));
44 }
45
46 static void gtk_input_event_box_init(GtkInputEventBox* widget) {
47   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
48   priv->event_window = NULL;
49 }
50
51 GtkWidget* gtk_input_event_box_new() {
52   return GTK_WIDGET(g_object_new(GTK_TYPE_INPUT_EVENT_BOX, NULL));
53 }
54
55 static void gtk_input_event_box_realize(GtkWidget* widget) {
56   g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget));
57
58   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
59
60   GdkWindow* parent = gtk_widget_get_parent_window(widget);
61   GdkWindowAttr attributes;
62   GtkAllocation allocation;
63   gint attributes_mask = GDK_WA_X | GDK_WA_Y;
64
65   gtk_widget_get_allocation(widget, &allocation);
66
67   attributes.x = allocation.x;
68   attributes.y = allocation.y;
69   attributes.width = allocation.width;
70   attributes.height = allocation.height;
71
72   attributes.window_type = GDK_WINDOW_CHILD;
73   attributes.wclass = GDK_INPUT_ONLY;
74
75   attributes.event_mask = gtk_widget_get_events(widget) |
76       GDK_BUTTON_MOTION_MASK |
77       GDK_BUTTON_PRESS_MASK |
78       GDK_BUTTON_RELEASE_MASK |
79       GDK_EXPOSURE_MASK |
80       GDK_ENTER_NOTIFY_MASK |
81       GDK_LEAVE_NOTIFY_MASK;
82
83   priv->event_window = gdk_window_new(parent, &attributes, attributes_mask);
84   gdk_window_set_user_data(priv->event_window, widget);
85
86   GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->realize(widget);
87 }
88
89 static void gtk_input_event_box_unrealize(GtkWidget* widget) {
90   g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget));
91
92   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
93   if (priv->event_window) {
94     gdk_window_set_user_data(priv->event_window, NULL);
95     gdk_window_destroy(priv->event_window);
96     priv->event_window = NULL;
97   }
98
99   GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->unrealize(widget);
100 }
101
102 static void gtk_input_event_box_map(GtkWidget* widget) {
103   g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget));
104
105   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
106   if (priv->event_window)
107     gdk_window_show(priv->event_window);
108
109   GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->map(widget);
110 }
111
112 static void gtk_input_event_box_unmap(GtkWidget* widget) {
113   g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget));
114
115   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
116   if (priv->event_window)
117     gdk_window_hide(priv->event_window);
118
119   GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->unmap(widget);
120 }
121
122 static void gtk_input_event_box_size_allocate(GtkWidget* widget,
123                                               GtkAllocation* allocation) {
124   g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget));
125
126   gtk_widget_set_allocation(widget, allocation);
127
128   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
129   if (priv->event_window) {
130     gdk_window_move_resize(priv->event_window,
131                            allocation->x,
132                            allocation->y,
133                            allocation->width,
134                            allocation->height);
135   }
136
137   GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget));
138   if (child)
139     gtk_widget_size_allocate(child, allocation);
140 }
141
142 static void gtk_input_event_box_size_request(GtkWidget* widget,
143                                              GtkRequisition* requisition) {
144
145   GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget));
146   if (child)
147     gtk_widget_size_request(child, requisition);
148 }
149
150 GdkWindow* gtk_input_event_box_get_window(GtkInputEventBox* widget) {
151   g_return_val_if_fail(GTK_IS_INPUT_EVENT_BOX(widget), NULL);
152
153   GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget);
154   return priv->event_window;
155 }
156
157 G_END_DECLS