[clutter/clutter-1.16] x11: Apply the window scaling factor
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/clutter-1.16] x11: Apply the window scaling factor
- Date: Thu, 19 Sep 2013 22:11:40 +0000 (UTC)
commit 75f81fee708f4811667191065740815b507d938e
Author: Emmanuele Bassi <ebassi gnome org>
Date: Wed Aug 14 11:25:01 2013 +0100
x11: Apply the window scaling factor
On high DPI density displays we create surfaces with a size scaled up by
a certain factor. Even if the contents stay at the same relative size
and position, we need to compensate the scaling both when changing the
surface size, and when dealing with input.
https://bugzilla.gnome.org/show_bug.cgi?id=705915
clutter/x11/clutter-backend-x11.c | 2 +-
clutter/x11/clutter-device-manager-core-x11.c | 27 ++++---
clutter/x11/clutter-device-manager-xi2.c | 39 ++++++-----
clutter/x11/clutter-stage-x11.c | 93 +++++++++++++++++++------
clutter/x11/clutter-stage-x11.h | 3 +
5 files changed, 111 insertions(+), 53 deletions(-)
---
diff --git a/clutter/x11/clutter-backend-x11.c b/clutter/x11/clutter-backend-x11.c
index 5ca1a0b..9252302 100644
--- a/clutter/x11/clutter-backend-x11.c
+++ b/clutter/x11/clutter-backend-x11.c
@@ -165,7 +165,7 @@ clutter_backend_x11_xsettings_notify (const char *name,
{
if (g_strcmp0 (name, CLUTTER_SETTING_X11_NAME (i)) == 0)
{
- GValue value = { 0, };
+ GValue value = G_VALUE_INIT;
switch (setting->type)
{
diff --git a/clutter/x11/clutter-device-manager-core-x11.c b/clutter/x11/clutter-device-manager-core-x11.c
index 6a3606d..f47e3b8 100644
--- a/clutter/x11/clutter-device-manager-core-x11.c
+++ b/clutter/x11/clutter-device-manager-core-x11.c
@@ -135,6 +135,7 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
ClutterTranslateReturn res;
ClutterStage *stage;
XEvent *xevent;
+ int window_scale;
manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (translator);
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
@@ -150,6 +151,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
+ window_scale = stage_x11->scale_factor;
+
event->any.stage = stage;
res = CLUTTER_TRANSLATE_CONTINUE;
@@ -222,8 +225,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->scroll.direction = CLUTTER_SCROLL_RIGHT;
event->scroll.time = xevent->xbutton.time;
- event->scroll.x = xevent->xbutton.x;
- event->scroll.y = xevent->xbutton.y;
+ event->scroll.x = xevent->xbutton.x / window_scale;
+ event->scroll.y = xevent->xbutton.y / window_scale;
event->scroll.modifier_state = xevent->xbutton.state;
event->scroll.axes = NULL;
break;
@@ -231,8 +234,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
default:
event->button.type = event->type = CLUTTER_BUTTON_PRESS;
event->button.time = xevent->xbutton.time;
- event->button.x = xevent->xbutton.x;
- event->button.y = xevent->xbutton.y;
+ event->button.x = xevent->xbutton.x / window_scale;
+ event->button.y = xevent->xbutton.y / window_scale;
event->button.modifier_state = xevent->xbutton.state;
event->button.button = xevent->xbutton.button;
event->button.axes = NULL;
@@ -265,8 +268,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
event->button.time = xevent->xbutton.time;
- event->button.x = xevent->xbutton.x;
- event->button.y = xevent->xbutton.y;
+ event->button.x = xevent->xbutton.x / window_scale;
+ event->button.y = xevent->xbutton.y / window_scale;
event->button.modifier_state = xevent->xbutton.state;
event->button.button = xevent->xbutton.button;
event->button.axes = NULL;
@@ -283,8 +286,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->motion.type = event->type = CLUTTER_MOTION;
event->motion.time = xevent->xmotion.time;
- event->motion.x = xevent->xmotion.x;
- event->motion.y = xevent->xmotion.y;
+ event->motion.x = xevent->xmotion.x / window_scale;
+ event->motion.y = xevent->xmotion.y / window_scale;
event->motion.modifier_state = xevent->xmotion.state;
event->motion.axes = NULL;
clutter_event_set_device (event, manager_x11->core_pointer);
@@ -297,8 +300,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->crossing.type = CLUTTER_ENTER;
event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = xevent->xcrossing.x;
- event->crossing.y = xevent->xcrossing.y;
+ event->crossing.x = xevent->xcrossing.x / window_scale;
+ event->crossing.y = xevent->xcrossing.y / window_scale;
event->crossing.source = CLUTTER_ACTOR (stage);
event->crossing.related = NULL;
clutter_event_set_device (event, manager_x11->core_pointer);
@@ -323,8 +326,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
event->crossing.type = CLUTTER_LEAVE;
event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = xevent->xcrossing.x;
- event->crossing.y = xevent->xcrossing.y;
+ event->crossing.x = xevent->xcrossing.x / window_scale;
+ event->crossing.y = xevent->xcrossing.y / window_scale;
event->crossing.source = CLUTTER_ACTOR (stage);
event->crossing.related = NULL;
clutter_event_set_device (event, manager_x11->core_pointer);
diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c
index 1ee4fd9..8f9133f 100644
--- a/clutter/x11/clutter-device-manager-xi2.c
+++ b/clutter/x11/clutter-device-manager-xi2.c
@@ -627,11 +627,11 @@ translate_axes (ClutterInputDevice *device,
switch (axis)
{
case CLUTTER_INPUT_AXIS_X:
- retval[i] = x;
+ retval[i] = x / stage_x11->scale_factor;
break;
case CLUTTER_INPUT_AXIS_Y:
- retval[i] = y;
+ retval[i] = y / stage_x11->scale_factor;
break;
default:
@@ -745,6 +745,7 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
XGenericEventCookie *cookie;
XIEvent *xi_event;
XEvent *xevent;
+ int window_scale;
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
@@ -773,6 +774,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->any.stage = stage;
+ window_scale = stage_x11->scale_factor;
+
switch (xi_event->evtype)
{
case XI_HierarchyChanged:
@@ -927,8 +930,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->scroll.stage = stage;
event->scroll.time = xev->time;
- event->scroll.x = xev->event_x;
- event->scroll.y = xev->event_y;
+ event->scroll.x = xev->event_x / window_scale;
+ event->scroll.y = xev->event_y / window_scale;
_clutter_input_device_xi2_translate_state (event,
&xev->mods,
&xev->buttons,
@@ -975,8 +978,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->button.stage = stage;
event->button.time = xev->time;
- event->button.x = xev->event_x;
- event->button.y = xev->event_y;
+ event->button.x = xev->event_x / window_scale;
+ event->button.y = xev->event_y / window_scale;
event->button.button = xev->detail;
_clutter_input_device_xi2_translate_state (event,
&xev->mods,
@@ -1058,8 +1061,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->scroll.stage = stage;
event->scroll.time = xev->time;
- event->scroll.x = xev->event_x;
- event->scroll.y = xev->event_y;
+ event->scroll.x = xev->event_x / window_scale;
+ event->scroll.y = xev->event_y / window_scale;
_clutter_input_device_xi2_translate_state (event,
&xev->mods,
&xev->buttons,
@@ -1087,8 +1090,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->motion.stage = stage;
event->motion.time = xev->time;
- event->motion.x = xev->event_x;
- event->motion.y = xev->event_y;
+ event->motion.x = xev->event_x / window_scale;
+ event->motion.y = xev->event_y / window_scale;
_clutter_input_device_xi2_translate_state (event,
&xev->mods,
&xev->buttons,
@@ -1139,8 +1142,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->touch.stage = stage;
event->touch.time = xev->time;
- event->touch.x = xev->event_x;
- event->touch.y = xev->event_y;
+ event->touch.x = xev->event_x / window_scale;
+ event->touch.y = xev->event_y / window_scale;
_clutter_input_device_xi2_translate_state (event,
&xev->mods,
&xev->buttons,
@@ -1195,8 +1198,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->touch.stage = stage;
event->touch.time = xev->time;
event->touch.sequence = GUINT_TO_POINTER (xev->detail);
- event->touch.x = xev->event_x;
- event->touch.y = xev->event_y;
+ event->touch.x = xev->event_x / window_scale;
+ event->touch.y = xev->event_y / window_scale;
clutter_event_set_source_device (event, source_device);
@@ -1253,8 +1256,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->crossing.related = NULL;
event->crossing.time = xev->time;
- event->crossing.x = xev->event_x;
- event->crossing.y = xev->event_y;
+ event->crossing.x = xev->event_x / window_scale;
+ event->crossing.y = xev->event_y / window_scale;
_clutter_input_device_set_stage (device, stage);
}
@@ -1277,8 +1280,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
event->crossing.related = NULL;
event->crossing.time = xev->time;
- event->crossing.x = xev->event_x;
- event->crossing.y = xev->event_y;
+ event->crossing.x = xev->event_x / window_scale;
+ event->crossing.y = xev->event_y / window_scale;
_clutter_input_device_set_stage (device, NULL);
}
diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c
index 08b8e15..9907840 100644
--- a/clutter/x11/clutter-stage-x11.c
+++ b/clutter/x11/clutter-stage-x11.c
@@ -22,6 +22,7 @@
#include "config.h"
#include <math.h>
+#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -151,10 +152,10 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
&min_height);
if (new_width <= 0)
- new_width = min_width;
+ new_width = min_width * stage_x11->scale_factor;
if (new_height <= 0)
- new_height = min_height;
+ new_height = min_height * stage_x11->scale_factor;
size_hints->flags = 0;
@@ -164,8 +165,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
{
if (resize)
{
- size_hints->min_width = min_width;
- size_hints->min_height = min_height;
+ size_hints->min_width = min_width * stage_x11->scale_factor;
+ size_hints->min_height = min_height * stage_x11->scale_factor;
size_hints->flags = PMinSize;
}
else
@@ -225,8 +226,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
return;
}
- geometry->width = stage_x11->xwin_width;
- geometry->height = stage_x11->xwin_height;
+ geometry->width = stage_x11->xwin_width / stage_x11->scale_factor;
+ geometry->height = stage_x11->xwin_height / stage_x11->scale_factor;
}
static void
@@ -244,8 +245,8 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
* so we need to manually set the size and queue a relayout on the
* stage here (as is normally done in response to ConfigureNotify).
*/
- stage_x11->xwin_width = width;
- stage_x11->xwin_height = height;
+ stage_x11->xwin_width = width * stage_x11->scale_factor;
+ stage_x11->xwin_height = height * stage_x11->scale_factor;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_cogl->wrapper));
return;
}
@@ -266,6 +267,9 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height);
+ width *= stage_x11->scale_factor;
+ height *= stage_x11->scale_factor;
+
if (stage_x11->xwin != None)
{
clutter_stage_x11_fix_window_size (stage_x11, width, height);
@@ -576,11 +580,18 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
ClutterDeviceManager *device_manager;
gfloat width, height;
- clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper),
- &width, &height);
+ clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper), &width, &height);
+
+ CLUTTER_NOTE (BACKEND, "Wrapper size: %.2f x %.2f", width, height);
+
+ width = width * (float) stage_x11->scale_factor;
+ height = height * (float) stage_x11->scale_factor;
- stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context,
- width, height);
+ CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f (factor: %d)",
+ width, height,
+ stage_x11->scale_factor);
+
+ stage_cogl->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
/* We just created a window of the size of the actor. No need to fix
the size of the stage, just update it. */
@@ -823,6 +834,26 @@ clutter_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
}
static void
+clutter_stage_x11_set_scale_factor (ClutterStageWindow *stage_window,
+ int factor)
+{
+ ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+
+ if (stage_x11->fixed_scale_factor)
+ return;
+
+ stage_x11->scale_factor = factor;
+}
+
+static int
+clutter_stage_x11_get_scale_factor (ClutterStageWindow *stage_window)
+{
+ ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
+
+ return stage_x11->scale_factor;
+}
+
+static void
clutter_stage_x11_finalize (GObject *gobject)
{
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (gobject);
@@ -855,6 +886,8 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
static void
clutter_stage_x11_init (ClutterStageX11 *stage)
{
+ const char *scale_str;
+
stage->xwin = None;
stage->xwin_width = 640;
stage->xwin_height = 480;
@@ -868,6 +901,20 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
stage->accept_focus = TRUE;
stage->title = NULL;
+
+ scale_str = g_getenv ("CLUTTER_SCALE");
+ if (scale_str != NULL)
+ {
+ CLUTTER_NOTE (BACKEND, "Scale factor set using environment variable: %d ('%s')",
+ atol (scale_str),
+ scale_str);
+ stage->fixed_scale_factor = TRUE;
+ stage->scale_factor = atol (scale_str);
+ stage->xwin_width *= stage->scale_factor;
+ stage->xwin_height *= stage->scale_factor;
+ }
+ else
+ stage->scale_factor = 1;
}
static void
@@ -887,6 +934,8 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
iface->realize = clutter_stage_x11_realize;
iface->unrealize = clutter_stage_x11_unrealize;
iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws;
+ iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
+ iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
}
static inline void
@@ -1008,8 +1057,8 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
}
clutter_actor_set_size (CLUTTER_ACTOR (stage),
- xevent->xconfigure.width,
- xevent->xconfigure.height);
+ xevent->xconfigure.width / stage_x11->scale_factor,
+ xevent->xconfigure.height / stage_x11->scale_factor);
CLUTTER_UNSET_PRIVATE_FLAGS (stage_cogl->wrapper, CLUTTER_IN_RESIZE);
@@ -1181,10 +1230,10 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
expose->width,
expose->height);
- clip.x = expose->x;
- clip.y = expose->y;
- clip.width = expose->width;
- clip.height = expose->height;
+ clip.x = expose->x / stage_x11->scale_factor;
+ clip.y = expose->y / stage_x11->scale_factor;
+ clip.width = expose->width / stage_x11->scale_factor;
+ clip.height = expose->height / stage_x11->scale_factor;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
}
break;
@@ -1350,8 +1399,8 @@ set_foreign_window_callback (ClutterActor *actor,
fwd->stage_x11->xwin = fwd->xwindow;
fwd->stage_x11->is_foreign_xwin = TRUE;
- fwd->stage_x11->xwin_width = fwd->geom.width;
- fwd->stage_x11->xwin_height = fwd->geom.height;
+ fwd->stage_x11->xwin_width = fwd->geom.width * fwd->stage_x11->scale_factor;
+ fwd->stage_x11->xwin_height = fwd->geom.height * fwd->stage_x11->scale_factor;
clutter_actor_set_size (actor, fwd->geom.width, fwd->geom.height);
@@ -1451,8 +1500,8 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
fwd.geom.x = x;
fwd.geom.y = y;
- fwd.geom.width = width;
- fwd.geom.height = height;
+ fwd.geom.width = width / stage_x11->scale_factor;
+ fwd.geom.height = height / stage_x11->scale_factor;
actor = CLUTTER_ACTOR (stage);
diff --git a/clutter/x11/clutter-stage-x11.h b/clutter/x11/clutter-stage-x11.h
index 8b61056..feaacf9 100644
--- a/clutter/x11/clutter-stage-x11.h
+++ b/clutter/x11/clutter-stage-x11.h
@@ -61,6 +61,8 @@ struct _ClutterStageX11
ClutterStageX11State wm_state;
+ int scale_factor;
+
guint is_foreign_xwin : 1;
guint fullscreening : 1;
guint is_cursor_visible : 1;
@@ -68,6 +70,7 @@ struct _ClutterStageX11
guint accept_focus : 1;
guint fullscreen_on_realize : 1;
guint cursor_hidden_xfixes : 1;
+ guint fixed_scale_factor : 1;
};
struct _ClutterStageX11Class
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]