100
ClutterBackend *backend = clutter_get_default_backend ();
101
ClutterBackendX11 *backend_x11;
104
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
105
backend_x11 = CLUTTER_BACKEND_X11 (backend);
96
107
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
98
if (stage_x11->xwin != None && stage_x11->is_foreign_xwin == FALSE)
109
if (stage_x11->xwin != None && !stage_x11->is_foreign_xwin)
111
guint min_width, min_height;
100
112
XSizeHints *size_hints;
101
gfloat min_width, min_height;
103
114
size_hints = XAllocSizeHints();
106
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stage_x11),
110
min_width = new_width;
113
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stage_x11),
117
min_height = new_height;
116
clutter_stage_get_minimum_size (stage_x11->wrapper,
121
new_width = min_width;
124
new_height = min_height;
119
126
size_hints->flags = 0;
121
128
/* If we are going fullscreen then we don't want any
122
129
restrictions on the window size */
123
if (!stage_x11->fullscreen_on_map)
130
if (!stage_x11->fullscreening)
125
size_hints->min_width = (int) min_width;
126
size_hints->min_height = (int) min_height;
127
size_hints->flags = PMinSize;
131
size_hints->max_width = size_hints->min_width;
132
size_hints->max_height = size_hints->min_height;
133
size_hints->flags |= PMaxSize;
134
size_hints->min_width = min_width;
135
size_hints->min_height = min_height;
136
size_hints->flags = PMinSize;
140
size_hints->min_width = new_width;
141
size_hints->min_height = new_height;
142
size_hints->max_width = new_width;
143
size_hints->max_height = new_height;
144
size_hints->flags = PMinSize | PMaxSize;
137
XSetWMNormalHints (stage_x11->xdpy, stage_x11->xwin, size_hints);
148
XSetWMNormalHints (backend_x11->xdpy, stage_x11->xwin, size_hints);
139
150
XFree(size_hints);
144
155
clutter_stage_x11_set_wm_protocols (ClutterStageX11 *stage_x11)
146
ClutterBackendX11 *backend_x11 = stage_x11->backend;
157
ClutterBackend *backend = clutter_get_default_backend ();
158
ClutterBackendX11 *backend_x11;
147
159
Atom protocols[2];
162
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
163
backend_x11 = CLUTTER_BACKEND_X11 (backend);
150
165
protocols[n++] = backend_x11->atom_WM_DELETE_WINDOW;
151
166
protocols[n++] = backend_x11->atom_NET_WM_PING;
153
XSetWMProtocols (stage_x11->xdpy, stage_x11->xwin, protocols, n);
157
clutter_stage_x11_get_preferred_width (ClutterActor *self,
160
gfloat *natural_width_p)
162
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
163
gboolean is_fullscreen, resize;
165
is_fullscreen = FALSE;
166
g_object_get (G_OBJECT (stage_x11->wrapper),
167
"fullscreen-set", &is_fullscreen,
170
if (is_fullscreen || stage_x11->fullscreen_on_map)
174
width = DisplayWidth (stage_x11->xdpy, stage_x11->xscreen);
177
*min_width_p = width;
180
*natural_width_p = width;
185
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
190
*min_width_p = 1; /* FIXME need API to set this */
192
*min_width_p = stage_x11->xwin_width;
196
*natural_width_p = stage_x11->xwin_width;
200
clutter_stage_x11_get_preferred_height (ClutterActor *self,
202
gfloat *min_height_p,
203
gfloat *natural_height_p)
205
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
206
gboolean is_fullscreen, resize;
208
is_fullscreen = FALSE;
209
g_object_get (G_OBJECT (stage_x11->wrapper),
210
"fullscreen-set", &is_fullscreen,
213
if (is_fullscreen || stage_x11->fullscreen_on_map)
217
height = DisplayHeight (stage_x11->xdpy, stage_x11->xscreen);
220
*min_height_p = height;
222
if (natural_height_p)
223
*natural_height_p = height;
228
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
233
*min_height_p = 1; /* FIXME need API to set this */
235
*min_height_p = stage_x11->xwin_height;
238
if (natural_height_p)
239
*natural_height_p = stage_x11->xwin_height;
243
clutter_stage_x11_allocate (ClutterActor *self,
244
const ClutterActorBox *box,
245
ClutterAllocationFlags flags)
247
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (self);
248
ClutterActorClass *parent_class;
249
gint new_width, new_height;
251
new_width = ABS ((int) (box->x2 - box->x1));
252
new_height = ABS ((int) (box->y2 - box->y1));
254
if (new_width == 0 || new_height == 0)
168
XSetWMProtocols (backend_x11->xdpy, stage_x11->xwin, protocols, n);
172
clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
173
ClutterGeometry *geometry)
175
ClutterBackend *backend = clutter_get_default_backend ();
176
ClutterBackendX11 *backend_x11;
177
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
179
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
180
backend_x11 = CLUTTER_BACKEND_X11 (backend);
182
/* If we're fullscreen, return the size of the display. */
183
if ((stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) &&
184
stage_x11->fullscreening)
186
geometry->width = DisplayWidth (backend_x11->xdpy, backend_x11->xscreen_num);
187
geometry->height = DisplayHeight (backend_x11->xdpy, backend_x11->xscreen_num);
192
geometry->width = stage_x11->xwin_width;
193
geometry->height = stage_x11->xwin_height;
197
clutter_stage_x11_resize (ClutterStageWindow *stage_window,
201
ClutterBackend *backend = clutter_get_default_backend ();
202
ClutterBackendX11 *backend_x11;
203
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
204
ClutterStage *stage = stage_x11->wrapper;
207
if (stage_x11->is_foreign_xwin)
209
/* If this is a foreign window we won't get a ConfigureNotify,
210
* so we need to manually set the size and queue a relayout on the
211
* stage here (as is normally done in response to ConfigureNotify).
213
stage_x11->xwin_width = width;
214
stage_x11->xwin_height = height;
215
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_x11->wrapper));
219
/* If we're going fullscreen, don't mess with the size */
220
if (stage_x11->fullscreening)
223
resize = clutter_stage_get_user_resizable (stage_x11->wrapper);
225
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
226
backend_x11 = CLUTTER_BACKEND_X11 (backend);
228
if (width == 0 || height == 0)
256
230
/* Should not happen, if this turns up we need to debug it and
257
231
* determine the cleanest way to fix.
259
233
g_warning ("X11 stage not allowed to have 0 width or height");
264
CLUTTER_NOTE (BACKEND, "New allocation received: (%d, %d)",
238
CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height);
268
if (new_width != stage_x11->xwin_width ||
269
new_height != stage_x11->xwin_height)
240
if (stage_x11->xwin != None)
271
stage_x11->xwin_width = new_width;
272
stage_x11->xwin_height = new_height;
242
clutter_stage_x11_fix_window_size (stage_x11, width, height);
274
if (stage_x11->xwin != None &&
275
!stage_x11->is_foreign_xwin)
244
if (width != stage_x11->xwin_width ||
245
height != stage_x11->xwin_height)
277
247
CLUTTER_NOTE (BACKEND, "%s: XResizeWindow[%x] (%d, %d)",
279
249
(unsigned int) stage_x11->xwin,
280
stage_x11->xwin_width,
281
stage_x11->xwin_height);
283
253
CLUTTER_SET_PRIVATE_FLAGS (stage_x11->wrapper,
284
254
CLUTTER_STAGE_IN_RESIZE);
286
XResizeWindow (stage_x11->xdpy,
256
XResizeWindow (backend_x11->xdpy,
288
stage_x11->xwin_width,
289
stage_x11->xwin_height);
292
clutter_stage_x11_fix_window_size (stage_x11, new_width, new_height);
294
if (stage_x11->xpixmap != None)
296
/* Need to recreate to resize */
297
_clutter_actor_rerealize (self, NULL, NULL);
261
/* If the viewport hasn't previously been initialized then even
262
* though we can't guarantee that the server will honour our request
263
* we need to ensure a valid viewport is set before our first paint.
265
if (G_UNLIKELY (!stage_x11->viewport_initialized))
267
ClutterPerspective perspective;
268
clutter_stage_get_perspective (stage, &perspective);
269
_cogl_setup_viewport (width,
301
/* chain up to fill in actor->priv->allocation */
302
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_x11_parent_class);
303
parent_class->allocate (self, box, flags);
306
280
static inline void
307
281
set_wm_pid (ClutterStageX11 *stage_x11)
309
ClutterBackendX11 *backend_x11 = stage_x11->backend;
283
ClutterBackend *backend = clutter_get_default_backend ();
284
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
312
if (stage_x11->xwin == None)
287
if (stage_x11->xwin == None || stage_x11->is_foreign_xwin)
315
290
/* this will take care of WM_CLIENT_MACHINE and WM_LOCALE_NAME */
316
XSetWMProperties (stage_x11->xdpy, stage_x11->xwin,
291
XSetWMProperties (backend_x11->xdpy, stage_x11->xwin,
320
295
NULL, NULL, NULL);
323
XChangeProperty (stage_x11->xdpy,
298
XChangeProperty (backend_x11->xdpy,
325
300
backend_x11->atom_NET_WM_PID, XA_CARDINAL, 32,
377
362
#if 0 /* HAVE_XFIXES - seems buggy/unreliable, check cursor in firefox
378
363
* loading page after hiding.
380
XFixesHideCursor (stage_x11->xdpy, stage_x11->xwin);
365
XFixesHideCursor (backend_x11->xdpy, stage_x11->xwin);
386
pix = XCreatePixmap (stage_x11->xdpy, stage_x11->xwin, 1, 1, 1);
371
pix = XCreatePixmap (backend_x11->xdpy, stage_x11->xwin, 1, 1, 1);
387
372
memset (&col, 0, sizeof (col));
388
curs = XCreatePixmapCursor (stage_x11->xdpy,
373
curs = XCreatePixmapCursor (backend_x11->xdpy,
392
XFreePixmap (stage_x11->xdpy, pix);
393
XDefineCursor (stage_x11->xdpy, stage_x11->xwin, curs);
377
XFreePixmap (backend_x11->xdpy, pix);
378
XDefineCursor (backend_x11->xdpy, stage_x11->xwin, curs);
394
379
#endif /* HAVE_XFIXES */
399
clutter_stage_x11_realize (ClutterActor *actor)
384
clutter_stage_x11_realize (ClutterStageWindow *stage_window)
401
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (actor);
386
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
403
388
set_wm_pid (stage_x11);
404
389
set_wm_title (stage_x11);
405
390
set_cursor_visible (stage_x11);
409
396
clutter_stage_x11_set_fullscreen (ClutterStageWindow *stage_window,
410
397
gboolean is_fullscreen)
399
ClutterBackend *backend = clutter_get_default_backend ();
400
ClutterBackendX11 *backend_x11;
412
401
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
413
ClutterBackendX11 *backend_x11 = stage_x11->backend;
414
402
ClutterStage *stage = stage_x11->wrapper;
404
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
405
backend_x11 = CLUTTER_BACKEND_X11 (backend);
416
407
if (stage == NULL)
410
if (!!(stage_x11->state & CLUTTER_STAGE_STATE_FULLSCREEN) == is_fullscreen)
413
CLUTTER_NOTE (BACKEND, "%ssetting fullscreen", is_fullscreen ? "" : "un");
419
415
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES);
421
417
if (is_fullscreen)
587
600
CLUTTER_NOTE (BACKEND, "Mapping stage[%lu]",
588
601
(unsigned long) stage_x11->xwin);
590
if (stage_x11->fullscreen_on_map)
603
set_stage_state (stage_x11, STAGE_X11_WITHDRAWN, 0);
605
update_wm_hints (stage_x11);
607
if (stage_x11->fullscreening)
591
608
clutter_stage_x11_set_fullscreen (stage_window, TRUE);
593
610
clutter_stage_x11_set_fullscreen (stage_window, FALSE);
595
set_stage_state (stage_x11, STAGE_X11_WITHDRAWN, 0);
597
update_wm_hints (stage_x11);
600
613
g_assert (STAGE_X11_IS_MAPPED (stage_x11));
602
clutter_actor_map (CLUTTER_ACTOR (stage_x11));
603
615
clutter_actor_map (CLUTTER_ACTOR (stage_x11->wrapper));
605
/* we force a redraw here, so that by the time we have
606
* been mapped, the window has contents
608
_clutter_do_redraw (CLUTTER_STAGE (stage_x11->wrapper));
610
XMapWindow (stage_x11->xdpy, stage_x11->xwin);
617
if (!stage_x11->is_foreign_xwin)
618
XMapWindow (backend_x11->xdpy, stage_x11->xwin);
615
623
clutter_stage_x11_hide (ClutterStageWindow *stage_window)
625
ClutterBackend *backend = clutter_get_default_backend ();
626
ClutterBackendX11 *backend_x11;
617
627
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
629
g_return_if_fail (CLUTTER_IS_BACKEND_X11 (backend));
630
backend_x11 = CLUTTER_BACKEND_X11 (backend);
619
632
if (stage_x11->xwin != None)
621
634
if (STAGE_X11_IS_MAPPED (stage_x11))
769
772
* clutter_x11_get_stage_visual:
770
773
* @stage: a #ClutterStage
772
* Returns the stage XVisualInfo
774
* Return value: The XVisualInfo for the stage.
775
* Returns an XVisualInfo suitable for creating a foreign window for the given
776
* stage. NOTE: It doesn't do as the name may suggest, which is return the
777
* XVisualInfo that was used to create an existing window for the given stage.
779
* XXX: It might be best to deprecate this function and replace with something
780
* along the lines of clutter_backend_x11_get_foreign_visual () or perhaps
781
* clutter_stage_x11_get_foreign_visual ()
783
* Return value: An XVisualInfo suitable for creating a foreign stage. Use
784
* XFree() to free the returned value instead
786
* Deprecated: 1.2: Use clutter_x11_get_visual_info() instead
779
791
clutter_x11_get_stage_visual (ClutterStage *stage)
781
ClutterStageWindow *impl;
782
ClutterStageX11 *stage_x11;
783
gboolean is_offscreen = FALSE;
785
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
787
g_object_get (G_OBJECT (stage), "offscreen", &is_offscreen, NULL);
789
impl = _clutter_stage_get_window (stage);
790
g_assert (CLUTTER_IS_STAGE_X11 (impl));
792
stage_x11 = CLUTTER_STAGE_X11 (impl);
794
if (stage_x11->xvisinfo == NULL)
796
ClutterBackendX11 *backend_x11 = stage_x11->backend;
798
stage_x11->xvisinfo =
799
clutter_backend_x11_get_visual_info (backend_x11, is_offscreen);
802
return stage_x11->xvisinfo;
793
ClutterBackend *backend = clutter_get_default_backend ();
794
ClutterBackendX11 *backend_x11;
796
g_return_val_if_fail (CLUTTER_IS_BACKEND_X11 (backend), NULL);
797
backend_x11 = CLUTTER_BACKEND_X11 (backend);
799
return clutter_backend_x11_get_visual_info (backend_x11);