--- gtk/channel-main.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/gtk/channel-main.c b/gtk/channel-main.c index 3c173c6..d7830ae 100644 --- a/gtk/channel-main.c +++ b/gtk/channel-main.c @@ -15,6 +15,10 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include <math.h> +#include <spice/vd_agent.h> +#include <common/rect.h> + #include "glib-compat.h" #include "spice-client.h" #include "spice-common.h" @@ -24,8 +28,6 @@ #include "spice-channel-priv.h" #include "spice-session-priv.h" -#include <spice/vd_agent.h> - /** * SECTION:channel-main * @short_description: the main Spice channel @@ -58,6 +60,7 @@ struct _SpiceMainChannelPrivate { gboolean display_disable_font_smooth:1; gboolean display_disable_animation:1; gboolean disable_display_position:1; + gboolean disable_display_align:1; int agent_tokens; VDAgentMessage agent_msg; /* partial msg reconstruction */ @@ -102,6 +105,7 @@ enum { PROP_DISPLAY_DISABLE_ANIMATION, PROP_DISPLAY_COLOR_DEPTH, PROP_DISABLE_DISPLAY_POSITION, + PROP_DISABLE_DISPLAY_ALIGN, }; /* Signals */ @@ -203,6 +207,9 @@ static void spice_main_get_property(GObject *object, case PROP_DISABLE_DISPLAY_POSITION: g_value_set_boolean(value, c->disable_display_position); break; + case PROP_DISABLE_DISPLAY_ALIGN: + g_value_set_boolean(value, c->disable_display_align); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -233,6 +240,9 @@ static void spice_main_set_property(GObject *gobject, guint prop_id, case PROP_DISABLE_DISPLAY_POSITION: c->disable_display_position = g_value_get_boolean(value); break; + case PROP_DISABLE_DISPLAY_ALIGN: + c->disable_display_align = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec); break; @@ -410,6 +420,23 @@ static void spice_main_channel_class_init(SpiceMainChannelClass *klass) G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /** + * SpiceMainChannel:disable-display-align: + * + * Disable automatic horizontal display position alignment. + * + * Since: 0.13 + */ + g_object_class_install_property + (gobject_class, PROP_DISABLE_DISPLAY_ALIGN, + g_param_spec_boolean("disable-display-align", + "Disable display align", + "Disable display position alignment", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + /* TODO use notify instead */ /** * SpiceMainChannel::main-mouse-update: @@ -846,6 +873,37 @@ static void agent_msg_queue_many(SpiceMainChannel *channel, int type, const void g_warn_if_fail(out == NULL); } +static int monitors_cmp(const void *p1, const void *p2) +{ + const VDAgentMonConfig *m1 = p1; + const VDAgentMonConfig *m2 = p2; + double d1 = sqrt(m1->x * m1->x + m1->y * m1->y); + double d2 = sqrt(m2->x * m2->x + m2->y * m2->y); + + return d1 - d2; +} + +static void monitors_align(VDAgentMonConfig *monitors, int nmonitors) +{ + gint i, x = 0; + + if (nmonitors == 0) + return; + + /* sort by distance from origin */ + qsort(monitors, nmonitors, sizeof(VDAgentMonConfig), monitors_cmp); + + /* super-KISS ltr alignment, feel free to improve */ + for (i = 0; i < nmonitors; i++) { + monitors[i].x = x; + monitors[i].y = 0; + x += monitors[i].width; + g_debug("#%d +%d+%d-%dx%d", i, monitors[i].x, monitors[i].y, + monitors[i].width, monitors[i].height); + } +} + + #define agent_msg_queue(Channel, Type, Size, Data) \ agent_msg_queue_many((Channel), (Type), (Data), (Size), NULL) @@ -882,7 +940,8 @@ gboolean spice_main_send_monitor_config(SpiceMainChannel *channel) mon = spice_malloc0(size); mon->num_of_monitors = monitors; - if (c->disable_display_position == FALSE) + if (c->disable_display_position == FALSE || + c->disable_display_align == FALSE) mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS; j = 0; @@ -901,6 +960,9 @@ gboolean spice_main_send_monitor_config(SpiceMainChannel *channel) j++; } + if (c->disable_display_align == FALSE) + monitors_align(mon->monitors, mon->num_of_monitors); + agent_msg_queue(channel, VD_AGENT_MONITORS_CONFIG, size, mon); free(mon); @@ -1845,6 +1907,10 @@ void spice_main_set_display(SpiceMainChannel *channel, int id, g_return_if_fail(channel != NULL); g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel)); + g_return_if_fail(x >= 0); + g_return_if_fail(y >= 0); + g_return_if_fail(width >= 0); + g_return_if_fail(height >= 0); c = SPICE_MAIN_CHANNEL(channel)->priv; -- 1.7.10.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel