]> code.delx.au - gnu-emacs/blob - src/emacsgtkfixed.c
upstream partial out of memory
[gnu-emacs] / src / emacsgtkfixed.c
1 /* A Gtk Widget that inherits GtkFixed, but can be shrunk.
2 This file is only use when compiling with Gtk+ 3.
3
4 Copyright (C) 2011-2012 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21 #include <config.h>
22
23 #include "emacsgtkfixed.h"
24 #include <signal.h>
25 #include <stdio.h>
26 #include <setjmp.h>
27 #include "lisp.h"
28 #include "frame.h"
29 #include "xterm.h"
30 #ifdef HAVE_XWIDGETS
31 #include "xwidget.h"
32 #endif
33 struct _EmacsFixedPrivate
34 {
35 struct frame *f;
36 };
37
38
39 static void emacs_fixed_get_preferred_width (GtkWidget *widget,
40 gint *minimum,
41 gint *natural);
42 static void emacs_fixed_get_preferred_height (GtkWidget *widget,
43 gint *minimum,
44 gint *natural);
45 G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
46
47 #ifdef HAVE_XWIDGETS
48 /* void aloc_callback(GtkWidget* child, GtkWidget* fixed){ */
49 /* GtkAllocation child_allocation; */
50 /* GtkRequisition child_requisition; */
51
52 /* //TODO */
53 /* // if child is an xwidget, find its clipping area and modify allocation */
54
55 /* struct xwidget_view* xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child), XG_XWIDGET_VIEW); */
56 /* printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child)); */
57 /* if(xv){ */
58 /* printf(" allocation modification for xw\n"); */
59 /* gtk_widget_get_allocation(child, &child_allocation); */
60 /* child_allocation.width = xv->clip_right; */
61 /* child_allocation.height = xv->clip_bottom - xv->clip_top; */
62 /* gtk_widget_size_allocate (child, &child_allocation); */
63 /* //TODO find a way to remove this feeble workaround */
64 /* } */
65
66 /* } */
67
68 struct GtkFixedPrivateL
69 {
70 GList *children;
71 };
72
73 static void emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
74 GtkAllocation *allocation){
75 //for xwidgets
76
77
78 //TODO 1st call base class method
79 EmacsFixedClass *klass;
80 GtkWidgetClass *parent_class;
81 struct GtkFixedPrivateL* priv;
82 GtkFixedChild *child;
83 GtkAllocation child_allocation;
84 GtkRequisition child_requisition;
85 GList *children;
86 struct xwidget_view* xv;
87
88 // printf(" emacs_fixed_gtk_widget_size_allocate\n");
89 klass = EMACS_FIXED_GET_CLASS (widget);
90 parent_class = g_type_class_peek_parent (klass);
91 parent_class->size_allocate (widget, allocation);
92
93 priv = G_TYPE_INSTANCE_GET_PRIVATE (widget,
94 GTK_TYPE_FIXED,
95 struct GtkFixedPrivateL);
96 //fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, GTK_TYPE_FIXED, GtkFixedPrivate);
97 //then modify allocations
98 /* gtk_container_foreach (widget, */
99 /* aloc_callback, */
100 /* widget); */
101
102 //begin copy paste extravaganza!!!
103
104 //GtkFixed *fixed = GTK_FIXED (widget);
105 //GtkFixedPrivate *priv = fixed->priv;
106
107
108 gtk_widget_set_allocation (widget, allocation);
109
110 if (gtk_widget_get_has_window (widget))
111 {
112 if (gtk_widget_get_realized (widget))
113 gdk_window_move_resize (gtk_widget_get_window (widget),
114 allocation->x,
115 allocation->y,
116 allocation->width,
117 allocation->height);
118 }
119
120 for (children = priv->children;
121 children;
122 children = children->next)
123 {
124 child = children->data;
125
126 if (!gtk_widget_get_visible (child->widget))
127 continue;
128
129 gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
130 child_allocation.x = child->x;
131 child_allocation.y = child->y;
132
133 if (!gtk_widget_get_has_window (widget))
134 {
135 child_allocation.x += allocation->x;
136 child_allocation.y += allocation->y;
137 }
138
139 child_allocation.width = child_requisition.width;
140 child_allocation.height = child_requisition.height;
141
142
143
144 xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW);
145 //printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child));
146 if(xv){
147 //gtk_widget_get_allocation(child, &child_allocation);
148 child_allocation.width = xv->clip_right;
149 child_allocation.height = xv->clip_bottom - xv->clip_top;
150 //gtk_widget_size_allocate (child, &child_allocation);
151 //TODO find a way to remove this feeble workaround
152 // printf(" allocation internal modification for xw %d %d,%d\n",xv, child_allocation.width, child_allocation.height);
153
154 }
155 gtk_widget_size_allocate (child->widget, &child_allocation);
156
157 }
158
159 }
160
161 #endif
162
163 static void
164 emacs_fixed_class_init (EmacsFixedClass *klass)
165 {
166 GtkWidgetClass *widget_class;
167 GtkFixedClass *fixed_class;
168
169 widget_class = (GtkWidgetClass*) klass;
170 fixed_class = (GtkFixedClass*) klass;
171
172 widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
173 widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
174 #ifdef HAVE_XWIDGETS
175 widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate;
176 #endif
177 g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
178 }
179
180 static GType
181 emacs_fixed_child_type (GtkFixed *container)
182 {
183 return GTK_TYPE_WIDGET;
184 }
185
186 static void
187 emacs_fixed_init (EmacsFixed *fixed)
188 {
189 fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, EMACS_TYPE_FIXED,
190 EmacsFixedPrivate);
191 fixed->priv->f = 0;
192 }
193
194 /**
195 * emacs_fixed_new:
196 *
197 * Creates a new #EmacsFixed.
198 *
199 * Returns: a new #EmacsFixed.
200 */
201 GtkWidget*
202 emacs_fixed_new (struct frame *f)
203 {
204 EmacsFixed *fixed = g_object_new (EMACS_TYPE_FIXED, NULL);
205 EmacsFixedPrivate *priv = fixed->priv;
206 priv->f = f;
207 return GTK_WIDGET (fixed);
208 }
209
210 static void
211 emacs_fixed_get_preferred_width (GtkWidget *widget,
212 gint *minimum,
213 gint *natural)
214 {
215 EmacsFixed *fixed = EMACS_FIXED (widget);
216 EmacsFixedPrivate *priv = fixed->priv;
217 int w = priv->f->output_data.x->size_hints.min_width;
218 if (minimum) *minimum = w;
219 if (natural) *natural = w;
220 }
221
222 static void
223 emacs_fixed_get_preferred_height (GtkWidget *widget,
224 gint *minimum,
225 gint *natural)
226 {
227 EmacsFixed *fixed = EMACS_FIXED (widget);
228 EmacsFixedPrivate *priv = fixed->priv;
229 int h = priv->f->output_data.x->size_hints.min_height;
230 if (minimum) *minimum = h;
231 if (natural) *natural = h;
232 }
233
234
235 /* Override the X function so we can intercept Gtk+ 3 calls.
236 Use our values for min_width/height so that KDE don't freak out
237 (Bug#8919), and so users can resize our frames as they wish. */
238
239 void
240 XSetWMSizeHints (Display* d,
241 Window w,
242 XSizeHints* hints,
243 Atom prop)
244 {
245 struct x_display_info *dpyinfo = x_display_info_for_display (d);
246 struct frame *f = x_top_window_to_frame (dpyinfo, w);
247 long data[18];
248 data[0] = hints->flags;
249 data[1] = hints->x;
250 data[2] = hints->y;
251 data[3] = hints->width;
252 data[4] = hints->height;
253 data[5] = hints->min_width;
254 data[6] = hints->min_height;
255 data[7] = hints->max_width;
256 data[8] = hints->max_height;
257 data[9] = hints->width_inc;
258 data[10] = hints->height_inc;
259 data[11] = hints->min_aspect.x;
260 data[12] = hints->min_aspect.y;
261 data[13] = hints->max_aspect.x;
262 data[14] = hints->max_aspect.y;
263 data[15] = hints->base_width;
264 data[16] = hints->base_height;
265 data[17] = hints->win_gravity;
266
267 if ((hints->flags & PMinSize) && f)
268 {
269 int w = f->output_data.x->size_hints.min_width;
270 int h = f->output_data.x->size_hints.min_height;
271 data[5] = w;
272 data[6] = h;
273 }
274
275 XChangeProperty (d, w, prop, XA_WM_SIZE_HINTS, 32, PropModeReplace,
276 (unsigned char *) data, 18);
277 }
278
279 /* Override this X11 function.
280 This function is in the same X11 file as the one above. So we must
281 provide it also. */
282
283 void
284 XSetWMNormalHints (Display *d, Window w, XSizeHints *hints)
285 {
286 XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS);
287 }