#include "e.h" #include "e_mod_main.h" #include "e_smart_monitor.h" /* local structure */ typedef struct _E_Smart_Data E_Smart_Data; struct _E_Smart_Data { /* canvas variable */ Evas *evas; /* geometry */ int x, y, w, h; /* test object */ Evas_Object *o_base; /* crtc config */ E_Randr_Crtc_Config *crtc; /* output config */ E_Randr_Output_Config *output; /* list of modes */ Eina_List *modes; /* visibility flag */ Eina_Bool visible : 1; }; /* smart 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); /* local function prototypes */ static void _e_smart_monitor_modes_fill(E_Smart_Data *sd); static int _e_smart_monitor_modes_sort(const void *data1, const void *data2); /* external functions exposed by this widget */ Evas_Object * e_smart_monitor_add(Evas *evas) { LOGFN(__FILE__, __LINE__, __FUNCTION__); 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); } void e_smart_monitor_crtc_set(Evas_Object *obj, E_Randr_Crtc_Config *crtc) { E_Smart_Data *sd; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* 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; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* set the output config */ sd->output = output; /* since we now have the output, let's be preemptive and fill in modes */ _e_smart_monitor_modes_fill(sd); } /* smart functions */ static void _e_smart_add(Evas_Object *obj) { E_Smart_Data *sd; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* 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); sd->o_base = evas_object_rectangle_add(sd->evas); evas_object_color_set(sd->o_base, 255, 0, 0, 255); /* set the objects smart data */ evas_object_smart_data_set(obj, sd); } static void _e_smart_del(Evas_Object *obj) { E_Smart_Data *sd; Ecore_X_Randr_Mode_Info *mode; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; evas_object_del(sd->o_base); /* free the list of modes */ EINA_LIST_FREE(sd->modes, mode) ecore_x_randr_mode_info_free(mode); /* 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; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* if there is no position change, then get out */ if ((sd->x == x) && (sd->y == y)) return; sd->x = x; sd->y = y; evas_object_move(sd->o_base, x, y); } static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { E_Smart_Data *sd; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* try to get the objects smart data */ if (!(sd = evas_object_smart_data_get(obj))) return; /* if there is no size change, then get out */ if ((sd->w == w) && (sd->h == h)) return; sd->w = w; sd->h = h; evas_object_resize(sd->o_base, w, h); } static void _e_smart_show(Evas_Object *obj) { E_Smart_Data *sd; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* 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; evas_object_show(sd->o_base); /* set visibility flag */ sd->visible = EINA_TRUE; } static void _e_smart_hide(Evas_Object *obj) { E_Smart_Data *sd; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* 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; evas_object_hide(sd->o_base); /* 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; evas_object_clip_set(sd->o_base, clip); } 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; evas_object_clip_unset(sd->o_base); } /* local functions */ 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; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* 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; }