summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <devilhorns@comcast.net>2013-05-19 12:41:26 +0100
committerDeon Thomas <PrinceAMD.Elive@gmail.com>2013-06-28 03:28:52 -0400
commitd8a1f8f9336d2a3a06b15fea446f89e8f9387408 (patch)
tree6b8a04c115f0b0965467ef84cfa9fe7dfdb840d0
parent83063049cf4255f10cc9ce7712fe88d3c8670aad (diff)
downloadenlightenment-d8a1f8f9336d2a3a06b15fea446f89e8f9387408.tar.gz
Backport: dc3c16c :: Fix randr dialog to display monitors that are disabled. Add function to get a monitor's preferred mode size. Add function to find any clones of a monitor. Add function to find a valid crtc for an output
NB: Raster, this should fix your reported problem ;) Signed-off-by: Chris Michael <devilhorns@comcast.net> Signed-off-by: Deon Thomas <PrinceAMD.Elive@gmail.com>
-rw-r--r--src/modules/conf_randr/e_smart_randr.c480
1 files changed, 274 insertions, 206 deletions
diff --git a/src/modules/conf_randr/e_smart_randr.c b/src/modules/conf_randr/e_smart_randr.c
index 9e305b706d..7511849f31 100644
--- a/src/modules/conf_randr/e_smart_randr.c
+++ b/src/modules/conf_randr/e_smart_randr.c
@@ -51,6 +51,10 @@ static void _e_smart_randr_monitor_cb_resized(void *data, Evas_Object *obj, void
static void _e_smart_randr_monitor_position_update(E_Smart_Data *sd, Evas_Object *obj, Evas_Object *skip);
static void _e_smart_randr_monitor_position_normalize(E_Smart_Data *sd);
+static void _e_smart_randr_monitor_preferred_mode_size_get(Ecore_X_Randr_Output output, Evas_Coord *mw, Evas_Coord *mh);
+static Evas_Object *_e_smart_randr_clone_find(Ecore_X_Window root, Ecore_X_Randr_Output output, Ecore_X_Randr_Crtc crtc, Evas_Coord cx, Evas_Coord cy, E_Smart_Data *sd);
+static Ecore_X_Randr_Crtc _e_smart_randr_crtc_find(Ecore_X_Randr_Output output);
+
/* external functions exposed by this widget */
Evas_Object *
e_smart_randr_add(Evas *evas)
@@ -81,9 +85,9 @@ e_smart_randr_virtual_size_calc(Evas_Object *obj)
{
E_Smart_Data *sd;
Ecore_X_Window root = 0;
- Ecore_X_Randr_Crtc *crtcs;
+ Ecore_X_Randr_Output *routputs;
Evas_Coord vw = 0, vh = 0;
- int ncrtcs = 0;
+ int noutputs = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@@ -98,74 +102,53 @@ e_smart_randr_virtual_size_calc(Evas_Object *obj)
/* grab the root window */
root = ecore_x_window_root_first_get();
- /* try to get the list of crtcs */
- if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
+ /* get list of outputs */
+ if ((routputs = ecore_x_randr_outputs_get(root, &noutputs)))
{
- int i = 0;
- Ecore_X_Randr_Output *routputs;
+ int j = 0;
+ intptr_t *o;
Eina_List *outputs = NULL;
- /* loop the list of crtcs and try to get the outputs on each */
- for (i = 0; i < ncrtcs; i++)
+ for (j = 0; j < noutputs; j++)
{
- int noutput = 0, j = 0;
- intptr_t *o;
-
- routputs =
- ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutput);
- if ((noutput == 0) || (!routputs))
- {
- /* find Possible outputs */
- routputs =
- ecore_x_randr_crtc_possible_outputs_get(root, crtcs[i],
- &noutput);
- if ((!noutput) || (!routputs)) continue;
- }
-
- for (j = 0; j < noutput; j++)
- {
- Ecore_X_Randr_Crtc rcrtc;
+ Ecore_X_Randr_Connection_Status status =
+ ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
- rcrtc = ecore_x_randr_output_crtc_get(root, routputs[j]);
- if ((rcrtc != 0) && (rcrtc != crtcs[i]))
- continue;
+ status =
+ ecore_x_randr_output_connection_status_get(root, routputs[j]);
+ if (status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) continue;
- outputs =
- eina_list_append(outputs, (intptr_t *)(long)routputs[j]);
- }
-
- /* loop the outputs and get the largest mode */
- EINA_LIST_FREE(outputs, o)
- {
- Ecore_X_Randr_Output output;
- Ecore_X_Randr_Mode *modes;
- Evas_Coord mw = 0, mh = 0;
- int nmode = 0;
+ outputs =
+ eina_list_append(outputs, (intptr_t *)(long)routputs[j]);
+ }
- output = (int)(long)o;
+ /* loop the outputs and get the largest mode */
+ EINA_LIST_FREE(outputs, o)
+ {
+ Ecore_X_Randr_Output output;
+ Ecore_X_Randr_Mode *modes;
+ Evas_Coord mw = 0, mh = 0;
+ int nmode = 0;
- /* try to get the list of modes for this output */
- modes =
- ecore_x_randr_output_modes_get(root, output,
- &nmode, NULL);
- if (!modes) continue;
+ output = (int)(long)o;
- /* get the size of the largest mode */
- ecore_x_randr_mode_size_get(root, modes[0], &mw, &mh);
+ /* try to get the list of modes for this output */
+ modes =
+ ecore_x_randr_output_modes_get(root, output,
+ &nmode, NULL);
+ if (!modes) continue;
- vw += MAX(mw, mh);
- vh += MAX(mw, mh);
+ /* get the size of the largest mode */
+ ecore_x_randr_mode_size_get(root, modes[0], &mw, &mh);
- /* free any allocated memory from ecore_x_randr */
- free(modes);
- }
+ vw += MAX(mw, mh);
+ vh += MAX(mw, mh);
/* free any allocated memory from ecore_x_randr */
- free(routputs);
+ free(modes);
}
- /* free any allocated memory from ecore_x_randr */
- free(crtcs);
+ free(outputs);
}
if ((vw == 0) && (vh == 0))
@@ -187,10 +170,9 @@ e_smart_randr_monitors_create(Evas_Object *obj)
E_Smart_Data *sd;
Evas *evas;
Ecore_X_Window root = 0;
- Ecore_X_Randr_Crtc *crtcs;
- int ncrtcs = 0;
Evas_Coord gx = 0, gy = 0, gw = 0, gh = 0;
- Evas_Coord nx = 0;
+ Ecore_X_Randr_Output *outputs;
+ int noutputs = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@@ -211,193 +193,157 @@ e_smart_randr_monitors_create(Evas_Object *obj)
/* grab the root window */
root = ecore_x_window_root_first_get();
- /* try to get the list of crtcs */
- if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
+ /* get a list of outputs from X */
+ if ((outputs = ecore_x_randr_outputs_get(root, &noutputs)))
{
int i = 0;
- Ecore_X_Randr_Output *routputs;
- Eina_List *outputs = NULL;
- Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0;
+ Evas_Coord nx = 0;
+ Eina_List *connected = NULL;
- /* loop the list of crtcs and try to get the outputs on each */
- for (i = 0; i < ncrtcs; i++)
+ /* loop these outputs */
+ for (i = 0; i < noutputs; i++)
{
- int noutput = 0, j = 0;
- intptr_t *o;
-
- printf("Checking Crtc: %d\n", crtcs[i]);
-
- /* TODO: Add EFL 1.8 check here and optimize this code */
-
- /* get the geometry for this crtc */
- ecore_x_randr_crtc_geometry_get(root, crtcs[i],
- &cx, &cy, &cw, &ch);
- printf("\tGeometry: %d %d %d %d\n", cx, cy, cw, ch);
-
- routputs =
- ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutput);
- printf("\t\tNum Of Outputs: %d\n", noutput);
-
- if ((noutput == 0) || (!routputs))
- {
- /* find Possible outputs */
- routputs =
- ecore_x_randr_crtc_possible_outputs_get(root, crtcs[i],
- &noutput);
- /* printf("\t\tNum Of Possible: %d\n", noutput); */
- if ((!noutput) || (!routputs)) continue;
- }
-
- /* loop possible outputs */
- for (j = 0; j < noutput; j++)
- {
- Ecore_X_Randr_Crtc rcrtc;
-
- /* get this outputs crtc */
- rcrtc = ecore_x_randr_output_crtc_get(root, routputs[j]);
- if (!rcrtc) continue;
-
- /* if crtc is not 0 (disabled), then check if it matches
- * the one we are currently working with. If it does not
- * match, then this is not a possible output for us */
- if ((rcrtc != 0) && (rcrtc != crtcs[i]))
- continue;
-
- outputs =
- eina_list_append(outputs, (intptr_t *)(long)routputs[j]);
- }
-
- /* loop the outputs and create monitors for each */
- EINA_LIST_FREE(outputs, o)
+ Evas_Object *mon;
+ Ecore_X_Randr_Crtc crtc = 0;
+ Evas_Coord mw = 0, mh = 0, crtcx = 0, crtcy = 0;
+ Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0;
+ Ecore_X_Randr_Connection_Status status =
+ ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
+
+ /* ask X if this output is connected */
+ status =
+ ecore_x_randr_output_connection_status_get(root, outputs[i]);
+
+ /* if it's not connected, skip it */
+ if (status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
+ continue;
+
+ connected =
+ eina_list_append(connected, (intptr_t *)(long)outputs[i]);
+
+ /* for each output, try to create a monitor */
+ if (!(mon = e_smart_monitor_add(evas)))
+ continue;
+
+ /* hook into monitor changed callback */
+ evas_object_smart_callback_add(mon, "monitor_changed",
+ _e_smart_randr_monitor_cb_changed, obj);
+ evas_object_smart_callback_add(mon, "monitor_moved",
+ _e_smart_randr_monitor_cb_moved, obj);
+ evas_object_smart_callback_add(mon, "monitor_resized",
+ _e_smart_randr_monitor_cb_resized, obj);
+
+ /* add this monitor to our list */
+ sd->monitors = eina_list_append(sd->monitors, mon);
+
+ /* tell monitor what the grid's virtual size is */
+ e_smart_monitor_grid_virtual_size_set(mon, sd->vw, sd->vh);
+
+ /* tell monitor what the grid is and it's geometry */
+ e_smart_monitor_grid_set(mon, sd->o_grid, gx, gy, gw, gh);
+
+ /* try to get the crtc of this output */
+ if ((crtc = ecore_x_randr_output_crtc_get(root, outputs[i])))
{
- Evas_Object *mon;
- Ecore_X_Randr_Output output;
+ Ecore_X_Randr_Mode mode = 0;
- /* for each output, try to create a monitor */
- if (!(mon = e_smart_monitor_add(evas)))
- continue;
+ /* get the geometry for this crtc */
+ ecore_x_randr_crtc_geometry_get(root, crtc,
+ &cx, &cy, &cw, &ch);
- /* hook into monitor changed callback */
- evas_object_smart_callback_add(mon, "monitor_changed",
- _e_smart_randr_monitor_cb_changed, obj);
- evas_object_smart_callback_add(mon, "monitor_moved",
- _e_smart_randr_monitor_cb_moved, obj);
- evas_object_smart_callback_add(mon, "monitor_resized",
- _e_smart_randr_monitor_cb_resized, obj);
+ e_smart_monitor_crtc_set(mon, crtc, cx, cy, cw, ch);
- /* add this monitor to our list */
- sd->monitors = eina_list_append(sd->monitors, mon);
+ mode = ecore_x_randr_crtc_mode_get(root, crtc);
- /* tell monitor what the grid's virtual size is */
- e_smart_monitor_grid_virtual_size_set(mon, sd->vw, sd->vh);
-
- /* tell monitor what the grid is and it's geometry */
- e_smart_monitor_grid_set(mon, sd->o_grid, gx, gy, gw, gh);
-
- output = (int)(long)o;
-
- printf("\t\t\tOutput %d Crtc Is: %d\n", output,
- ecore_x_randr_output_crtc_get(root, output));
-
- if ((cw == 0) && (ch == 0))
+ /* if this crtc has no mode, or it's size is 0,
+ * then it's disabled */
+ if ((!mode) || ((cw == 0) && (ch == 0)))
{
- Ecore_X_Randr_Mode *modes;
- Evas_Coord mw = 0, mh = 0;
- int nmode = 0;
-
- /* try to get the list of modes for this output */
- modes =
- ecore_x_randr_output_modes_get(root, output,
- &nmode, NULL);
- if (!modes) continue;
-
- /* get the size of the largest mode */
- ecore_x_randr_mode_size_get(root, modes[0], &mw, &mh);
-
- /* free any allocated memory from ecore_x_randr */
- free(modes);
+ /* get the size of the preferred mode for this output */
+ _e_smart_randr_monitor_preferred_mode_size_get(outputs[i],
+ &mw, &mh);
+ printf("Preferred Size: %d %d\n", mw, mh);
/* tell monitor what it's current position is
* NB: This also packs into the grid */
e_smart_monitor_current_geometry_set(mon, nx, 0, mw, mh);
+ /* tell monitor to set the background preview */
+ e_smart_monitor_background_set(mon, nx, 0);
+
+ crtcx = nx;
+ crtcy = 0;
nx += mw;
}
else
{
/* tell monitor what it's current position is
* NB: This also packs into the grid */
- e_smart_monitor_current_geometry_set(mon, cx, cy, cw, ch);
+ e_smart_monitor_current_geometry_set(mon, cx, cy,
+ cw, ch);
+
+ /* tell monitor to set the background preview */
+ e_smart_monitor_background_set(mon, cx, cy);
+ crtcx = cx;
+ crtcy = cy;
nx += cw;
}
+ }
+ else
+ {
+ crtc = _e_smart_randr_crtc_find(outputs[i]);
- /* tell monitor what crtc it uses and current position */
- e_smart_monitor_crtc_set(mon, crtcs[i], cx, cy, cw, ch);
+ /* get the size of the preferred mode for this output */
+ _e_smart_randr_monitor_preferred_mode_size_get(outputs[i],
+ &mw, &mh);
+ printf("Preferred Size: %d %d\n", mw, mh);
- /* tell monitor what output it uses */
- e_smart_monitor_output_set(mon, output);
+ /* no crtc assigned to this output. it's disabled */
+ e_smart_monitor_crtc_set(mon, crtc, nx, 0, mw, mh);
+
+ /* tell monitor what it's current position is
+ * NB: This also packs into the grid */
+ e_smart_monitor_current_geometry_set(mon, nx, 0, mw, mh);
/* tell monitor to set the background preview */
- e_smart_monitor_background_set(mon, cx, cy);
+ e_smart_monitor_background_set(mon, nx, 0);
+
+ crtcx = nx;
+ crtcy = 0;
+ nx += mw;
+ }
- /* if we have a previous crtc */
- if (i > 0)
+ /* tell monitor what output it uses */
+ e_smart_monitor_output_set(mon, outputs[i]);
+
+ if (eina_list_count(connected) > 0)
+ {
+ Eina_List *l;
+ intptr_t *o;
+ Evas_Object *pmon;
+
+ EINA_LIST_FOREACH(connected, l, o)
{
- /* check if this crtc is a clone of that one */
- Ecore_X_Randr_Crtc pcrtc = 0;
- Evas_Coord px = 0, py = 0;
+ Ecore_X_Randr_Output out;
- pcrtc = crtcs[i - 1];
+ out = (int)(long)o;
+ if (out == outputs[i]) continue;
- /* get the geometry for this previous crtc */
- ecore_x_randr_crtc_geometry_get(root, pcrtc,
- &px, &py, NULL, NULL);
+ pmon =
+ _e_smart_randr_clone_find(root, out, crtc,
+ crtcx, crtcy, sd);
- /* check if the geometry's match */
- if ((px == cx) && (py == cy))
+ if (pmon)
{
- Ecore_X_Randr_Orientation orient, porient;
-
- orient =
- ecore_x_randr_crtc_orientation_get(root, crtcs[i]);
-
- porient =
- ecore_x_randr_crtc_orientation_get(root, pcrtc);
-
- /* check orientation */
- if ((porient == orient))
- {
- Ecore_X_Randr_Mode mode = 0, pmode = 0;
-
- mode =
- ecore_x_randr_crtc_mode_get(root, crtcs[i]);
- pmode =
- ecore_x_randr_crtc_mode_get(root, pcrtc);
-
- /* check mode */
- if ((pmode == mode))
- {
- Evas_Object *pmon;
-
- /* find monitor for this prev crtc */
- if ((pmon = _e_smart_randr_monitor_crtc_find(sd, pcrtc)))
- {
- /* tell This monitor it is cloned into previous */
- e_smart_monitor_clone_set(mon, pmon);
- }
- }
- }
+ e_smart_monitor_clone_set(mon, pmon);
+ break;
}
}
}
-
- /* free any allocated memory from ecore_x_randr */
- free(routputs);
}
- /* free any allocated memory from ecore_x_randr */
- free(crtcs);
+ free(outputs);
}
}
@@ -848,3 +794,125 @@ _e_smart_randr_monitor_position_normalize(E_Smart_Data *sd)
}
}
}
+
+static void
+_e_smart_randr_monitor_preferred_mode_size_get(Ecore_X_Randr_Output output, Evas_Coord *mw, Evas_Coord *mh)
+{
+ Ecore_X_Window root = 0;
+ Ecore_X_Randr_Mode *modes;
+ int n = 0, p = 0;
+
+ if (mw) *mw = 0;
+ if (mh) *mh = 0;
+ if (!output) return;
+
+ root = ecore_x_window_root_first_get();
+
+ modes = ecore_x_randr_output_modes_get(root, output, &n, &p);
+ if ((!modes) || (n == 0)) return;
+
+ ecore_x_randr_mode_size_get(root, modes[p - 1], mw, mh);
+
+ free(modes);
+}
+
+static Evas_Object *
+_e_smart_randr_clone_find(Ecore_X_Window root, Ecore_X_Randr_Output output, Ecore_X_Randr_Crtc crtc, Evas_Coord cx, Evas_Coord cy, E_Smart_Data *sd)
+{
+ Evas_Object *mon = NULL;
+ Ecore_X_Randr_Crtc pcrtc = 0;
+ Evas_Coord px = 0, py = 0;
+
+ /* get the crtc of the previous output */
+ pcrtc = ecore_x_randr_output_crtc_get(root, output);
+ if (!pcrtc) return NULL;
+
+ /* get this crtcs geom */
+ ecore_x_randr_crtc_geometry_get(root, pcrtc,
+ &px, &py, NULL, NULL);
+
+ if ((px == cx) && (py == cy))
+ {
+ Ecore_X_Randr_Orientation orient =
+ ECORE_X_RANDR_ORIENTATION_ROT_0;
+ Ecore_X_Randr_Orientation porient =
+ ECORE_X_RANDR_ORIENTATION_ROT_0;
+
+ porient =
+ ecore_x_randr_crtc_orientation_get(root, pcrtc);
+
+ orient =
+ ecore_x_randr_crtc_orientation_get(root, crtc);
+
+ if (porient == orient)
+ {
+ Ecore_X_Randr_Mode mode = 0, pmode = 0;
+ Evas_Coord pw = 0, ph = 0;
+ Evas_Coord w = 0, h = 0;
+
+ pmode =
+ ecore_x_randr_crtc_mode_get(root, pcrtc);
+ ecore_x_randr_mode_size_get(root, pmode, &pw, &ph);
+
+ mode =
+ ecore_x_randr_crtc_mode_get(root, crtc);
+ ecore_x_randr_mode_size_get(root, mode, &w, &h);
+
+ if ((pmode == mode) || ((pw == w) && (ph == h)))
+ mon = _e_smart_randr_monitor_crtc_find(sd, pcrtc);
+ }
+ }
+
+ return mon;
+}
+
+static Ecore_X_Randr_Crtc
+_e_smart_randr_crtc_find(Ecore_X_Randr_Output output)
+{
+ Ecore_X_Randr_Crtc ret = 0;
+ Ecore_X_Window root = 0;
+ Ecore_X_Randr_Crtc *crtcs;
+ int ncrtcs = 0;
+
+ /* get root window */
+ root = ecore_x_window_root_first_get();
+
+ /* get possible crtcs for this output */
+ if ((crtcs = ecore_x_randr_output_possible_crtcs_get(root, output, &ncrtcs)))
+ {
+ Ecore_X_Randr_Output *outputs;
+ int i = 0, noutputs = 0;
+
+ for (i = 0; i < ncrtcs; i++)
+ {
+ int j = 0;
+
+ /* get any outputs on this crtc */
+ outputs =
+ ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs);
+
+ /* if this crtc has no outputs, we can use it */
+ if ((!outputs) || (noutputs == 0))
+ ret = crtcs[i];
+ else
+ {
+ /* loop the outputs */
+ for (j = 0; j < noutputs; j++)
+ {
+ /* check if it is this output */
+ if (outputs[j] == output)
+ {
+ ret = crtcs[i];
+ break;
+ }
+ }
+ }
+
+ if (ret) break;
+ }
+
+ free(crtcs);
+ }
+
+ return ret;
+}