upstream
[emacs.git] / src / emacsgtkfixed.c
blob3b997c0d4f55040fbeaa391f6c280a5c9f91e97a
1 /* A Gtk Widget that inherits GtkFixed, but can be shrunk.
2 This file is only use when compiling with Gtk+ 3.
4 Copyright (C) 2011-2014 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
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.
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.
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/>. */
21 #include <config.h>
23 #include "lisp.h"
24 #include "frame.h"
25 #include "xterm.h"
26 #ifdef HAVE_XWIDGETS
27 #include "xwidget.h"
28 #endif
29 #include "emacsgtkfixed.h"
31 /* Silence a bogus diagnostic; see GNOME bug 683906. */
32 #if 4 < __GNUC__ + (7 <= __GNUC_MINOR__)
33 # pragma GCC diagnostic push
34 # pragma GCC diagnostic ignored "-Wunused-local-typedefs"
35 #endif
37 //#define EMACS_TYPE_FIXED emacs_fixed_get_type ()
38 /* #define EMACS_FIXED(obj) \ */
39 /* G_TYPE_CHECK_INSTANCE_CAST (obj, EMACS_TYPE_FIXED, EmacsFixed) */
41 typedef struct _EmacsFixed EmacsFixed;
42 typedef struct _EmacsFixedPrivate EmacsFixedPrivate;
43 typedef struct _EmacsFixedClass EmacsFixedClass;
45 /* struct _EmacsFixed */
46 /* { */
47 /* GtkFixed container; */
49 /* /\*< private >*\/ */
50 /* EmacsFixedPrivate *priv; */
51 /* }; */
53 /* struct _EmacsFixedClass */
54 /* { */
55 /* GtkFixedClass parent_class; */
56 /* }; */
58 struct _EmacsFixedPrivate
60 struct frame *f;
64 static void emacs_fixed_get_preferred_width (GtkWidget *widget,
65 gint *minimum,
66 gint *natural);
67 static void emacs_fixed_get_preferred_height (GtkWidget *widget,
68 gint *minimum,
69 gint *natural);
70 G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
72 #ifdef HAVE_XWIDGETS
73 /* void aloc_callback(GtkWidget* child, GtkWidget* fixed){ */
74 /* GtkAllocation child_allocation; */
75 /* GtkRequisition child_requisition; */
77 /* //TODO */
78 /* // if child is an xwidget, find its clipping area and modify allocation */
80 /* struct xwidget_view* xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child), XG_XWIDGET_VIEW); */
81 /* printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child)); */
82 /* if(xv){ */
83 /* printf(" allocation modification for xw\n"); */
84 /* gtk_widget_get_allocation(child, &child_allocation); */
85 /* child_allocation.width = xv->clip_right; */
86 /* child_allocation.height = xv->clip_bottom - xv->clip_top; */
87 /* gtk_widget_size_allocate (child, &child_allocation); */
88 /* //TODO find a way to remove this feeble workaround */
89 /* } */
91 /* } */
93 struct GtkFixedPrivateL
95 GList *children;
98 static void emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
99 GtkAllocation *allocation){
100 //for xwidgets
103 //TODO 1st call base class method
104 EmacsFixedClass *klass;
105 GtkWidgetClass *parent_class;
106 struct GtkFixedPrivateL* priv;
107 GtkFixedChild *child;
108 GtkAllocation child_allocation;
109 GtkRequisition child_requisition;
110 GList *children;
111 struct xwidget_view* xv;
113 // printf(" emacs_fixed_gtk_widget_size_allocate\n");
114 klass = EMACS_FIXED_GET_CLASS (widget);
115 parent_class = g_type_class_peek_parent (klass);
116 parent_class->size_allocate (widget, allocation);
118 priv = G_TYPE_INSTANCE_GET_PRIVATE (widget,
119 GTK_TYPE_FIXED,
120 struct GtkFixedPrivateL);
121 //fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, GTK_TYPE_FIXED, GtkFixedPrivate);
122 //then modify allocations
123 /* gtk_container_foreach (widget, */
124 /* aloc_callback, */
125 /* widget); */
127 //begin copy paste extravaganza!!!
129 //GtkFixed *fixed = GTK_FIXED (widget);
130 //GtkFixedPrivate *priv = fixed->priv;
133 gtk_widget_set_allocation (widget, allocation);
135 if (gtk_widget_get_has_window (widget))
137 if (gtk_widget_get_realized (widget))
138 gdk_window_move_resize (gtk_widget_get_window (widget),
139 allocation->x,
140 allocation->y,
141 allocation->width,
142 allocation->height);
145 for (children = priv->children;
146 children;
147 children = children->next)
149 child = children->data;
151 if (!gtk_widget_get_visible (child->widget))
152 continue;
154 gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
155 child_allocation.x = child->x;
156 child_allocation.y = child->y;
158 if (!gtk_widget_get_has_window (widget))
160 child_allocation.x += allocation->x;
161 child_allocation.y += allocation->y;
164 child_allocation.width = child_requisition.width;
165 child_allocation.height = child_requisition.height;
169 xv = (struct xwidget_view*) g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW);
170 //printf("aloc callback %d %s\n", xv, gtk_widget_get_name(child));
171 if(xv){
172 //gtk_widget_get_allocation(child, &child_allocation);
173 child_allocation.width = xv->clip_right;
174 child_allocation.height = xv->clip_bottom - xv->clip_top;
175 //gtk_widget_size_allocate (child, &child_allocation);
176 //TODO find a way to remove this feeble workaround
177 // printf(" allocation internal modification for xw %d %d,%d\n",xv, child_allocation.width, child_allocation.height);
180 gtk_widget_size_allocate (child->widget, &child_allocation);
186 #endif /* HAVE_XWIDGETS */
188 static void
189 emacs_fixed_class_init (EmacsFixedClass *klass)
191 GtkWidgetClass *widget_class;
192 GtkFixedClass *fixed_class;
194 widget_class = (GtkWidgetClass*) klass;
195 fixed_class = (GtkFixedClass*) klass;
197 widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
198 widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
199 #ifdef HAVE_XWIDGETS
200 widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate;
201 #endif
202 g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
205 static GType
206 emacs_fixed_child_type (GtkFixed *container)
208 return GTK_TYPE_WIDGET;
211 static void
212 emacs_fixed_init (EmacsFixed *fixed)
214 fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, EMACS_TYPE_FIXED,
215 EmacsFixedPrivate);
216 fixed->priv->f = 0;
220 * emacs_fixed_new:
222 * Creates a new #EmacsFixed.
224 * Returns: a new #EmacsFixed.
226 GtkWidget*
227 emacs_fixed_new (struct frame *f)
229 EmacsFixed *fixed = g_object_new (EMACS_TYPE_FIXED, NULL);
230 EmacsFixedPrivate *priv = fixed->priv;
231 priv->f = f;
232 return GTK_WIDGET (fixed);
235 static void
236 emacs_fixed_get_preferred_width (GtkWidget *widget,
237 gint *minimum,
238 gint *natural)
240 EmacsFixed *fixed = EMACS_FIXED (widget);
241 EmacsFixedPrivate *priv = fixed->priv;
242 int w = priv->f->output_data.x->size_hints.min_width;
243 if (minimum) *minimum = w;
244 if (natural) *natural = w;
247 static void
248 emacs_fixed_get_preferred_height (GtkWidget *widget,
249 gint *minimum,
250 gint *natural)
252 EmacsFixed *fixed = EMACS_FIXED (widget);
253 EmacsFixedPrivate *priv = fixed->priv;
254 int h = priv->f->output_data.x->size_hints.min_height;
255 if (minimum) *minimum = h;
256 if (natural) *natural = h;
260 /* Override the X function so we can intercept Gtk+ 3 calls.
261 Use our values for min_width/height so that KDE don't freak out
262 (Bug#8919), and so users can resize our frames as they wish. */
264 void
265 XSetWMSizeHints (Display* d,
266 Window w,
267 XSizeHints* hints,
268 Atom prop)
270 struct x_display_info *dpyinfo = x_display_info_for_display (d);
271 struct frame *f = x_top_window_to_frame (dpyinfo, w);
272 long data[18];
273 data[0] = hints->flags;
274 data[1] = hints->x;
275 data[2] = hints->y;
276 data[3] = hints->width;
277 data[4] = hints->height;
278 data[5] = hints->min_width;
279 data[6] = hints->min_height;
280 data[7] = hints->max_width;
281 data[8] = hints->max_height;
282 data[9] = hints->width_inc;
283 data[10] = hints->height_inc;
284 data[11] = hints->min_aspect.x;
285 data[12] = hints->min_aspect.y;
286 data[13] = hints->max_aspect.x;
287 data[14] = hints->max_aspect.y;
288 data[15] = hints->base_width;
289 data[16] = hints->base_height;
290 data[17] = hints->win_gravity;
292 if ((hints->flags & PMinSize) && f)
294 int w = f->output_data.x->size_hints.min_width;
295 int h = f->output_data.x->size_hints.min_height;
296 data[5] = w;
297 data[6] = h;
300 XChangeProperty (d, w, prop, XA_WM_SIZE_HINTS, 32, PropModeReplace,
301 (unsigned char *) data, 18);
304 /* Override this X11 function.
305 This function is in the same X11 file as the one above. So we must
306 provide it also. */
308 void
309 XSetWMNormalHints (Display *d, Window w, XSizeHints *hints)
311 XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS);