2013-02-19 02:55:07 -08:00
|
|
|
#include "e.h"
|
|
|
|
#include "e_mod_main.h"
|
|
|
|
#include "e_smart_monitor.h"
|
2013-02-19 02:55:30 -08:00
|
|
|
|
|
|
|
/* local structure */
|
|
|
|
typedef struct _E_Smart_Data E_Smart_Data;
|
|
|
|
struct _E_Smart_Data
|
|
|
|
{
|
|
|
|
/* canvas variable */
|
|
|
|
Evas *evas;
|
|
|
|
|
2013-02-19 02:55:54 -08:00
|
|
|
/* geometry */
|
|
|
|
int x, y, w, h;
|
|
|
|
|
2013-02-19 02:55:45 -08:00
|
|
|
/* crtc config */
|
|
|
|
E_Randr_Crtc_Config *crtc;
|
|
|
|
|
|
|
|
/* output config */
|
|
|
|
E_Randr_Output_Config *output;
|
|
|
|
|
2013-02-19 02:55:56 -08:00
|
|
|
/* list of modes */
|
|
|
|
Eina_List *modes;
|
|
|
|
|
2013-02-19 02:55:30 -08:00
|
|
|
/* visibility flag */
|
|
|
|
Eina_Bool visible : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
static void _e_smart_add(Evas_Object *obj);
|
|
|
|
static void _e_smart_del(Evas_Object *obj);
|
|
|
|
static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
|
|
|
|
static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
|
|
|
|
static void _e_smart_show(Evas_Object *obj);
|
|
|
|
static void _e_smart_hide(Evas_Object *obj);
|
|
|
|
static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
|
|
|
|
static void _e_smart_clip_unset(Evas_Object *obj);
|
|
|
|
|
2013-02-19 02:55:56 -08:00
|
|
|
static void _e_smart_monitor_modes_fill(E_Smart_Data *sd);
|
|
|
|
static int _e_smart_monitor_modes_sort(const void *data1, const void *data2);
|
|
|
|
|
2013-02-19 02:55:30 -08:00
|
|
|
/* external functions exposed by this widget */
|
|
|
|
Evas_Object *
|
|
|
|
e_smart_monitor_add(Evas *evas)
|
|
|
|
{
|
|
|
|
static Evas_Smart *smart = NULL;
|
|
|
|
static const Evas_Smart_Class sc =
|
|
|
|
{
|
|
|
|
"smart_monitor", EVAS_SMART_CLASS_VERSION,
|
|
|
|
_e_smart_add, _e_smart_del, _e_smart_move, _e_smart_resize,
|
|
|
|
_e_smart_show, _e_smart_hide, NULL,
|
|
|
|
_e_smart_clip_set, _e_smart_clip_unset,
|
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
/* if we have never created the smart class, do it now */
|
|
|
|
if (!smart)
|
|
|
|
if (!(smart = evas_smart_class_new(&sc)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* return a newly created smart randr widget */
|
|
|
|
return evas_object_smart_add(evas, smart);
|
|
|
|
}
|
|
|
|
|
2013-02-19 02:55:45 -08:00
|
|
|
void
|
|
|
|
e_smart_monitor_crtc_set(Evas_Object *obj, E_Randr_Crtc_Config *crtc)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
|
|
|
/* set the crtc config */
|
|
|
|
sd->crtc = crtc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
e_smart_monitor_output_set(Evas_Object *obj, E_Randr_Output_Config *output)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
|
|
|
/* set the output config */
|
|
|
|
sd->output = output;
|
2013-02-19 02:55:56 -08:00
|
|
|
|
|
|
|
/* since we now have the output, let's be preemptive and fill in modes */
|
|
|
|
_e_smart_monitor_modes_fill(sd);
|
2013-02-19 02:55:45 -08:00
|
|
|
}
|
|
|
|
|
2013-02-19 02:55:30 -08:00
|
|
|
/* local functions */
|
|
|
|
static void
|
|
|
|
_e_smart_add(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to allocate the smart data structure */
|
|
|
|
if (!(sd = E_NEW(E_Smart_Data, 1))) return;
|
|
|
|
|
|
|
|
/* grab the canvas */
|
|
|
|
sd->evas = evas_object_evas_get(obj);
|
|
|
|
|
|
|
|
/* set the objects smart data */
|
|
|
|
evas_object_smart_data_set(obj, sd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_del(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
2013-02-19 02:55:56 -08:00
|
|
|
Ecore_X_Randr_Mode_Info *mode;
|
2013-02-19 02:55:30 -08:00
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
2013-02-19 02:55:56 -08:00
|
|
|
/* free the list of modes */
|
|
|
|
EINA_LIST_FREE(sd->modes, mode)
|
|
|
|
ecore_x_randr_mode_info_free(mode);
|
|
|
|
|
2013-02-19 02:55:30 -08:00
|
|
|
/* try to free the allocated structure */
|
|
|
|
E_FREE(sd);
|
|
|
|
|
|
|
|
/* set the objects smart data to null */
|
|
|
|
evas_object_smart_data_set(obj, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
2013-02-19 02:55:54 -08:00
|
|
|
|
|
|
|
/* if there is no position change, then get out */
|
|
|
|
if ((sd->x == x) && (sd->y == y)) return;
|
|
|
|
|
|
|
|
sd->x = x;
|
|
|
|
sd->y = y;
|
2013-02-19 02:55:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
2013-02-19 02:55:54 -08:00
|
|
|
|
|
|
|
/* if there is no size change, then get out */
|
|
|
|
if ((sd->w == w) && (sd->h == h)) return;
|
|
|
|
|
|
|
|
sd->w = w;
|
|
|
|
sd->h = h;
|
2013-02-19 02:55:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_show(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
|
|
|
/* if we are already visible, then nothing to do */
|
|
|
|
if (sd->visible) return;
|
|
|
|
|
|
|
|
/* set visibility flag */
|
|
|
|
sd->visible = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_hide(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
|
|
|
|
/* if we are already hidden, then nothing to do */
|
|
|
|
if (!sd->visible) return;
|
|
|
|
|
|
|
|
/* set visibility flag */
|
|
|
|
sd->visible = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_clip_unset(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
E_Smart_Data *sd;
|
|
|
|
|
|
|
|
/* try to get the objects smart data */
|
|
|
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
|
|
|
}
|
2013-02-19 02:55:56 -08:00
|
|
|
|
|
|
|
static void
|
|
|
|
_e_smart_monitor_modes_fill(E_Smart_Data *sd)
|
|
|
|
{
|
|
|
|
Ecore_X_Window root = 0;
|
|
|
|
Ecore_X_Randr_Mode *modes;
|
|
|
|
int num = 0, i = 0;
|
|
|
|
|
|
|
|
/* safety check */
|
|
|
|
if (!sd) return;
|
|
|
|
|
|
|
|
/* try to get the root window */
|
|
|
|
root = ecore_x_window_root_first_get();
|
|
|
|
|
|
|
|
/* try to get the modes for this output from ecore_x_randr */
|
|
|
|
modes = ecore_x_randr_output_modes_get(root, sd->output->xid, &num, NULL);
|
|
|
|
if (!modes) return;
|
|
|
|
|
|
|
|
/* loop the returned modes */
|
|
|
|
for (i = 0; i < num; i++)
|
|
|
|
{
|
|
|
|
Ecore_X_Randr_Mode_Info *mode;
|
|
|
|
|
|
|
|
/* try to get the mode info */
|
|
|
|
if (!(mode = ecore_x_randr_mode_info_get(root, modes[i])))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* append the mode info to our list of modes */
|
|
|
|
sd->modes = eina_list_append(sd->modes, mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free any memory allocated from ecore_x_randr */
|
|
|
|
free(modes);
|
|
|
|
|
|
|
|
/* sort the list of modes (smallest to largest) */
|
|
|
|
if (sd->modes)
|
|
|
|
sd->modes = eina_list_sort(sd->modes, 0, _e_smart_monitor_modes_sort);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_e_smart_monitor_modes_sort(const void *data1, const void *data2)
|
|
|
|
{
|
|
|
|
const Ecore_X_Randr_Mode_Info *m1, *m2 = NULL;
|
|
|
|
|
|
|
|
if (!(m1 = data1)) return 1;
|
|
|
|
if (!(m2 = data2)) return -1;
|
|
|
|
|
|
|
|
/* second one compares to previous to determine position */
|
|
|
|
if (m2->width < m1->width) return 1;
|
|
|
|
if (m2->width > m1->width) return -1;
|
|
|
|
|
|
|
|
/* width are same, compare heights */
|
|
|
|
if ((m2->width == m1->width))
|
|
|
|
{
|
|
|
|
if (m2->height < m1->height) return 1;
|
|
|
|
if (m2->height > m1->height) return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|