enlightenment/src/modules/conf_randr/e_int_config_randr_resoluti...

293 lines
9.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "e_int_config_randr.h"
#include "e_randr.h"
#include "e_widget_ilist.h"
#ifdef Ecore_X_Randr_Unset
#undef Ecore_X_Randr_Unset
#define Ecore_X_Randr_Unset -1
#else
#define Ecore_X_Randr_Unset -1
#endif
#ifdef Ecore_X_Randr_None
#undef Ecore_X_Randr_None
#endif
#define Ecore_X_Randr_None 0
#define ICON_WIDTH 10
#define ICON_HEIGHT 10
#define RESOLUTION_TXT_MAX_LENGTH 50
extern E_Config_Dialog_Data *e_config_runtime_info;
static Ecore_X_Randr_Mode_Info disabled_mode = {.xid = Ecore_X_Randr_None, .name = "Disabled"};
static void _resolution_widget_selected_cb(void *data);
Eina_Bool
resolution_widget_create_data(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (odd->crtc)
{
odd->preferred_mode = (Ecore_X_Randr_Mode_Info *)eina_list_data_get(odd->crtc->outputs_common_modes);
odd->previous_mode = odd->crtc->current_mode ? odd->crtc->current_mode : &disabled_mode;
}
else if (odd->output && odd->output->monitor)
{
odd->previous_mode = NULL;
odd->preferred_mode = (Ecore_X_Randr_Mode_Info *)eina_list_data_get(odd->output->monitor->preferred_modes);
}
odd->new_mode = NULL;
}
return EINA_TRUE;
}
void
resolution_widget_free_cfdata(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__)
{
}
Evas_Object *
resolution_widget_basic_create_widgets(Evas *canvas)
{
Evas_Object *widget;
if (e_config_runtime_info->gui.widgets.resolution.widget)
return e_config_runtime_info->gui.widgets.resolution.widget;
else if (!canvas || !e_config_runtime_info || !(widget = e_widget_ilist_add(canvas, ICON_WIDTH * e_scale, ICON_HEIGHT * e_scale, NULL)))
return NULL;
e_widget_ilist_multi_select_set(widget, EINA_FALSE);
e_widget_disabled_set(widget, EINA_TRUE);
evas_object_show(widget);
return widget;
}
Eina_Bool
resolution_widget_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata __UNUSED__)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Ecore_X_Randr_Output *outputs = NULL;
E_Randr_Crtc_Info *crtc_info = NULL;
Eina_List *it, *it2;
int noutputs = Ecore_X_Randr_Unset;
Eina_Bool success = EINA_TRUE, another_one_enabled = EINA_FALSE;
//make sure at least one other output is not disabled
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, odd)
{
if ((!odd->new_mode && odd->previous_mode && (odd->previous_mode != &disabled_mode)) || (odd->new_mode && (odd->new_mode != &disabled_mode)))
{
another_one_enabled = EINA_TRUE;
break;
}
}
if (!another_one_enabled)
{
e_util_dialog_show("Invalid configuration!", "At least one monitor has to remain enabled!");
fprintf(stderr, "CONF_RANDR: No other monitor is enabled, aborting reconfiguration.\n");
return EINA_FALSE;
}
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, odd)
{
if (!odd || !odd->new_mode || (odd->new_mode == odd->previous_mode))
continue;
if (odd->crtc)
crtc_info = odd->crtc; //CRTC is already asssigned, easy one!
else if (odd->output)
{
//CRTC not assigned yet. Let's try to find a non occupied one.
fprintf(stderr, "CONF_RANDR: Trying to find a CRTC for output %d, %d crtcs are possible.\n", odd->output->xid, eina_list_count(odd->output->possible_crtcs));
outputs = &odd->output->xid;
noutputs = 1;
EINA_LIST_FOREACH(odd->output->possible_crtcs, it2, crtc_info)
{
if (crtc_info->outputs)
crtc_info = NULL; //CRTC is not occupied yet
else
break;
}
}
if (!crtc_info)
{
fprintf(stderr, "CONF_RANDR: Changing mode failed, no unoccupied CRTC found!\n");
success = EINA_FALSE;
continue;
}
if (odd->new_mode == crtc_info->current_mode)
{
if (odd->output && (eina_list_data_find(crtc_info->outputs, odd->output)))
fprintf(stderr, "CONF_RANDR: Nothing to be done for output %s.\n", odd->output->name);
fprintf(stderr, "CONF_RANDR: Resolution remains unchanged for CRTC %d.\n", crtc_info->xid);
continue;
}
fprintf(stderr, "CONF_RANDR: Changing mode of crtc %d to %d.\n", crtc_info->xid, odd->new_mode->xid);
if (ecore_x_randr_crtc_mode_set(cfd->con->manager->root, crtc_info->xid, outputs, noutputs, odd->new_mode->xid))
{
//update information
odd->crtc = crtc_info;
}
}
return success;
}
Eina_Bool
resolution_widget_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata __UNUSED__)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *it;
EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, it, odd)
{
if (!odd || !odd->new_mode)
continue;
if (odd->new_mode != odd->previous_mode)
return EINA_TRUE;
}
return EINA_FALSE;
}
void
resolution_widget_update_list(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
{
Eina_List *iter, *modelist = NULL;
Ecore_X_Randr_Mode_Info *mode_info, *current_mode = NULL;
char resolution_text[RESOLUTION_TXT_MAX_LENGTH];
float rate;
Eina_Bool enable = EINA_FALSE;
int i = 0;
e_widget_ilist_freeze(e_config_runtime_info->gui.widgets.resolution.widget);
e_widget_ilist_clear(e_config_runtime_info->gui.widgets.resolution.widget);
if (!odd)
goto _go_and_return;
//select correct mode list
if (odd->new_mode)
current_mode = odd->new_mode;
else if (odd->crtc)
{
if (!odd->crtc->current_mode)
current_mode = &disabled_mode;
else
current_mode = odd->crtc->current_mode;
}
if (odd->crtc)
modelist = odd->crtc->outputs_common_modes;
else if (odd->output && odd->output->monitor)
modelist = odd->output->monitor->modes;
if (!modelist)
goto _go_and_return;
EINA_LIST_FOREACH(modelist, iter, mode_info)
{
//calculate refresh rate
if (!mode_info) continue;
if (mode_info->hTotal && mode_info->vTotal)
rate = ((float)mode_info->dotClock /
((float)mode_info->hTotal * (float)mode_info->vTotal));
else
rate = 0.0;
if (mode_info->name)
snprintf(resolution_text, (RESOLUTION_TXT_MAX_LENGTH - 1), _("%s@%.1fHz"), mode_info->name, rate);
else
snprintf(resolution_text, (RESOLUTION_TXT_MAX_LENGTH - 1), _("%d×%d@%.1fHz"), mode_info->width, mode_info->height, rate);
e_widget_ilist_append(e_config_runtime_info->gui.widgets.resolution.widget, NULL, resolution_text, _resolution_widget_selected_cb, mode_info, NULL);
if (mode_info != current_mode)
i++;
else
e_widget_ilist_selected_set(e_config_runtime_info->gui.widgets.resolution.widget, i);
}
//append 'disabled' mode
e_widget_ilist_append(e_config_runtime_info->gui.widgets.resolution.widget, NULL, _("Disabled"), NULL, &disabled_mode, NULL);
if (current_mode == &disabled_mode) //select currently enabled mode
{
i = eina_list_count(modelist);
e_widget_ilist_selected_set(e_config_runtime_info->gui.widgets.resolution.widget, i);
}
//reenable widget
enable = EINA_TRUE;
_go_and_return:
e_widget_disabled_set(e_config_runtime_info->gui.widgets.resolution.widget, enable);
e_widget_ilist_go(e_config_runtime_info->gui.widgets.resolution.widget);
e_widget_ilist_thaw(e_config_runtime_info->gui.widgets.resolution.widget);
}
void
resolution_widget_keep_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
if (!odd || !odd->new_mode || (odd->new_mode == odd->previous_mode))
continue;
odd->previous_mode = (odd->new_mode == &disabled_mode) ? NULL : odd->new_mode;
odd->new_mode = NULL;
}
}
void
resolution_widget_discard_changes(E_Config_Dialog_Data *cfdata)
{
E_Config_Randr_Dialog_Output_Dialog_Data *odd;
Eina_List *iter;
if (!cfdata) return;
EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
{
//for now, there is no way to redisable an output during discartion
if (!odd->crtc || !odd->previous_mode) continue;
//use currently used outputs (noutputs == Ecore_X_Randr_Unset)
ecore_x_randr_crtc_mode_set(cfdata->manager->root, odd->crtc->xid, NULL, Ecore_X_Randr_Unset, odd->previous_mode->xid);
}
ecore_x_randr_screen_reset(cfdata->manager->root);
}
static void
_resolution_widget_selected_cb(void *data)
{
Ecore_X_Randr_Mode_Info *selected_mode = (Ecore_X_Randr_Mode_Info*)data;
if (!selected_mode)
return;
if (!e_config_runtime_info->gui.selected_output_dd)
{
fprintf(stderr, "CONF_RANDR: Can't set newly selected resolution, because no odd was set \"selected\" yet!\n");
return;
}
e_config_runtime_info->gui.selected_output_dd->new_mode = selected_mode;
fprintf(stderr, "CONF_RANDR: Mode %s was selected for crtc/output %d!\n", (selected_mode ? selected_mode->name : "None"), (e_config_runtime_info->gui.selected_output_dd->crtc ? e_config_runtime_info->gui.selected_output_dd->crtc->xid : e_config_runtime_info->gui.selected_output_dd->output->xid));
arrangement_widget_rep_update(e_config_runtime_info->gui.selected_output_dd);
}