/*
*
* LiveWallpaper
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Copyright (C) 2012-2016 Maximilian Schnarr
*
*/
/**
* SECTION: output
* @Short_description: Onscreen output area
*
* The LwOutput object specifies the position and the size of an onscreen
* output area. Usually one LwOutput will be created for each physical monitor.
*/
#include
struct _LwOutputPrivate
{
guint id;
guint x;
guint y;
guint width;
guint height;
};
enum
{
PROP_0,
PROP_ID,
PROP_X,
PROP_Y,
PROP_WIDTH,
PROP_HEIGHT,
N_PROPERTIES
};
static GParamSpec *obj_properties[N_PROPERTIES] = {NULL, };
/**
* LwOutput:
*
* Represents an output area. One #LwOutput will be created for each physical
* monitor.
*
* If LiveWallpaper recognizes a new screen or if the screen resolution changes,
* all outputs will be destroyed and LiveWallpaper will create new outputs. Just
* keep this in mind if you associate data with a specific output, because the
* output can be destroyed and you don't recognize it.
*
*
* LiveWallpaper will never destroy an output without calling lw_wallpaper_restore_viewport().
*
*
*/
G_DEFINE_TYPE(LwOutput, lw_output, G_TYPE_OBJECT)
static void
lw_output_set_property(GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
LwOutput *self = LW_OUTPUT(object);
switch(property_id)
{
case PROP_X:
self->priv->x = g_value_get_uint(value);
break;
case PROP_Y:
self->priv->y = g_value_get_uint(value);
break;
case PROP_WIDTH:
self->priv->width = g_value_get_uint(value);
break;
case PROP_HEIGHT:
self->priv->height = g_value_get_uint(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
}
}
static void
lw_output_get_property(GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
LwOutput *self = LW_OUTPUT(object);
switch(property_id)
{
case PROP_ID:
g_value_set_uint(value, lw_output_get_id(self));
break;
case PROP_X:
g_value_set_uint(value, lw_output_get_x(self));
break;
case PROP_Y:
g_value_set_uint(value, lw_output_get_y(self));
break;
case PROP_WIDTH:
g_value_set_uint(value, lw_output_get_width(self));
break;
case PROP_HEIGHT:
g_value_set_uint(value, lw_output_get_height(self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
}
}
/**
* lw_output_get_id:
* @self: A #LwOutput
*
* Since LiveWallpaper 0.5 the size and position of an output cannot change. You can use
* the ID to identify exactly this output.
*
* Returns: The ID of the output
*/
guint
lw_output_get_id(LwOutput *self)
{
return self->priv->id;
}
/**
* lw_output_get_x:
* @self: A #LwOutput
*
* Returns: The position of the output in x direction
*/
guint
lw_output_get_x(LwOutput *self)
{
return self->priv->x;
}
/**
* lw_output_get_y:
* @self: A #LwOutput
*
* Returns: The position of the output in y direction
*/
guint
lw_output_get_y(LwOutput *self)
{
return self->priv->y;
}
/**
* lw_output_get_width:
* @self: A #LwOutput
*
* Returns: The width of the output
*/
guint
lw_output_get_width(LwOutput *self)
{
return self->priv->width;
}
/**
* lw_output_get_height:
* @self: A #LwOutput
*
* Returns: The height of the output
*/
guint
lw_output_get_height(LwOutput *self)
{
return self->priv->height;
}
/**
* lw_output_get_aspect_ratio:
* @self: A #LwOutput
*
* Returns the quotient of width and height if both are > 0 and 0 otherwise.
*
* Returns: width / height
*/
gdouble
lw_output_get_aspect_ratio(LwOutput *self)
{
if(self->priv->width == 0 || self->priv->height == 0)
return 0;
return ((gdouble) self->priv->width) / ((gdouble) self->priv->height);
}
/**
* lw_output_get_longest_side:
* @self: A #LwOutput
*
* Returns the width if width > height, otherwise the height.
*
* Returns: The longest side in pixels
*
* Since: 0.5
*/
guint
lw_output_get_longest_side(LwOutput *self)
{
if(self->priv->width > self->priv->height)
return self->priv->width;
else
return self->priv->height;
}
/**
* lw_output_get_shortest_side:
* @self: A #LwOutput
*
* Returns the width, if width < height, otherwise the height.
*
* Returns: The shortest side in pixels
*
* Since: 0.5
*/
guint
lw_output_get_shortest_side(LwOutput *self)
{
if(self->priv->height < self->priv->width)
return self->priv->height;
else
return self->priv->width;
}
/**
* lw_output_make_current:
* @self: A #LwOutput
*
* Adjusts the OpenGL viewport to fit to the output. It also restricts the drawing
* operations to the viewport using glScissor.
* LiveWallpaper will call this for you so you don't have to do this again in
* lw_wallpaper_adjust_viewport().
*
* Since: 0.5
*/
void
lw_output_make_current(LwOutput *self)
{
glViewport(self->priv->x, self->priv->y,
self->priv->width, self->priv->height);
glScissor(self->priv->x, self->priv->y,
self->priv->width, self->priv->height);
}
static guint next_id = 0;
static void
lw_output_init(LwOutput *self)
{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, LW_TYPE_OUTPUT,
LwOutputPrivate);
self->priv->id = next_id++;
}
static void
lw_output_class_init(LwOutputClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = lw_output_set_property;
gobject_class->get_property = lw_output_get_property;
g_type_class_add_private(klass, sizeof(LwOutputPrivate));
/**
* LwOutput:id:
*
* ID of the output
*/
obj_properties[PROP_ID] = g_param_spec_uint("id", "ID", "ID of the output", 0, G_MAXUINT, 0, G_PARAM_READABLE);
/**
* LwOutput:x:
*
* The X coordinate of the output
*/
obj_properties[PROP_X] = g_param_spec_uint("x", "X", "The X coordinate of the output", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
/**
* LwOutput:y:
*
* The Y coordinate of the output
*/
obj_properties[PROP_Y] = g_param_spec_uint("y", "Y", "The Y coordinate of the output", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
/**
* LwOutput:width:
*
* The width of the output
*/
obj_properties[PROP_WIDTH] = g_param_spec_uint("width", "Width", "The width of the output", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
/**
* LwOutput:height:
*
* The height of the output
*/
obj_properties[PROP_HEIGHT] = g_param_spec_uint("height", "Height", "The height of the output", 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties(gobject_class, N_PROPERTIES, obj_properties);
}