Commit c749d9f7 authored by spiiroin's avatar spiiroin

Support 100 brightness levels and up to 21 ALS profiles

Previously mce used brightness levels 1-5, that corresponded to 20, 40,
60, 80 or 100 percent brightness (manual mode) or selected one of the 5
ALS profiles available (automatic mode).

Now brightness level setting itself is percentage in manual mode and thus
allows user to have more freedom to select suitable brightness.

In automatic mode the percentage is mapped to one of the maximum of 21
ALS profiles. The profiles follow the same logic as the previous five
did, but having more of them allows user to select suitable compromise
between how low the brightness is allowed to go vs. how fast it should go
to the maximum brightness. There is also greater difference between the
profiles in "office lightning" conditions, which hopefully makes it more
apparent to users that the automatic mode is actually doing something.

Existing brightness settings in the 1-5 range are migrated on during mce
start up.

Also the dimmed display brightness is now dynamic and is always less
bright than the display on brightness.

[mce] Support 100 brightness levels and 21 ALS profiles. Fixes JB#13670
parent 32c586b4
......@@ -1226,19 +1226,19 @@ static const setting_t gconf_defaults[] =
// MCE_GCONF_DISPLAY_BRIGHTNESS_PATH @ modules/display.h
.key = "/system/osso/dsm/display/display_brightness",
.type = "i",
.def = "3",
.def = "3", // Note: Legacy value, migrated at mce startup
},
{
// Hint for settings UI. Not used by MCE itself.
// MCE_GCONF_DISPLAY_BRIGHTNESS_LEVEL_SIZE_PATH @ modules/display.h
.key = "/system/osso/dsm/display/display_brightness_level_step",
.type = "i",
.def = "1",
.def = "1", // Note: Legacy value, migrated at mce startup
},
{
// Hint for settings UI. Not used by MCE itself.
// MCE_GCONF_DISPLAY_BRIGHTNESS_LEVEL_COUNT_PATH @ modules/display.h
.key = "/system/osso/dsm/display/max_display_brightness_levels",
.type = "i",
.def = "5",
.def = "5", // Note: Legacy value, migrated at mce startup
},
{
// MCE_GCONF_DISPLAY_DIM_TIMEOUT_LIST_PATH @ modules/display.h
......
......@@ -8,28 +8,76 @@
[BrightnessDisplay]
LimitsMinimum=1;2;3;6;11;20;36;66;121;220;515;663;853;1099;1414;1821;2344;3017;3884;5000
LevelsMinimum=5;8;10;13;15;18;20;23;25;28;37;44;51;58;65;72;79;86;93;100
LimitsProfile0=1;2;4;6;11;19;34;61;109;195;350;457;596;778;1014;1323;1726;2252;2938;3833;5000
LevelsProfile0=1;3;5;7;9;11;13;15;17;19;20;28;36;44;52;60;68;76;84;92;100
LimitsEconomy=1;2;3;6;11;20;36;66;121;220;504;634;798;1005;1265;1592;2005;2524;3177;4000
LevelsEconomy=15;18;21;24;27;30;33;36;39;42;51;56;62;67;73;78;84;89;95;100
LimitsProfile1=1;2;4;6;11;19;34;61;109;195;350;454;589;764;990;1284;1665;2159;2800;3631;4708
LevelsProfile1=1;4;6;8;10;12;15;17;19;21;23;31;39;47;54;62;70;77;85;93;100
LimitsNormal=1;2;3;6;11;20;36;66;121;220;489;599;732;896;1095;1340;1639;2005;2453;3000
LevelsNormal=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
LimitsProfile2=1;2;4;6;11;19;34;61;109;195;350;452;582;750;967;1246;1606;2070;2668;3440;4433
LevelsProfile2=2;5;7;10;12;14;17;19;22;24;26;34;41;49;56;63;71;78;86;93;100
LimitsBright=1;2;3;6;11;20;36;66;121;220;470;552;648;761;894;1051;1234;1450;1703;2000
LevelsBright=55;57;59;61;63;65;67;69;71;73;78;80;83;85;88;90;93;95;98;100
LimitsProfile3=1;2;4;6;11;19;34;61;109;195;350;449;575;737;944;1209;1549;1985;2543;3258;4174
LevelsProfile3=2;5;8;11;13;16;19;21;24;27;29;37;44;51;58;65;72;79;86;93;100
LimitsMaximum=1;2;3;6;11;20;36;66;121;220;438;480;527;577;632;693;760;833;912;1000
LevelsMaximum=80;81;82;83;84;85;86;87;88;89;91;92;93;94;95;96;97;98;99;100
LimitsProfile4=1;2;4;6;11;19;34;61;109;195;350;446;568;724;921;1173;1494;1903;2423;3086;3930
LevelsProfile4=2;5;8;11;14;17;20;23;26;29;32;39;46;53;60;66;73;80;87;94;100
LimitsProfile5=1;2;4;6;11;19;34;61;109;195;350;444;561;711;899;1138;1441;1824;2309;2923;3700
LevelsProfile5=3;7;10;13;16;19;23;26;29;32;35;42;48;55;61;68;74;81;87;94;100
LimitsProfile6=1;2;4;6;11;19;34;61;109;195;350;441;555;698;878;1105;1390;1749;2201;2769;3484
LevelsProfile6=4;8;11;15;18;21;25;28;32;35;38;45;51;57;63;69;76;82;88;94;100
LimitsProfile7=1;2;4;6;11;19;34;61;109;195;350;438;548;685;857;1072;1341;1677;2098;2624;3281
LevelsProfile7=4;8;12;16;19;23;27;30;34;38;41;47;53;59;65;71;77;83;89;95;100
LimitsProfile8=1;2;4;6;11;19;34;61;109;195;350;436;542;673;837;1040;1293;1608;1999;2485;3089
LevelsProfile8=5;9;13;17;21;25;29;33;37;41;44;50;56;61;67;72;78;84;89;95;100
LimitsProfile9=1;2;4;6;11;19;34;61;109;195;350;433;535;661;817;1010;1248;1542;1905;2354;2909
LevelsProfile9=7;11;15;19;23;27;31;35;39;43;47;53;58;63;69;74;79;85;90;95;100
LimitsProfile10=1;2;4;6;11;19;34;61;109;195;350;430;529;649;798;980;1203;1478;1816;2230;2739
LevelsProfile10=8;13;17;21;25;29;34;38;42;46;50;55;60;65;70;75;80;85;90;95;100
LimitsProfile11=1;2;4;6;11;19;34;61;109;195;350;428;522;638;779;951;1161;1417;1730;2113;2579
LevelsProfile11=10;15;19;23;28;32;36;41;45;49;53;58;63;68;72;77;82;86;91;96;100
LimitsProfile12=1;2;4;6;11;19;34;61;109;195;350;425;516;626;760;922;1119;1358;1649;2001;2428
LevelsProfile12=13;18;22;26;31;35;39;44;48;52;56;61;65;70;74;78;83;87;92;96;100
LimitsProfile13=1;2;4;6;11;19;34;61;109;195;350;423;510;615;742;895;1080;1302;1571;1895;2286
LevelsProfile13=16;21;25;29;34;38;42;47;51;55;59;64;68;72;76;80;84;88;92;96;100
LimitsProfile14=1;2;4;6;11;19;34;61;109;195;350;420;504;604;724;869;1041;1249;1498;1796;2153
LevelsProfile14=20;25;29;33;37;41;46;50;54;58;62;66;70;74;78;81;85;89;93;97;100
LimitsProfile15=1;2;4;6;11;19;34;61;109;195;350;418;498;593;707;843;1005;1197;1427;1701;2027
LevelsProfile15=24;29;33;37;41;45;49;53;57;61;65;69;72;76;79;83;86;90;93;97;100
LimitsProfile16=1;2;4;6;11;19;34;61;109;195;350;415;492;583;690;818;969;1148;1360;1611;1908
LevelsProfile16=30;34;38;42;46;49;53;57;61;65;68;72;75;78;81;84;88;91;94;97;100
LimitsProfile17=1;2;4;6;11;19;34;61;109;195;350;413;486;572;674;794;935;1101;1296;1526;1797
LevelsProfile17=37;41;44;48;51;54;58;61;65;68;71;74;77;80;83;86;89;92;95;98;100
LimitsProfile18=1;2;4;6;11;19;34;61;109;195;350;410;480;562;658;770;901;1055;1235;1446;1692
LevelsProfile18=46;49;52;55;58;60;63;66;69;72;74;77;80;82;85;87;90;93;95;98;100
LimitsProfile19=1;2;4;6;11;19;34;61;109;195;350;408;474;552;642;747;869;1012;1177;1369;1593
LevelsProfile19=57;59;61;63;65;67;69;71;73;75;77;80;82;84;87;89;91;94;96;98;100
LimitsProfile20=1;2;4;6;11;19;34;61;109;195;350;405;469;542;627;725;839;970;1122;1297;1500
LevelsProfile20=70;71;72;73;74;75;76;77;78;79;80;82;84;86;88;90;92;94;96;98;100
[BrightnessLed]
LimitsNormal=1;2;3;6;11;20;36;66;121;220;489;599;732;896;1095;1340;1639;2005;2453;3000
LevelsNormal=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
LimitsProfile0=1;2;3;6;11;20;36;66;121;220;489;599;732;896;1095;1340;1639;2005;2453;3000
LevelsProfile0=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
[BrightnessKeypad]
LimitsNormal=1;2;3;6;11;20;36;66;121;220;489;599;732;896;1095;1340;1639;2005;2453;3000
LevelsNormal=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
LimitsProfile0=1;2;3;6;11;20;36;66;121;220;489;599;732;896;1095;1340;1639;2005;2453;3000
LevelsProfile0=30;33;36;39;42;45;48;51;54;57;64;68;72;76;80;84;88;92;96;100
......@@ -409,4 +409,40 @@ void mce_quit_mainloop(void);
res;\
})
/** Translate integer value from one range to another
*
* Linear conversion of a value in [src_lo, src_hi] range
* to [dst_lo, dst_hi] range.
*
* Uses rounding, so that 55 [0,100] -> 6 [0, 10].
*
* @param src_lo lower bound for source range
* @param src_hi upper bound for source range
* @param dst_lo lower bound for destination range
* @param dst_hi upper bound for destination range
* @param val value in source range to be translated
*
* @return input value mapped to destination range
*/
static inline int
mce_xlat_int(int src_lo, int src_hi, int dst_lo, int dst_hi, int val)
{
/* Deal with empty ranges first; assume that the
* low bound is sanest choise available */
if( src_lo >= src_hi || dst_lo >= dst_hi )
return dst_lo;
int src_range = src_hi - src_lo;
int dst_range = dst_hi - dst_lo;
val -= src_lo;
val = (val * dst_range + src_range / 2) / src_range;
val += dst_lo;
if( val > dst_hi ) val = dst_hi; else
if( val < dst_lo ) val = dst_lo;
return val;
}
#endif /* _MCE_H_ */
This diff is collapsed.
......@@ -119,8 +119,17 @@
#ifndef MCE_GCONF_DISPLAY_PATH
#define MCE_GCONF_DISPLAY_PATH "/system/osso/dsm/display"
#endif /* MCE_GCONF_DISPLAY_PATH */
/** Path to the display brightness GConf setting */
#define MCE_GCONF_DISPLAY_BRIGHTNESS_PATH MCE_GCONF_DISPLAY_PATH "/display_brightness"
/** Path to the display brightness level count GConf setting */
#define MCE_GCONF_DISPLAY_BRIGHTNESS_LEVEL_COUNT_PATH MCE_GCONF_DISPLAY_PATH "/max_display_brightness_levels"
/** Path to the display brightness level size GConf setting */
#define MCE_GCONF_DISPLAY_BRIGHTNESS_LEVEL_SIZE_PATH MCE_GCONF_DISPLAY_PATH "/display_brightness_level_step"
/** Path to the list of possible dim timeouts GConf setting */
#define MCE_GCONF_DISPLAY_DIM_TIMEOUT_LIST_PATH MCE_GCONF_DISPLAY_PATH "/possible_display_dim_timeouts"
/** Path to the dim timeout GConf setting */
......@@ -145,10 +154,22 @@
/** Path to the unresponsive lipstick core dump delay */
#define MCE_GCONF_LIPSTICK_CORE_DELAY_PATH MCE_GCONF_DISPLAY_PATH "/lipstick_core_dump_delay"
/* NOTE: The following defines the legacy mce brightness scale. It is
* carved in stone for the sake of backwards compatibility. On
* startup mce will migrate existing, possibly modified by user
* brightness settings to 1-100 range - Which is then used for
* actual brightness control.
*/
/** Default display brightness on a scale from 1-5 */
#define DEFAULT_DISP_BRIGHTNESS 3 /* 60% */
/** Default display brightness (power save mode active) on a scale from 1-5 */
#define DEFAULT_PSM_DISP_BRIGHTNESS 1 /* 20% */
/** Number of display brightness steps */
#define DEFAULT_DISP_BRIGHTNESS_STEP_COUNT 5
/** Logical size of each step; not sure if this has ever been used */
#define DEFAULT_DISP_BRIGHTNESS_STEP_SIZE 1
/** Default blank timeout, in seconds */
#define DEFAULT_BLANK_TIMEOUT 3 /* 3 seconds */
/**
......
......@@ -64,7 +64,7 @@ enum
*
* Enough to cover 5% to 95% in 5% steps.
*/
ALS_LUX_STEPS = 20, // allows 5% steps for [5 ... 100] range
ALS_LUX_STEPS = 21, // allows 5% steps for [5 ... 100] range
};
/** A step in ALS ramp */
......@@ -80,8 +80,8 @@ typedef struct
/** Filter name; used for locating configuration data */
const char *id;
/** ALS profiles the filter supports; used when loading config */
unsigned mask;
/* Number of profiles available */
int profiles;
/** Threshold: lower lux limit */
int lux_lo;
......@@ -133,25 +133,18 @@ static const char * const color_profiles[] =
static als_filter_t lut_display =
{
.id = "Display",
.mask = (1u << ALS_PROFILE_MINIMUM |
1u << ALS_PROFILE_ECONOMY |
1u << ALS_PROFILE_NORMAL |
1u << ALS_PROFILE_BRIGHT |
1u << ALS_PROFILE_MAXIMUM),
};
/** ALS filtering state for keypad backlight brightness */
static als_filter_t lut_key =
{
.id = "Keypad",
.mask = 1u << ALS_PROFILE_NORMAL,
};
/** ALS filtering state for indication led brightness */
static als_filter_t lut_led =
{
.id = "Led",
.mask = 1u << ALS_PROFILE_NORMAL,
};
static gboolean set_color_profile(const gchar *id);
......@@ -180,33 +173,6 @@ static gboolean color_profile_exists(const char *id)
return FALSE;
}
/** ALS profile id to string
*
* @param id profile enumeration id
*
* @return name of profile
*/
static const char *
als_profile_name(als_profile_t id)
{
static const char * const lut[ALS_PROFILE_COUNT] =
{
[ALS_PROFILE_MINIMUM] = "Minimum",
[ALS_PROFILE_ECONOMY] = "Economy",
[ALS_PROFILE_NORMAL] = "Normal",
[ALS_PROFILE_BRIGHT] = "Bright",
[ALS_PROFILE_MAXIMUM] = "Maximum",
};
const char *res = 0;
if( (unsigned)id < (unsigned) ALS_PROFILE_COUNT )
res = lut[id];
return res ?: "Unknown";
}
/** Remove transition thresholds from filtering state
*
* Set thresholds so that any lux value will be out of bounds.
......@@ -248,10 +214,11 @@ static void als_filter_init(als_filter_t *self)
* @param grp Configuration group name
* @param prof ALS profile id
*/
static void
static bool
als_filter_load_profile(als_filter_t *self, const char *grp,
als_profile_t prof)
{
bool success = false;
gsize lim_cnt = 0;
gsize lev_cnt = 0;
gint *lim_val = 0;
......@@ -259,14 +226,15 @@ als_filter_load_profile(als_filter_t *self, const char *grp,
char lim_key[64];
char lev_key[64];
snprintf(lim_key, sizeof lim_key, "Limits%s", als_profile_name(prof));
snprintf(lev_key, sizeof lev_key, "Levels%s", als_profile_name(prof));
snprintf(lim_key, sizeof lim_key, "LimitsProfile%d", prof);
snprintf(lev_key, sizeof lev_key, "LevelsProfile%d", prof);
lim_val = mce_conf_get_int_list(grp, lim_key, &lim_cnt);
lev_val = mce_conf_get_int_list(grp, lev_key, &lev_cnt);
if( !lim_val || lim_cnt < 1 ) {
mce_log(LL_WARN, "[%s] %s: no items", grp, lim_key);
if( prof == 0 )
mce_log(LL_WARN, "[%s] %s: no items", grp, lim_key);
goto EXIT;
}
......@@ -290,9 +258,13 @@ als_filter_load_profile(als_filter_t *self, const char *grp,
self->lut[prof][k].lux = lim_val[k];
self->lut[prof][k].val = lev_val[k];
}
success = true;
EXIT:
g_free(lim_val);
g_free(lev_val);
return success;
}
/** Load ALS ramps into filtering state
......@@ -311,10 +283,13 @@ static void als_filter_load_config(als_filter_t *self)
goto EXIT;
}
for( int i = 0; i < ALS_PROFILE_COUNT; ++i ) {
if( self->mask & (1u << i) )
als_filter_load_profile(self, grp, i);
for( self->profiles = 0; self->profiles < ALS_PROFILE_COUNT; ++self->profiles ) {
if( !als_filter_load_profile(self, grp, self->profiles) )
break;
}
if( self->profiles < 1 )
mce_log(LL_WARN, "[%s]: als config broken", grp);
EXIT:
return;
}
......@@ -542,10 +517,15 @@ static gpointer display_brightness_filter(gpointer data)
{
int setting = GPOINTER_TO_INT(data);
if( setting < 1 ) setting = 1; else
if( setting > 5 ) setting = 5;
if( setting < 1 ) setting = 1; else
if( setting > 100 ) setting = 100;
int brightness = setting * 20;
int brightness = setting;
int max_prof = lut_display.profiles - 1;
if( max_prof < 0 )
goto EXIT;
if( !use_als_flag )
goto EXIT;
......@@ -553,7 +533,8 @@ static gpointer display_brightness_filter(gpointer data)
if( als_lux_latest < 0 )
goto EXIT;
als_profile_t prof = setting - 1;
als_profile_t prof = mce_xlat_int(1,100, 0,max_prof, setting);
brightness = als_filter_run(&lut_display, prof, als_lux_latest);
EXIT:
......@@ -572,10 +553,13 @@ static gpointer led_brightness_filter(gpointer data)
int value = GPOINTER_TO_INT(data);
int scale = 40;
if( lut_led.profiles < 1 )
goto EXIT;
if( als_lux_latest < 0 )
goto EXIT;
scale = als_filter_run(&lut_led, ALS_PROFILE_NORMAL, als_lux_latest);
scale = als_filter_run(&lut_led, 0, als_lux_latest);
EXIT:
return GINT_TO_POINTER(value * scale / 100);
......@@ -592,10 +576,13 @@ static gpointer key_backlight_filter(gpointer data)
int value = GPOINTER_TO_INT(data);
int scale = 100;
if( lut_key.profiles < 1 )
goto EXIT;
if( als_lux_latest < 0 )
goto EXIT;
scale = als_filter_run(&lut_key, ALS_PROFILE_NORMAL, als_lux_latest);
scale = als_filter_run(&lut_key, 0, als_lux_latest);
EXIT:
return GINT_TO_POINTER(value * scale / 100);
......
......@@ -212,12 +212,7 @@ typedef struct {
/** ALS profiles */
typedef enum {
ALS_PROFILE_MINIMUM = 0, /**< Minimum profile */
ALS_PROFILE_ECONOMY, /**< Economy profile */
ALS_PROFILE_NORMAL, /**< Normal profile */
ALS_PROFILE_BRIGHT, /**< Bright profile */
ALS_PROFILE_MAXIMUM, /**< Maximum profile */
ALS_PROFILE_COUNT, /**< Number of profiles */
ALS_PROFILE_COUNT = 21, /**< Number of profiles */
} als_profile_t;
#endif /* _FILTER_BRIGHTNESS_ALS_H_ */
......@@ -63,38 +63,18 @@ static display_state_t display_state = MCE_DISPLAY_UNDEF;
/**
* Simple level adjustment filter for display brightness
*
* @param data The un-processed brightness setting (1-5) stored in a pointer
* @param data The un-processed brightness setting (1-100) stored in a pointer
* @return The processed brightness value (percentage)
*/
static gpointer display_brightness_filter(gpointer data) G_GNUC_PURE;
static gpointer display_brightness_filter(gpointer data)
{
gint raw = GPOINTER_TO_INT(data);
gpointer retval;
/* If the display is off or in low power mode,
* don't update its brightness
*/
if ((display_state == MCE_DISPLAY_OFF) ||
(display_state == MCE_DISPLAY_LPM_OFF) ||
(display_state == MCE_DISPLAY_LPM_ON)) {
raw = 0;
goto EXIT;
}
/* Safety net */
if (raw < DISPLAY_BRIGHTNESS_MINIMUM)
raw = DISPLAY_BRIGHTNESS_MINIMUM;
else if (raw > DISPLAY_BRIGHTNESS_MAXIMUM)
raw = DISPLAY_BRIGHTNESS_MAXIMUM;
/* Convert to percentage */
raw *= 20;
EXIT:
retval = GINT_TO_POINTER(raw);
return retval;
gint retval = GPOINTER_TO_INT(data);
if( retval < 1 ) retval = 1; else
if( retval > 100 ) retval = 100;
return GINT_TO_POINTER(retval);
}
/**
......
......@@ -1773,7 +1773,7 @@ static void xmce_set_display_brightness(const char *args)
debugf("%s(%s)\n", __FUNCTION__, args);
int val = xmce_parse_integer(args);
if( val < 1 || val > 5 ) {
if( val < 1 || val > 100 ) {
errorf("%d: invalid brightness value\n", val);
exit(EXIT_FAILURE);
}
......@@ -1790,7 +1790,7 @@ static void xmce_get_display_brightness(void)
strcpy(txt, "unknown");
if( mcetool_gconf_get_int(MCE_GCONF_DISPLAY_BRIGHTNESS_PATH, &val) )
snprintf(txt, sizeof txt, "%d", (int)val);
printf("%-"PAD1"s %s (1-5)\n", "Brightness:", txt);
printf("%-"PAD1"s %s (1-100)\n", "Brightness:", txt);
}
/* ------------------------------------------------------------------------- *
......@@ -2872,9 +2872,9 @@ PARAM"-i, --set-fake-doubletap=<enabled|disabled>\n"
EXTRA"set the doubletap emulation mode; valid modes are:\n"
EXTRA" 'enabled' and 'disabled'\n"
#endif
PARAM"-b, --set-display-brightness=<1|2|3|4|5>\n"
PARAM"-b, --set-display-brightness=<1...100>\n"
EXTRA"set the display brightness to BRIGHTNESS;\n"
EXTRA" valid values are: 1-5\n"
EXTRA" valid values are: 1-100\n"
PARAM"-g, --set-als-mode=<enabled|disabled>\n"
EXTRA"set the als mode; valid modes are:\n"
EXTRA" 'enabled' and 'disabled'\n"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment