Changed indentation everywhere
This commit is contained in:
@@ -56,7 +56,7 @@ char *battery_uwheel_command;
|
|||||||
char *battery_dwheel_command;
|
char *battery_dwheel_command;
|
||||||
gboolean battery_found;
|
gboolean battery_found;
|
||||||
|
|
||||||
char *battery_sys_prefix = (char*)"";
|
char *battery_sys_prefix = (char *)"";
|
||||||
|
|
||||||
void battery_init_fonts();
|
void battery_init_fonts();
|
||||||
char *battery_get_tooltip(void *obj);
|
char *battery_get_tooltip(void *obj);
|
||||||
@@ -65,407 +65,397 @@ void battery_dump_geometry(void *obj, int indent);
|
|||||||
|
|
||||||
void default_battery()
|
void default_battery()
|
||||||
{
|
{
|
||||||
battery_enabled = FALSE;
|
battery_enabled = FALSE;
|
||||||
battery_tooltip_enabled = TRUE;
|
battery_tooltip_enabled = TRUE;
|
||||||
battery_found = FALSE;
|
battery_found = FALSE;
|
||||||
percentage_hide = 101;
|
percentage_hide = 101;
|
||||||
battery_low_cmd_sent = FALSE;
|
battery_low_cmd_sent = FALSE;
|
||||||
battery_timeout = NULL;
|
battery_timeout = NULL;
|
||||||
bat1_has_font = FALSE;
|
bat1_has_font = FALSE;
|
||||||
bat1_font_desc = NULL;
|
bat1_font_desc = NULL;
|
||||||
bat2_has_font = FALSE;
|
bat2_has_font = FALSE;
|
||||||
bat2_font_desc = NULL;
|
bat2_font_desc = NULL;
|
||||||
ac_connected_cmd = NULL;
|
ac_connected_cmd = NULL;
|
||||||
ac_disconnected_cmd = NULL;
|
ac_disconnected_cmd = NULL;
|
||||||
battery_low_cmd = NULL;
|
battery_low_cmd = NULL;
|
||||||
battery_lclick_command = NULL;
|
battery_lclick_command = NULL;
|
||||||
battery_mclick_command = NULL;
|
battery_mclick_command = NULL;
|
||||||
battery_rclick_command = NULL;
|
battery_rclick_command = NULL;
|
||||||
battery_uwheel_command = NULL;
|
battery_uwheel_command = NULL;
|
||||||
battery_dwheel_command = NULL;
|
battery_dwheel_command = NULL;
|
||||||
battery_state.percentage = 0;
|
battery_state.percentage = 0;
|
||||||
battery_state.time.hours = 0;
|
battery_state.time.hours = 0;
|
||||||
battery_state.time.minutes = 0;
|
battery_state.time.minutes = 0;
|
||||||
battery_state.time.seconds = 0;
|
battery_state.time.seconds = 0;
|
||||||
battery_state.state = BATTERY_UNKNOWN;
|
battery_state.state = BATTERY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_battery()
|
void cleanup_battery()
|
||||||
{
|
{
|
||||||
pango_font_description_free(bat1_font_desc);
|
pango_font_description_free(bat1_font_desc);
|
||||||
bat1_font_desc = NULL;
|
bat1_font_desc = NULL;
|
||||||
pango_font_description_free(bat2_font_desc);
|
pango_font_description_free(bat2_font_desc);
|
||||||
bat2_font_desc = NULL;
|
bat2_font_desc = NULL;
|
||||||
free(battery_low_cmd);
|
free(battery_low_cmd);
|
||||||
battery_low_cmd = NULL;
|
battery_low_cmd = NULL;
|
||||||
free(battery_lclick_command);
|
free(battery_lclick_command);
|
||||||
battery_lclick_command = NULL;
|
battery_lclick_command = NULL;
|
||||||
free(battery_mclick_command);
|
free(battery_mclick_command);
|
||||||
battery_mclick_command = NULL;
|
battery_mclick_command = NULL;
|
||||||
free(battery_rclick_command);
|
free(battery_rclick_command);
|
||||||
battery_rclick_command = NULL;
|
battery_rclick_command = NULL;
|
||||||
free(battery_uwheel_command);
|
free(battery_uwheel_command);
|
||||||
battery_uwheel_command = NULL;
|
battery_uwheel_command = NULL;
|
||||||
free(battery_dwheel_command);
|
free(battery_dwheel_command);
|
||||||
battery_dwheel_command = NULL;
|
battery_dwheel_command = NULL;
|
||||||
free(ac_connected_cmd);
|
free(ac_connected_cmd);
|
||||||
ac_connected_cmd = NULL;
|
ac_connected_cmd = NULL;
|
||||||
free(ac_disconnected_cmd);
|
free(ac_disconnected_cmd);
|
||||||
ac_disconnected_cmd = NULL;
|
ac_disconnected_cmd = NULL;
|
||||||
stop_timeout(battery_timeout);
|
stop_timeout(battery_timeout);
|
||||||
battery_timeout = NULL;
|
battery_timeout = NULL;
|
||||||
battery_found = FALSE;
|
battery_found = FALSE;
|
||||||
|
|
||||||
battery_os_free();
|
battery_os_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_battery()
|
void init_battery()
|
||||||
{
|
{
|
||||||
if (!battery_enabled)
|
if (!battery_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
battery_found = battery_os_init();
|
battery_found = battery_os_init();
|
||||||
|
|
||||||
if (!battery_timeout)
|
if (!battery_timeout)
|
||||||
battery_timeout = add_timeout(10, 30000, update_battery_tick, 0, &battery_timeout);
|
battery_timeout = add_timeout(10, 30000, update_battery_tick, 0, &battery_timeout);
|
||||||
|
|
||||||
update_battery();
|
update_battery();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reinit_battery()
|
void reinit_battery()
|
||||||
{
|
{
|
||||||
battery_os_free();
|
battery_os_free();
|
||||||
battery_found = battery_os_init();
|
battery_found = battery_os_init();
|
||||||
update_battery();
|
update_battery();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_battery_panel(void *p)
|
void init_battery_panel(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
Battery *battery = &panel->battery;
|
Battery *battery = &panel->battery;
|
||||||
|
|
||||||
if (!battery_enabled)
|
if (!battery_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
battery_init_fonts();
|
battery_init_fonts();
|
||||||
|
|
||||||
if (!battery->area.bg)
|
if (!battery->area.bg)
|
||||||
battery->area.bg = &g_array_index(backgrounds, Background, 0);
|
battery->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
|
|
||||||
battery->area.parent = p;
|
battery->area.parent = p;
|
||||||
battery->area.panel = p;
|
battery->area.panel = p;
|
||||||
snprintf(battery->area.name, sizeof(battery->area.name), "Battery");
|
snprintf(battery->area.name, sizeof(battery->area.name), "Battery");
|
||||||
battery->area._draw_foreground = draw_battery;
|
battery->area._draw_foreground = draw_battery;
|
||||||
battery->area.size_mode = LAYOUT_FIXED;
|
battery->area.size_mode = LAYOUT_FIXED;
|
||||||
battery->area._resize = resize_battery;
|
battery->area._resize = resize_battery;
|
||||||
battery->area._compute_desired_size = battery_compute_desired_size;
|
battery->area._compute_desired_size = battery_compute_desired_size;
|
||||||
battery->area._is_under_mouse = full_width_area_is_under_mouse;
|
battery->area._is_under_mouse = full_width_area_is_under_mouse;
|
||||||
battery->area.on_screen = TRUE;
|
battery->area.on_screen = TRUE;
|
||||||
battery->area.resize_needed = 1;
|
battery->area.resize_needed = 1;
|
||||||
battery->area.has_mouse_over_effect =
|
battery->area.has_mouse_over_effect =
|
||||||
panel_config.mouse_effects && (battery_lclick_command || battery_mclick_command || battery_rclick_command ||
|
panel_config.mouse_effects && (battery_lclick_command || battery_mclick_command || battery_rclick_command ||
|
||||||
battery_uwheel_command || battery_dwheel_command);
|
battery_uwheel_command || battery_dwheel_command);
|
||||||
battery->area.has_mouse_press_effect = battery->area.has_mouse_over_effect;
|
battery->area.has_mouse_press_effect = battery->area.has_mouse_over_effect;
|
||||||
if (battery_tooltip_enabled)
|
if (battery_tooltip_enabled)
|
||||||
battery->area._get_tooltip_text = battery_get_tooltip;
|
battery->area._get_tooltip_text = battery_get_tooltip;
|
||||||
instantiate_area_gradients(&battery->area);
|
instantiate_area_gradients(&battery->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_init_fonts()
|
void battery_init_fonts()
|
||||||
{
|
{
|
||||||
if (!bat1_font_desc) {
|
if (!bat1_font_desc) {
|
||||||
bat1_font_desc = pango_font_description_from_string(get_default_font());
|
bat1_font_desc = pango_font_description_from_string(get_default_font());
|
||||||
pango_font_description_set_size(bat1_font_desc, pango_font_description_get_size(bat1_font_desc) - PANGO_SCALE);
|
pango_font_description_set_size(bat1_font_desc, pango_font_description_get_size(bat1_font_desc) - PANGO_SCALE);
|
||||||
}
|
}
|
||||||
if (!bat2_font_desc) {
|
if (!bat2_font_desc) {
|
||||||
bat2_font_desc = pango_font_description_from_string(get_default_font());
|
bat2_font_desc = pango_font_description_from_string(get_default_font());
|
||||||
pango_font_description_set_size(bat2_font_desc, pango_font_description_get_size(bat2_font_desc) - PANGO_SCALE);
|
pango_font_description_set_size(bat2_font_desc, pango_font_description_get_size(bat2_font_desc) - PANGO_SCALE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_default_font_changed()
|
void battery_default_font_changed()
|
||||||
{
|
{
|
||||||
if (!battery_enabled)
|
if (!battery_enabled)
|
||||||
return;
|
return;
|
||||||
if (bat1_has_font && bat2_has_font)
|
if (bat1_has_font && bat2_has_font)
|
||||||
return;
|
return;
|
||||||
if (!bat1_has_font) {
|
if (!bat1_has_font) {
|
||||||
pango_font_description_free(bat1_font_desc);
|
pango_font_description_free(bat1_font_desc);
|
||||||
bat1_font_desc = NULL;
|
bat1_font_desc = NULL;
|
||||||
}
|
}
|
||||||
if (!bat2_has_font) {
|
if (!bat2_has_font) {
|
||||||
pango_font_description_free(bat2_font_desc);
|
pango_font_description_free(bat2_font_desc);
|
||||||
bat2_font_desc = NULL;
|
bat2_font_desc = NULL;
|
||||||
}
|
}
|
||||||
battery_init_fonts();
|
battery_init_fonts();
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
panels[i].battery.area.resize_needed = TRUE;
|
panels[i].battery.area.resize_needed = TRUE;
|
||||||
schedule_redraw(&panels[i].battery.area);
|
schedule_redraw(&panels[i].battery.area);
|
||||||
}
|
}
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_battery_tick(void *arg)
|
void update_battery_tick(void *arg)
|
||||||
{
|
{
|
||||||
if (!battery_enabled)
|
if (!battery_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gboolean old_found = battery_found;
|
gboolean old_found = battery_found;
|
||||||
int old_percentage = battery_state.percentage;
|
int old_percentage = battery_state.percentage;
|
||||||
gboolean old_ac_connected = battery_state.ac_connected;
|
gboolean old_ac_connected = battery_state.ac_connected;
|
||||||
int16_t old_hours = battery_state.time.hours;
|
int16_t old_hours = battery_state.time.hours;
|
||||||
int8_t old_minutes = battery_state.time.minutes;
|
int8_t old_minutes = battery_state.time.minutes;
|
||||||
|
|
||||||
if (!battery_found) {
|
if (!battery_found) {
|
||||||
init_battery();
|
init_battery();
|
||||||
old_ac_connected = battery_state.ac_connected;
|
old_ac_connected = battery_state.ac_connected;
|
||||||
}
|
}
|
||||||
if (update_battery() != 0) {
|
if (update_battery() != 0) {
|
||||||
// Try to reconfigure on failed update
|
// Try to reconfigure on failed update
|
||||||
init_battery();
|
init_battery();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_ac_connected != battery_state.ac_connected) {
|
if (old_ac_connected != battery_state.ac_connected) {
|
||||||
if (battery_state.ac_connected)
|
if (battery_state.ac_connected)
|
||||||
tint_exec(ac_connected_cmd);
|
tint_exec(ac_connected_cmd);
|
||||||
else
|
else
|
||||||
tint_exec(ac_disconnected_cmd);
|
tint_exec(ac_disconnected_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (battery_state.percentage < battery_low_status && battery_state.state == BATTERY_DISCHARGING &&
|
if (battery_state.percentage < battery_low_status && battery_state.state == BATTERY_DISCHARGING &&
|
||||||
!battery_low_cmd_sent) {
|
!battery_low_cmd_sent) {
|
||||||
tint_exec(battery_low_cmd);
|
tint_exec(battery_low_cmd);
|
||||||
battery_low_cmd_sent = TRUE;
|
battery_low_cmd_sent = TRUE;
|
||||||
}
|
}
|
||||||
if (battery_state.percentage > battery_low_status && battery_state.state == BATTERY_CHARGING &&
|
if (battery_state.percentage > battery_low_status && battery_state.state == BATTERY_CHARGING &&
|
||||||
battery_low_cmd_sent) {
|
battery_low_cmd_sent) {
|
||||||
battery_low_cmd_sent = FALSE;
|
battery_low_cmd_sent = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
// Show/hide if needed
|
// Show/hide if needed
|
||||||
if (!battery_found) {
|
if (!battery_found) {
|
||||||
hide(&panels[i].battery.area);
|
hide(&panels[i].battery.area);
|
||||||
} else {
|
} else {
|
||||||
if (battery_state.percentage >= percentage_hide)
|
if (battery_state.percentage >= percentage_hide)
|
||||||
hide(&panels[i].battery.area);
|
hide(&panels[i].battery.area);
|
||||||
else
|
else
|
||||||
show(&panels[i].battery.area);
|
show(&panels[i].battery.area);
|
||||||
}
|
}
|
||||||
// Redraw if needed
|
// Redraw if needed
|
||||||
if (panels[i].battery.area.on_screen) {
|
if (panels[i].battery.area.on_screen) {
|
||||||
if (old_found != battery_found || old_percentage != battery_state.percentage ||
|
if (old_found != battery_found || old_percentage != battery_state.percentage ||
|
||||||
old_hours != battery_state.time.hours || old_minutes != battery_state.time.minutes) {
|
old_hours != battery_state.time.hours || old_minutes != battery_state.time.minutes) {
|
||||||
panels[i].battery.area.resize_needed = TRUE;
|
panels[i].battery.area.resize_needed = TRUE;
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int update_battery()
|
int update_battery()
|
||||||
{
|
{
|
||||||
// Reset
|
// Reset
|
||||||
battery_state.state = BATTERY_UNKNOWN;
|
battery_state.state = BATTERY_UNKNOWN;
|
||||||
battery_state.percentage = 0;
|
battery_state.percentage = 0;
|
||||||
battery_state.ac_connected = FALSE;
|
battery_state.ac_connected = FALSE;
|
||||||
battery_state_set_time(&battery_state, 0);
|
battery_state_set_time(&battery_state, 0);
|
||||||
|
|
||||||
int err = battery_os_update(&battery_state);
|
int err = battery_os_update(&battery_state);
|
||||||
|
|
||||||
// Clamp percentage to 100 in case battery is misreporting that its current charge is more than its max
|
// Clamp percentage to 100 in case battery is misreporting that its current charge is more than its max
|
||||||
if (battery_state.percentage > 100) {
|
if (battery_state.percentage > 100) {
|
||||||
battery_state.percentage = 100;
|
battery_state.percentage = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int battery_compute_desired_size(void *obj)
|
int battery_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
Battery *battery = (Battery *)obj;
|
Battery *battery = (Battery *)obj;
|
||||||
Panel *panel = (Panel *)battery->area.panel;
|
Panel *panel = (Panel *)battery->area.panel;
|
||||||
int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink;
|
int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink;
|
||||||
int bat_time_height, bat_time_width, bat_time_height_ink;
|
int bat_time_height, bat_time_width, bat_time_height_ink;
|
||||||
|
|
||||||
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
|
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
|
||||||
if (battery_state.state == BATTERY_FULL) {
|
if (battery_state.state == BATTERY_FULL) {
|
||||||
strcpy(buf_bat_time, "Full");
|
strcpy(buf_bat_time, "Full");
|
||||||
} else {
|
} else {
|
||||||
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
|
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
|
||||||
}
|
}
|
||||||
get_text_size2(bat1_font_desc,
|
get_text_size2(bat1_font_desc,
|
||||||
&bat_percentage_height_ink,
|
&bat_percentage_height_ink,
|
||||||
&bat_percentage_height,
|
&bat_percentage_height,
|
||||||
&bat_percentage_width,
|
&bat_percentage_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
buf_bat_percentage,
|
buf_bat_percentage,
|
||||||
strlen(buf_bat_percentage),
|
strlen(buf_bat_percentage),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
get_text_size2(bat2_font_desc,
|
get_text_size2(bat2_font_desc,
|
||||||
&bat_time_height_ink,
|
&bat_time_height_ink,
|
||||||
&bat_time_height,
|
&bat_time_height,
|
||||||
&bat_time_width,
|
&bat_time_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
buf_bat_time,
|
buf_bat_time,
|
||||||
strlen(buf_bat_time),
|
strlen(buf_bat_time),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
|
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
|
||||||
new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area);
|
new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area);
|
||||||
return new_size;
|
return new_size;
|
||||||
} else {
|
} else {
|
||||||
int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr +
|
int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr +
|
||||||
top_bottom_border_width(&battery->area);
|
top_bottom_border_width(&battery->area);
|
||||||
return new_size;
|
return new_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_battery(void *obj)
|
gboolean resize_battery(void *obj)
|
||||||
{
|
{
|
||||||
Battery *battery = (Battery *)obj;
|
Battery *battery = (Battery *)obj;
|
||||||
Panel *panel = (Panel *)battery->area.panel;
|
Panel *panel = (Panel *)battery->area.panel;
|
||||||
int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink;
|
int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink;
|
||||||
int bat_time_height, bat_time_width, bat_time_height_ink;
|
int bat_time_height, bat_time_width, bat_time_height_ink;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
|
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
|
||||||
if (battery_state.state == BATTERY_FULL) {
|
if (battery_state.state == BATTERY_FULL) {
|
||||||
strcpy(buf_bat_time, "Full");
|
strcpy(buf_bat_time, "Full");
|
||||||
} else {
|
} else {
|
||||||
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
|
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
|
||||||
}
|
}
|
||||||
get_text_size2(bat1_font_desc,
|
get_text_size2(bat1_font_desc,
|
||||||
&bat_percentage_height_ink,
|
&bat_percentage_height_ink,
|
||||||
&bat_percentage_height,
|
&bat_percentage_height,
|
||||||
&bat_percentage_width,
|
&bat_percentage_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
buf_bat_percentage,
|
buf_bat_percentage,
|
||||||
strlen(buf_bat_percentage),
|
strlen(buf_bat_percentage),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
get_text_size2(bat2_font_desc,
|
get_text_size2(bat2_font_desc,
|
||||||
&bat_time_height_ink,
|
&bat_time_height_ink,
|
||||||
&bat_time_height,
|
&bat_time_height,
|
||||||
&bat_time_width,
|
&bat_time_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
buf_bat_time,
|
buf_bat_time,
|
||||||
strlen(buf_bat_time),
|
strlen(buf_bat_time),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
|
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
|
||||||
new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area);
|
new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area);
|
||||||
if (new_size > battery->area.width || new_size < battery->area.width - 2) {
|
if (new_size > battery->area.width || new_size < battery->area.width - 2) {
|
||||||
// we try to limit the number of resize
|
// we try to limit the number of resize
|
||||||
battery->area.width = new_size;
|
battery->area.width = new_size;
|
||||||
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height) / 2;
|
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height) / 2;
|
||||||
battery->bat2_posy = battery->bat1_posy + bat_percentage_height;
|
battery->bat2_posy = battery->bat1_posy + bat_percentage_height;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr +
|
int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr +
|
||||||
top_bottom_border_width(&battery->area);
|
top_bottom_border_width(&battery->area);
|
||||||
if (new_size > battery->area.height || new_size < battery->area.height - 2) {
|
if (new_size > battery->area.height || new_size < battery->area.height - 2) {
|
||||||
battery->area.height = new_size;
|
battery->area.height = new_size;
|
||||||
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height - 2) / 2;
|
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height - 2) / 2;
|
||||||
battery->bat2_posy = battery->bat1_posy + bat_percentage_height + 2;
|
battery->bat2_posy = battery->bat1_posy + bat_percentage_height + 2;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_redraw(&battery->area);
|
schedule_redraw(&battery->area);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_battery(void *obj, cairo_t *c)
|
void draw_battery(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
Battery *battery = obj;
|
Battery *battery = obj;
|
||||||
|
|
||||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||||
pango_layout_set_font_description(layout, bat1_font_desc);
|
pango_layout_set_font_description(layout, bat1_font_desc);
|
||||||
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
|
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
|
||||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||||
pango_layout_set_text(layout, buf_bat_percentage, strlen(buf_bat_percentage));
|
pango_layout_set_text(layout, buf_bat_percentage, strlen(buf_bat_percentage));
|
||||||
|
|
||||||
cairo_set_source_rgba(c,
|
cairo_set_source_rgba(c,
|
||||||
battery->font_color.rgb[0],
|
battery->font_color.rgb[0],
|
||||||
battery->font_color.rgb[1],
|
battery->font_color.rgb[1],
|
||||||
battery->font_color.rgb[2],
|
battery->font_color.rgb[2],
|
||||||
battery->font_color.alpha);
|
battery->font_color.alpha);
|
||||||
|
|
||||||
pango_cairo_update_layout(c, layout);
|
pango_cairo_update_layout(c, layout);
|
||||||
draw_text(layout, c, 0, battery->bat1_posy, &battery->font_color, ((Panel *)battery->area.panel)->font_shadow);
|
draw_text(layout, c, 0, battery->bat1_posy, &battery->font_color, ((Panel *)battery->area.panel)->font_shadow);
|
||||||
|
|
||||||
pango_layout_set_font_description(layout, bat2_font_desc);
|
pango_layout_set_font_description(layout, bat2_font_desc);
|
||||||
pango_layout_set_indent(layout, 0);
|
pango_layout_set_indent(layout, 0);
|
||||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||||
pango_layout_set_text(layout, buf_bat_time, strlen(buf_bat_time));
|
pango_layout_set_text(layout, buf_bat_time, strlen(buf_bat_time));
|
||||||
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
|
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
|
||||||
|
|
||||||
pango_cairo_update_layout(c, layout);
|
pango_cairo_update_layout(c, layout);
|
||||||
draw_text(layout, c, 0, battery->bat2_posy, &battery->font_color, ((Panel *)battery->area.panel)->font_shadow);
|
draw_text(layout, c, 0, battery->bat2_posy, &battery->font_color, ((Panel *)battery->area.panel)->font_shadow);
|
||||||
pango_cairo_show_layout(c, layout);
|
pango_cairo_show_layout(c, layout);
|
||||||
|
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_dump_geometry(void *obj, int indent)
|
void battery_dump_geometry(void *obj, int indent)
|
||||||
{
|
{
|
||||||
Battery *battery = obj;
|
Battery *battery = obj;
|
||||||
fprintf(stderr,
|
fprintf(stderr, "%*sText 1: y = %d, text = %s\n", indent, "", battery->bat1_posy, buf_bat_percentage);
|
||||||
"%*sText 1: y = %d, text = %s\n",
|
fprintf(stderr, "%*sText 2: y = %d, text = %s\n", indent, "", battery->bat2_posy, buf_bat_time);
|
||||||
indent,
|
|
||||||
"",
|
|
||||||
battery->bat1_posy,
|
|
||||||
buf_bat_percentage);
|
|
||||||
fprintf(stderr,
|
|
||||||
"%*sText 2: y = %d, text = %s\n",
|
|
||||||
indent,
|
|
||||||
"",
|
|
||||||
battery->bat2_posy,
|
|
||||||
buf_bat_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *battery_get_tooltip(void *obj)
|
char *battery_get_tooltip(void *obj)
|
||||||
{
|
{
|
||||||
return battery_os_tooltip();
|
return battery_os_tooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_action(int button)
|
void battery_action(int button)
|
||||||
{
|
{
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case 1:
|
case 1:
|
||||||
command = battery_lclick_command;
|
command = battery_lclick_command;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
command = battery_mclick_command;
|
command = battery_mclick_command;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
command = battery_rclick_command;
|
command = battery_rclick_command;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
command = battery_uwheel_command;
|
command = battery_uwheel_command;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
command = battery_dwheel_command;
|
command = battery_dwheel_command;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tint_exec(command);
|
tint_exec(command);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,30 +17,30 @@
|
|||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
|
||||||
typedef struct Battery {
|
typedef struct Battery {
|
||||||
Area area;
|
Area area;
|
||||||
Color font_color;
|
Color font_color;
|
||||||
int bat1_posy;
|
int bat1_posy;
|
||||||
int bat2_posy;
|
int bat2_posy;
|
||||||
} Battery;
|
} Battery;
|
||||||
|
|
||||||
typedef enum ChargeState {
|
typedef enum ChargeState {
|
||||||
BATTERY_UNKNOWN = 0,
|
BATTERY_UNKNOWN = 0,
|
||||||
BATTERY_CHARGING,
|
BATTERY_CHARGING,
|
||||||
BATTERY_DISCHARGING,
|
BATTERY_DISCHARGING,
|
||||||
BATTERY_FULL,
|
BATTERY_FULL,
|
||||||
} ChargeState;
|
} ChargeState;
|
||||||
|
|
||||||
typedef struct BatteryTime {
|
typedef struct BatteryTime {
|
||||||
int16_t hours;
|
int16_t hours;
|
||||||
int8_t minutes;
|
int8_t minutes;
|
||||||
int8_t seconds;
|
int8_t seconds;
|
||||||
} BatteryTime;
|
} BatteryTime;
|
||||||
|
|
||||||
typedef struct BatteryState {
|
typedef struct BatteryState {
|
||||||
int percentage;
|
int percentage;
|
||||||
BatteryTime time;
|
BatteryTime time;
|
||||||
ChargeState state;
|
ChargeState state;
|
||||||
gboolean ac_connected;
|
gboolean ac_connected;
|
||||||
} BatteryState;
|
} BatteryState;
|
||||||
|
|
||||||
extern struct BatteryState battery_state;
|
extern struct BatteryState battery_state;
|
||||||
@@ -68,26 +68,26 @@ extern char *battery_sys_prefix;
|
|||||||
|
|
||||||
static inline gchar *chargestate2str(ChargeState state)
|
static inline gchar *chargestate2str(ChargeState state)
|
||||||
{
|
{
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case BATTERY_CHARGING:
|
case BATTERY_CHARGING:
|
||||||
return "Charging";
|
return "Charging";
|
||||||
case BATTERY_DISCHARGING:
|
case BATTERY_DISCHARGING:
|
||||||
return "Discharging";
|
return "Discharging";
|
||||||
case BATTERY_FULL:
|
case BATTERY_FULL:
|
||||||
return "Full";
|
return "Full";
|
||||||
case BATTERY_UNKNOWN:
|
case BATTERY_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void battery_state_set_time(BatteryState *state, int seconds)
|
static inline void battery_state_set_time(BatteryState *state, int seconds)
|
||||||
{
|
{
|
||||||
state->time.hours = seconds / 3600;
|
state->time.hours = seconds / 3600;
|
||||||
seconds -= 3600 * state->time.hours;
|
seconds -= 3600 * state->time.hours;
|
||||||
state->time.minutes = seconds / 60;
|
state->time.minutes = seconds / 60;
|
||||||
seconds -= 60 * state->time.minutes;
|
seconds -= 60 * state->time.minutes;
|
||||||
state->time.seconds = seconds;
|
state->time.seconds = seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
// default global data
|
// default global data
|
||||||
|
|||||||
@@ -25,20 +25,20 @@
|
|||||||
|
|
||||||
gboolean battery_os_init()
|
gboolean battery_os_init()
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_os_free()
|
void battery_os_free()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int battery_os_update(BatteryState *state)
|
int battery_os_update(BatteryState *state)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *battery_os_tooltip()
|
char *battery_os_tooltip()
|
||||||
{
|
{
|
||||||
return strdup("Operating System not supported");
|
return strdup("Operating System not supported");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,77 +26,77 @@
|
|||||||
|
|
||||||
gboolean battery_os_init()
|
gboolean battery_os_init()
|
||||||
{
|
{
|
||||||
int sysctl_out = 0;
|
int sysctl_out = 0;
|
||||||
size_t len = sizeof(sysctl_out);
|
size_t len = sizeof(sysctl_out);
|
||||||
|
|
||||||
return (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) ||
|
return (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||||
(sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0) ||
|
(sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0) ||
|
||||||
(sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0);
|
(sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_os_free()
|
void battery_os_free()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int battery_os_update(BatteryState *state)
|
int battery_os_update(BatteryState *state)
|
||||||
{
|
{
|
||||||
int sysctl_out = 0;
|
int sysctl_out = 0;
|
||||||
size_t len = sizeof(sysctl_out);
|
size_t len = sizeof(sysctl_out);
|
||||||
gboolean err = 0;
|
gboolean err = 0;
|
||||||
|
|
||||||
if (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) {
|
if (sysctlbyname("hw.acpi.battery.state", &sysctl_out, &len, NULL, 0) == 0) {
|
||||||
switch (sysctl_out) {
|
switch (sysctl_out) {
|
||||||
case 1:
|
case 1:
|
||||||
state->state = BATTERY_DISCHARGING;
|
state->state = BATTERY_DISCHARGING;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
state->state = BATTERY_CHARGING;
|
state->state = BATTERY_CHARGING;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state->state = BATTERY_FULL;
|
state->state = BATTERY_FULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "power update: no such sysctl");
|
fprintf(stderr, "power update: no such sysctl");
|
||||||
err = -1;
|
err = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0)
|
if (sysctlbyname("hw.acpi.battery.time", &sysctl_out, &len, NULL, 0) == 0)
|
||||||
battery_state_set_time(state, sysctl_out * 60);
|
battery_state_set_time(state, sysctl_out * 60);
|
||||||
else
|
else
|
||||||
err = -1;
|
err = -1;
|
||||||
|
|
||||||
if (sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0)
|
if (sysctlbyname("hw.acpi.battery.life", &sysctl_out, &len, NULL, 0) == 0)
|
||||||
state->percentage = sysctl_out;
|
state->percentage = sysctl_out;
|
||||||
else
|
else
|
||||||
err = -1;
|
err = -1;
|
||||||
|
|
||||||
if (sysctlbyname("hw.acpi.acline", &sysctl_out, &len, NULL, 0) == 0)
|
if (sysctlbyname("hw.acpi.acline", &sysctl_out, &len, NULL, 0) == 0)
|
||||||
state->ac_connected = sysctl_out;
|
state->ac_connected = sysctl_out;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *battery_os_tooltip()
|
char *battery_os_tooltip()
|
||||||
{
|
{
|
||||||
GString *tooltip = g_string_new("");
|
GString *tooltip = g_string_new("");
|
||||||
gchar *result;
|
gchar *result;
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "Battery\n");
|
g_string_append_printf(tooltip, "Battery\n");
|
||||||
|
|
||||||
gchar *state = (battery_state.state == BATTERY_UNKNOWN) ? "Level" : chargestate2str(battery_state.state);
|
gchar *state = (battery_state.state == BATTERY_UNKNOWN) ? "Level" : chargestate2str(battery_state.state);
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "\t%s: %d%%", state, battery_state.percentage);
|
g_string_append_printf(tooltip, "\t%s: %d%%", state, battery_state.percentage);
|
||||||
|
|
||||||
g_string_append_c(tooltip, '\n');
|
g_string_append_c(tooltip, '\n');
|
||||||
g_string_append_printf(tooltip, "AC\n");
|
g_string_append_printf(tooltip, "AC\n");
|
||||||
g_string_append_printf(tooltip, battery_state.ac_connected ? "\tConnected" : "\tDisconnected");
|
g_string_append_printf(tooltip, battery_state.ac_connected ? "\tConnected" : "\tDisconnected");
|
||||||
|
|
||||||
result = tooltip->str;
|
result = tooltip->str;
|
||||||
g_string_free(tooltip, FALSE);
|
g_string_free(tooltip, FALSE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,513 +26,514 @@
|
|||||||
#include "uevent.h"
|
#include "uevent.h"
|
||||||
|
|
||||||
enum psy_type {
|
enum psy_type {
|
||||||
PSY_UNKNOWN,
|
PSY_UNKNOWN,
|
||||||
PSY_BATTERY,
|
PSY_BATTERY,
|
||||||
PSY_MAINS,
|
PSY_MAINS,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct psy_battery {
|
struct psy_battery {
|
||||||
/* generic properties */
|
/* generic properties */
|
||||||
gchar *name;
|
gchar *name;
|
||||||
/* monotonic time, in microseconds */
|
/* monotonic time, in microseconds */
|
||||||
gint64 timestamp;
|
gint64 timestamp;
|
||||||
/* sysfs files */
|
/* sysfs files */
|
||||||
gchar *path_present;
|
gchar *path_present;
|
||||||
gchar *path_level_now;
|
gchar *path_level_now;
|
||||||
gchar *path_level_full;
|
gchar *path_level_full;
|
||||||
gchar *path_rate_now;
|
gchar *path_rate_now;
|
||||||
gchar *path_status;
|
gchar *path_status;
|
||||||
/* values */
|
/* values */
|
||||||
gboolean present;
|
gboolean present;
|
||||||
gint level_now;
|
gint level_now;
|
||||||
gint level_full;
|
gint level_full;
|
||||||
gint rate_now;
|
gint rate_now;
|
||||||
gchar unit;
|
gchar unit;
|
||||||
ChargeState status;
|
ChargeState status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct psy_mains {
|
struct psy_mains {
|
||||||
/* generic properties */
|
/* generic properties */
|
||||||
gchar *name;
|
gchar *name;
|
||||||
/* sysfs files */
|
/* sysfs files */
|
||||||
gchar *path_online;
|
gchar *path_online;
|
||||||
/* values */
|
/* values */
|
||||||
gboolean online;
|
gboolean online;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void uevent_battery_update()
|
static void uevent_battery_update()
|
||||||
{
|
{
|
||||||
update_battery_tick(NULL);
|
update_battery_tick(NULL);
|
||||||
}
|
}
|
||||||
static struct uevent_notify psy_change = {UEVENT_CHANGE, "power_supply", NULL, uevent_battery_update};
|
static struct uevent_notify psy_change = {UEVENT_CHANGE, "power_supply", NULL, uevent_battery_update};
|
||||||
|
|
||||||
static void uevent_battery_plug()
|
static void uevent_battery_plug()
|
||||||
{
|
{
|
||||||
printf("reinitialize batteries after HW change\n");
|
printf("reinitialize batteries after HW change\n");
|
||||||
reinit_battery();
|
reinit_battery();
|
||||||
}
|
}
|
||||||
static struct uevent_notify psy_plug = {UEVENT_ADD | UEVENT_REMOVE, "power_supply", NULL, uevent_battery_plug};
|
static struct uevent_notify psy_plug = {UEVENT_ADD | UEVENT_REMOVE, "power_supply", NULL, uevent_battery_plug};
|
||||||
|
|
||||||
#define RETURN_ON_ERROR(err) \
|
#define RETURN_ON_ERROR(err) \
|
||||||
if (err) { \
|
if (err) { \
|
||||||
g_error_free(err); \
|
g_error_free(err); \
|
||||||
fprintf(stderr, RED "%s:%d: errror" RESET "\n", __FILE__, __LINE__); \
|
fprintf(stderr, RED "%s:%d: errror" RESET "\n", __FILE__, __LINE__); \
|
||||||
return FALSE; \
|
return FALSE; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *batteries = NULL;
|
static GList *batteries = NULL;
|
||||||
static GList *mains = NULL;
|
static GList *mains = NULL;
|
||||||
|
|
||||||
static guint8 level_to_percent(gint level_now, gint level_full)
|
static guint8 level_to_percent(gint level_now, gint level_full)
|
||||||
{
|
{
|
||||||
return 0.5 + ((level_now <= level_full ? level_now : level_full) * 100.0) / level_full;
|
return 0.5 + ((level_now <= level_full ? level_now : level_full) * 100.0) / level_full;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum psy_type power_supply_get_type(const gchar *entryname)
|
static enum psy_type power_supply_get_type(const gchar *entryname)
|
||||||
{
|
{
|
||||||
gchar *path_type = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "type", NULL);
|
gchar *path_type = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "type", NULL);
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gchar *type;
|
gchar *type;
|
||||||
gsize typelen;
|
gsize typelen;
|
||||||
|
|
||||||
g_file_get_contents(path_type, &type, &typelen, &error);
|
g_file_get_contents(path_type, &type, &typelen, &error);
|
||||||
g_free(path_type);
|
g_free(path_type);
|
||||||
if (error) {
|
if (error) {
|
||||||
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
return PSY_UNKNOWN;
|
return PSY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_strcmp0(type, "Battery\n")) {
|
if (!g_strcmp0(type, "Battery\n")) {
|
||||||
g_free(type);
|
g_free(type);
|
||||||
return PSY_BATTERY;
|
return PSY_BATTERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_strcmp0(type, "Mains\n")) {
|
if (!g_strcmp0(type, "Mains\n")) {
|
||||||
g_free(type);
|
g_free(type);
|
||||||
return PSY_MAINS;
|
return PSY_MAINS;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(type);
|
g_free(type);
|
||||||
|
|
||||||
return PSY_UNKNOWN;
|
return PSY_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean init_linux_battery(struct psy_battery *bat)
|
static gboolean init_linux_battery(struct psy_battery *bat)
|
||||||
{
|
{
|
||||||
const gchar *entryname = bat->name;
|
const gchar *entryname = bat->name;
|
||||||
|
|
||||||
bat->path_present = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "present", NULL);
|
bat->path_present = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "present", NULL);
|
||||||
if (!g_file_test(bat->path_present, G_FILE_TEST_EXISTS)) {
|
if (!g_file_test(bat->path_present, G_FILE_TEST_EXISTS)) {
|
||||||
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
||||||
goto err0;
|
goto err0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bat->path_level_now = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "energy_now", NULL);
|
bat->path_level_now =
|
||||||
bat->path_level_full =
|
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "energy_now", NULL);
|
||||||
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "energy_full", NULL);
|
bat->path_level_full =
|
||||||
bat->path_rate_now = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "power_now", NULL);
|
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "energy_full", NULL);
|
||||||
bat->unit = 'W';
|
bat->path_rate_now = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "power_now", NULL);
|
||||||
|
bat->unit = 'W';
|
||||||
|
|
||||||
if (!g_file_test(bat->path_level_now, G_FILE_TEST_EXISTS) ||
|
if (!g_file_test(bat->path_level_now, G_FILE_TEST_EXISTS) ||
|
||||||
!g_file_test(bat->path_level_full, G_FILE_TEST_EXISTS) ||
|
!g_file_test(bat->path_level_full, G_FILE_TEST_EXISTS) ||
|
||||||
!g_file_test(bat->path_rate_now, G_FILE_TEST_EXISTS)) {
|
!g_file_test(bat->path_rate_now, G_FILE_TEST_EXISTS)) {
|
||||||
g_free(bat->path_level_now);
|
g_free(bat->path_level_now);
|
||||||
g_free(bat->path_level_full);
|
g_free(bat->path_level_full);
|
||||||
g_free(bat->path_rate_now);
|
g_free(bat->path_rate_now);
|
||||||
bat->path_level_now =
|
bat->path_level_now =
|
||||||
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "charge_now", NULL);
|
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "charge_now", NULL);
|
||||||
bat->path_level_full =
|
bat->path_level_full =
|
||||||
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "charge_full", NULL);
|
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "charge_full", NULL);
|
||||||
bat->path_rate_now =
|
bat->path_rate_now =
|
||||||
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "current_now", NULL);
|
g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "current_now", NULL);
|
||||||
bat->unit = 'A';
|
bat->unit = 'A';
|
||||||
}
|
}
|
||||||
if (!g_file_test(bat->path_level_now, G_FILE_TEST_EXISTS) ||
|
if (!g_file_test(bat->path_level_now, G_FILE_TEST_EXISTS) ||
|
||||||
!g_file_test(bat->path_level_full, G_FILE_TEST_EXISTS) ||
|
!g_file_test(bat->path_level_full, G_FILE_TEST_EXISTS) ||
|
||||||
!g_file_test(bat->path_rate_now, G_FILE_TEST_EXISTS)) {
|
!g_file_test(bat->path_rate_now, G_FILE_TEST_EXISTS)) {
|
||||||
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bat->path_status = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "status", NULL);
|
bat->path_status = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "status", NULL);
|
||||||
if (!g_file_test(bat->path_status, G_FILE_TEST_EXISTS)) {
|
if (!g_file_test(bat->path_status, G_FILE_TEST_EXISTS)) {
|
||||||
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
g_free(bat->path_status);
|
g_free(bat->path_status);
|
||||||
err1:
|
err1:
|
||||||
g_free(bat->path_level_now);
|
g_free(bat->path_level_now);
|
||||||
g_free(bat->path_level_full);
|
g_free(bat->path_level_full);
|
||||||
g_free(bat->path_rate_now);
|
g_free(bat->path_rate_now);
|
||||||
err0:
|
err0:
|
||||||
g_free(bat->path_present);
|
g_free(bat->path_present);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean init_linux_mains(struct psy_mains *ac)
|
static gboolean init_linux_mains(struct psy_mains *ac)
|
||||||
{
|
{
|
||||||
const gchar *entryname = ac->name;
|
const gchar *entryname = ac->name;
|
||||||
|
|
||||||
ac->path_online = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "online", NULL);
|
ac->path_online = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", entryname, "online", NULL);
|
||||||
if (!g_file_test(ac->path_online, G_FILE_TEST_EXISTS)) {
|
if (!g_file_test(ac->path_online, G_FILE_TEST_EXISTS)) {
|
||||||
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
fprintf(stderr, RED "%s:%d: read failed" RESET "\n", __FILE__, __LINE__);
|
||||||
g_free(ac->path_online);
|
g_free(ac->path_online);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psy_battery_free(gpointer data)
|
static void psy_battery_free(gpointer data)
|
||||||
{
|
{
|
||||||
struct psy_battery *bat = data;
|
struct psy_battery *bat = data;
|
||||||
g_free(bat->name);
|
g_free(bat->name);
|
||||||
g_free(bat->path_status);
|
g_free(bat->path_status);
|
||||||
g_free(bat->path_rate_now);
|
g_free(bat->path_rate_now);
|
||||||
g_free(bat->path_level_full);
|
g_free(bat->path_level_full);
|
||||||
g_free(bat->path_level_now);
|
g_free(bat->path_level_now);
|
||||||
g_free(bat->path_present);
|
g_free(bat->path_present);
|
||||||
g_free(bat);
|
g_free(bat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psy_mains_free(gpointer data)
|
static void psy_mains_free(gpointer data)
|
||||||
{
|
{
|
||||||
struct psy_mains *ac = data;
|
struct psy_mains *ac = data;
|
||||||
g_free(ac->name);
|
g_free(ac->name);
|
||||||
g_free(ac->path_online);
|
g_free(ac->path_online);
|
||||||
g_free(ac);
|
g_free(ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_os_free()
|
void battery_os_free()
|
||||||
{
|
{
|
||||||
uevent_unregister_notifier(&psy_change);
|
uevent_unregister_notifier(&psy_change);
|
||||||
uevent_unregister_notifier(&psy_plug);
|
uevent_unregister_notifier(&psy_plug);
|
||||||
|
|
||||||
g_list_free_full(batteries, psy_battery_free);
|
g_list_free_full(batteries, psy_battery_free);
|
||||||
batteries = NULL;
|
batteries = NULL;
|
||||||
g_list_free_full(mains, psy_mains_free);
|
g_list_free_full(mains, psy_mains_free);
|
||||||
mains = NULL;
|
mains = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_battery(const char *entryname)
|
static void add_battery(const char *entryname)
|
||||||
{
|
{
|
||||||
struct psy_battery *bat = g_malloc0(sizeof(*bat));
|
struct psy_battery *bat = g_malloc0(sizeof(*bat));
|
||||||
bat->name = g_strdup(entryname);
|
bat->name = g_strdup(entryname);
|
||||||
|
|
||||||
if (init_linux_battery(bat)) {
|
if (init_linux_battery(bat)) {
|
||||||
batteries = g_list_append(batteries, bat);
|
batteries = g_list_append(batteries, bat);
|
||||||
fprintf(stdout, GREEN "Found battery \"%s\"" RESET "\n", bat->name);
|
fprintf(stdout, GREEN "Found battery \"%s\"" RESET "\n", bat->name);
|
||||||
} else {
|
} else {
|
||||||
g_free(bat);
|
g_free(bat);
|
||||||
fprintf(stderr, RED "Failed to initialize battery \"%s\"" RESET "\n", entryname);
|
fprintf(stderr, RED "Failed to initialize battery \"%s\"" RESET "\n", entryname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_mains(const char *entryname)
|
static void add_mains(const char *entryname)
|
||||||
{
|
{
|
||||||
struct psy_mains *ac = g_malloc0(sizeof(*ac));
|
struct psy_mains *ac = g_malloc0(sizeof(*ac));
|
||||||
ac->name = g_strdup(entryname);
|
ac->name = g_strdup(entryname);
|
||||||
|
|
||||||
if (init_linux_mains(ac)) {
|
if (init_linux_mains(ac)) {
|
||||||
mains = g_list_append(mains, ac);
|
mains = g_list_append(mains, ac);
|
||||||
fprintf(stdout, GREEN "Found mains \"%s\"" RESET "\n", ac->name);
|
fprintf(stdout, GREEN "Found mains \"%s\"" RESET "\n", ac->name);
|
||||||
} else {
|
} else {
|
||||||
g_free(ac);
|
g_free(ac);
|
||||||
fprintf(stderr, RED "Failed to initialize mains \"%s\"" RESET "\n", entryname);
|
fprintf(stderr, RED "Failed to initialize mains \"%s\"" RESET "\n", entryname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean battery_os_init()
|
gboolean battery_os_init()
|
||||||
{
|
{
|
||||||
GDir *directory = 0;
|
GDir *directory = 0;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
const char *entryname;
|
const char *entryname;
|
||||||
|
|
||||||
battery_os_free();
|
battery_os_free();
|
||||||
|
|
||||||
gchar *dir_path = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", NULL);
|
gchar *dir_path = g_build_filename(battery_sys_prefix, "/sys/class/power_supply", NULL);
|
||||||
directory = g_dir_open(dir_path, 0, &error);
|
directory = g_dir_open(dir_path, 0, &error);
|
||||||
g_free(dir_path);
|
g_free(dir_path);
|
||||||
RETURN_ON_ERROR(error);
|
RETURN_ON_ERROR(error);
|
||||||
|
|
||||||
while ((entryname = g_dir_read_name(directory))) {
|
while ((entryname = g_dir_read_name(directory))) {
|
||||||
fprintf(stderr, GREEN "Found power device %s" RESET "\n", entryname);
|
fprintf(stderr, GREEN "Found power device %s" RESET "\n", entryname);
|
||||||
enum psy_type type = power_supply_get_type(entryname);
|
enum psy_type type = power_supply_get_type(entryname);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PSY_BATTERY:
|
case PSY_BATTERY:
|
||||||
add_battery(entryname);
|
add_battery(entryname);
|
||||||
break;
|
break;
|
||||||
case PSY_MAINS:
|
case PSY_MAINS:
|
||||||
add_mains(entryname);
|
add_mains(entryname);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_dir_close(directory);
|
g_dir_close(directory);
|
||||||
|
|
||||||
uevent_register_notifier(&psy_change);
|
uevent_register_notifier(&psy_change);
|
||||||
uevent_register_notifier(&psy_plug);
|
uevent_register_notifier(&psy_plug);
|
||||||
|
|
||||||
return batteries != NULL;
|
return batteries != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint estimate_rate_usage(struct psy_battery *bat, gint old_level_now, gint64 old_timestamp)
|
static gint estimate_rate_usage(struct psy_battery *bat, gint old_level_now, gint64 old_timestamp)
|
||||||
{
|
{
|
||||||
gint64 diff_level = ABS(bat->level_now - old_level_now);
|
gint64 diff_level = ABS(bat->level_now - old_level_now);
|
||||||
gint64 diff_time = bat->timestamp - old_timestamp;
|
gint64 diff_time = bat->timestamp - old_timestamp;
|
||||||
|
|
||||||
/* µW = (µWh * 3600) / (µs / 1000000) */
|
/* µW = (µWh * 3600) / (µs / 1000000) */
|
||||||
gint rate = diff_level * 3600 * 1000000 / MAX(1, diff_time);
|
gint rate = diff_level * 3600 * 1000000 / MAX(1, diff_time);
|
||||||
|
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean update_linux_battery(struct psy_battery *bat)
|
static gboolean update_linux_battery(struct psy_battery *bat)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gchar *data;
|
gchar *data;
|
||||||
gsize datalen;
|
gsize datalen;
|
||||||
|
|
||||||
gint64 old_timestamp = bat->timestamp;
|
gint64 old_timestamp = bat->timestamp;
|
||||||
int old_level_now = bat->level_now;
|
int old_level_now = bat->level_now;
|
||||||
gint old_rate_now = bat->rate_now;
|
gint old_rate_now = bat->rate_now;
|
||||||
|
|
||||||
/* reset values */
|
/* reset values */
|
||||||
bat->present = 0;
|
bat->present = 0;
|
||||||
bat->status = BATTERY_UNKNOWN;
|
bat->status = BATTERY_UNKNOWN;
|
||||||
bat->level_now = 0;
|
bat->level_now = 0;
|
||||||
bat->level_full = 0;
|
bat->level_full = 0;
|
||||||
bat->rate_now = 0;
|
bat->rate_now = 0;
|
||||||
bat->timestamp = g_get_monotonic_time();
|
bat->timestamp = g_get_monotonic_time();
|
||||||
|
|
||||||
/* present */
|
/* present */
|
||||||
g_file_get_contents(bat->path_present, &data, &datalen, &error);
|
g_file_get_contents(bat->path_present, &data, &datalen, &error);
|
||||||
RETURN_ON_ERROR(error);
|
RETURN_ON_ERROR(error);
|
||||||
bat->present = (atoi(data) == 1);
|
bat->present = (atoi(data) == 1);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
|
||||||
/* we are done, if battery is not present */
|
/* we are done, if battery is not present */
|
||||||
if (!bat->present)
|
if (!bat->present)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* status */
|
/* status */
|
||||||
bat->status = BATTERY_UNKNOWN;
|
bat->status = BATTERY_UNKNOWN;
|
||||||
g_file_get_contents(bat->path_status, &data, &datalen, &error);
|
g_file_get_contents(bat->path_status, &data, &datalen, &error);
|
||||||
RETURN_ON_ERROR(error);
|
RETURN_ON_ERROR(error);
|
||||||
if (!g_strcmp0(data, "Charging\n")) {
|
if (!g_strcmp0(data, "Charging\n")) {
|
||||||
bat->status = BATTERY_CHARGING;
|
bat->status = BATTERY_CHARGING;
|
||||||
} else if (!g_strcmp0(data, "Discharging\n")) {
|
} else if (!g_strcmp0(data, "Discharging\n")) {
|
||||||
bat->status = BATTERY_DISCHARGING;
|
bat->status = BATTERY_DISCHARGING;
|
||||||
} else if (!g_strcmp0(data, "Full\n")) {
|
} else if (!g_strcmp0(data, "Full\n")) {
|
||||||
bat->status = BATTERY_FULL;
|
bat->status = BATTERY_FULL;
|
||||||
}
|
}
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
|
||||||
/* level now */
|
/* level now */
|
||||||
g_file_get_contents(bat->path_level_now, &data, &datalen, &error);
|
g_file_get_contents(bat->path_level_now, &data, &datalen, &error);
|
||||||
RETURN_ON_ERROR(error);
|
RETURN_ON_ERROR(error);
|
||||||
bat->level_now = atoi(data);
|
bat->level_now = atoi(data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
|
||||||
/* level full */
|
/* level full */
|
||||||
g_file_get_contents(bat->path_level_full, &data, &datalen, &error);
|
g_file_get_contents(bat->path_level_full, &data, &datalen, &error);
|
||||||
RETURN_ON_ERROR(error);
|
RETURN_ON_ERROR(error);
|
||||||
bat->level_full = atoi(data);
|
bat->level_full = atoi(data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
|
||||||
/* rate now */
|
/* rate now */
|
||||||
g_file_get_contents(bat->path_rate_now, &data, &datalen, &error);
|
g_file_get_contents(bat->path_rate_now, &data, &datalen, &error);
|
||||||
if (g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NODEV)) {
|
if (g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NODEV)) {
|
||||||
/* some hardware does not support reading current rate consumption */
|
/* some hardware does not support reading current rate consumption */
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
bat->rate_now = estimate_rate_usage(bat, old_level_now, old_timestamp);
|
bat->rate_now = estimate_rate_usage(bat, old_level_now, old_timestamp);
|
||||||
if (bat->rate_now == 0 && bat->status != BATTERY_FULL) {
|
if (bat->rate_now == 0 && bat->status != BATTERY_FULL) {
|
||||||
/* If the hardware updates the level slower than our sampling period,
|
/* If the hardware updates the level slower than our sampling period,
|
||||||
* we need to sample more rarely */
|
* we need to sample more rarely */
|
||||||
bat->rate_now = old_rate_now;
|
bat->rate_now = old_rate_now;
|
||||||
bat->timestamp = old_timestamp;
|
bat->timestamp = old_timestamp;
|
||||||
}
|
}
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
bat->rate_now = atoi(data);
|
bat->rate_now = atoi(data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean update_linux_mains(struct psy_mains *ac)
|
static gboolean update_linux_mains(struct psy_mains *ac)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gchar *data;
|
gchar *data;
|
||||||
gsize datalen;
|
gsize datalen;
|
||||||
ac->online = FALSE;
|
ac->online = FALSE;
|
||||||
|
|
||||||
/* online */
|
/* online */
|
||||||
g_file_get_contents(ac->path_online, &data, &datalen, &error);
|
g_file_get_contents(ac->path_online, &data, &datalen, &error);
|
||||||
RETURN_ON_ERROR(error);
|
RETURN_ON_ERROR(error);
|
||||||
ac->online = (atoi(data) == 1);
|
ac->online = (atoi(data) == 1);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int battery_os_update(BatteryState *state)
|
int battery_os_update(BatteryState *state)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
gint64 total_level_now = 0;
|
gint64 total_level_now = 0;
|
||||||
gint64 total_level_full = 0;
|
gint64 total_level_full = 0;
|
||||||
gint64 total_rate_now = 0;
|
gint64 total_rate_now = 0;
|
||||||
gint seconds = 0;
|
gint seconds = 0;
|
||||||
|
|
||||||
gboolean charging = FALSE;
|
gboolean charging = FALSE;
|
||||||
gboolean discharging = FALSE;
|
gboolean discharging = FALSE;
|
||||||
gboolean full = FALSE;
|
gboolean full = FALSE;
|
||||||
gboolean ac_connected = FALSE;
|
gboolean ac_connected = FALSE;
|
||||||
|
|
||||||
for (l = batteries; l != NULL; l = l->next) {
|
for (l = batteries; l != NULL; l = l->next) {
|
||||||
struct psy_battery *bat = l->data;
|
struct psy_battery *bat = l->data;
|
||||||
update_linux_battery(bat);
|
update_linux_battery(bat);
|
||||||
|
|
||||||
total_level_now += bat->level_now;
|
total_level_now += bat->level_now;
|
||||||
total_level_full += bat->level_full;
|
total_level_full += bat->level_full;
|
||||||
total_rate_now += bat->rate_now;
|
total_rate_now += bat->rate_now;
|
||||||
|
|
||||||
charging |= (bat->status == BATTERY_CHARGING);
|
charging |= (bat->status == BATTERY_CHARGING);
|
||||||
discharging |= (bat->status == BATTERY_DISCHARGING);
|
discharging |= (bat->status == BATTERY_DISCHARGING);
|
||||||
full |= (bat->status == BATTERY_FULL);
|
full |= (bat->status == BATTERY_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = mains; l != NULL; l = l->next) {
|
for (l = mains; l != NULL; l = l->next) {
|
||||||
struct psy_mains *ac = l->data;
|
struct psy_mains *ac = l->data;
|
||||||
update_linux_mains(ac);
|
update_linux_mains(ac);
|
||||||
ac_connected |= (ac->online);
|
ac_connected |= (ac->online);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build global state */
|
/* build global state */
|
||||||
if (charging && !discharging)
|
if (charging && !discharging)
|
||||||
state->state = BATTERY_CHARGING;
|
state->state = BATTERY_CHARGING;
|
||||||
else if (!charging && discharging)
|
else if (!charging && discharging)
|
||||||
state->state = BATTERY_DISCHARGING;
|
state->state = BATTERY_DISCHARGING;
|
||||||
else if (!charging && !discharging && full)
|
else if (!charging && !discharging && full)
|
||||||
state->state = BATTERY_FULL;
|
state->state = BATTERY_FULL;
|
||||||
|
|
||||||
/* calculate seconds */
|
/* calculate seconds */
|
||||||
if (total_rate_now > 0) {
|
if (total_rate_now > 0) {
|
||||||
if (state->state == BATTERY_CHARGING)
|
if (state->state == BATTERY_CHARGING)
|
||||||
seconds = 3600 * (total_level_full - total_level_now) / total_rate_now;
|
seconds = 3600 * (total_level_full - total_level_now) / total_rate_now;
|
||||||
else if (state->state == BATTERY_DISCHARGING)
|
else if (state->state == BATTERY_DISCHARGING)
|
||||||
seconds = 3600 * total_level_now / total_rate_now;
|
seconds = 3600 * total_level_now / total_rate_now;
|
||||||
seconds = MAX(0, seconds);
|
seconds = MAX(0, seconds);
|
||||||
}
|
}
|
||||||
battery_state_set_time(state, seconds);
|
battery_state_set_time(state, seconds);
|
||||||
|
|
||||||
/* calculate percentage */
|
/* calculate percentage */
|
||||||
state->percentage = level_to_percent(total_level_now, total_level_full);
|
state->percentage = level_to_percent(total_level_now, total_level_full);
|
||||||
|
|
||||||
/* AC state */
|
/* AC state */
|
||||||
state->ac_connected = ac_connected;
|
state->ac_connected = ac_connected;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *level_human_readable(struct psy_battery *bat)
|
static gchar *level_human_readable(struct psy_battery *bat)
|
||||||
{
|
{
|
||||||
gint now = bat->level_now;
|
gint now = bat->level_now;
|
||||||
gint full = bat->level_full;
|
gint full = bat->level_full;
|
||||||
|
|
||||||
if (full >= 1000000) {
|
if (full >= 1000000) {
|
||||||
return g_strdup_printf("%d.%d / %d.%d %ch",
|
return g_strdup_printf("%d.%d / %d.%d %ch",
|
||||||
now / 1000000,
|
now / 1000000,
|
||||||
(now % 1000000) / 100000,
|
(now % 1000000) / 100000,
|
||||||
full / 1000000,
|
full / 1000000,
|
||||||
(full % 1000000) / 100000,
|
(full % 1000000) / 100000,
|
||||||
bat->unit);
|
bat->unit);
|
||||||
} else if (full >= 1000) {
|
} else if (full >= 1000) {
|
||||||
return g_strdup_printf("%d.%d / %d.%d m%ch",
|
return g_strdup_printf("%d.%d / %d.%d m%ch",
|
||||||
now / 1000,
|
now / 1000,
|
||||||
(now % 1000) / 100,
|
(now % 1000) / 100,
|
||||||
full / 1000,
|
full / 1000,
|
||||||
(full % 1000) / 100,
|
(full % 1000) / 100,
|
||||||
bat->unit);
|
bat->unit);
|
||||||
} else {
|
} else {
|
||||||
return g_strdup_printf("%d / %d µ%ch", now, full, bat->unit);
|
return g_strdup_printf("%d / %d µ%ch", now, full, bat->unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *rate_human_readable(struct psy_battery *bat)
|
static gchar *rate_human_readable(struct psy_battery *bat)
|
||||||
{
|
{
|
||||||
gint rate = bat->rate_now;
|
gint rate = bat->rate_now;
|
||||||
gchar unit = bat->unit;
|
gchar unit = bat->unit;
|
||||||
|
|
||||||
if (rate >= 1000000) {
|
if (rate >= 1000000) {
|
||||||
return g_strdup_printf("%d.%d %c", rate / 1000000, (rate % 1000000) / 100000, unit);
|
return g_strdup_printf("%d.%d %c", rate / 1000000, (rate % 1000000) / 100000, unit);
|
||||||
} else if (rate >= 1000) {
|
} else if (rate >= 1000) {
|
||||||
return g_strdup_printf("%d.%d m%c", rate / 1000, (rate % 1000) / 100, unit);
|
return g_strdup_printf("%d.%d m%c", rate / 1000, (rate % 1000) / 100, unit);
|
||||||
} else if (rate > 0) {
|
} else if (rate > 0) {
|
||||||
return g_strdup_printf("%d µ%c", rate, unit);
|
return g_strdup_printf("%d µ%c", rate, unit);
|
||||||
} else {
|
} else {
|
||||||
return g_strdup_printf("0 %c", unit);
|
return g_strdup_printf("0 %c", unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *battery_os_tooltip()
|
char *battery_os_tooltip()
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
GString *tooltip = g_string_new("");
|
GString *tooltip = g_string_new("");
|
||||||
gchar *result;
|
gchar *result;
|
||||||
|
|
||||||
for (l = batteries; l != NULL; l = l->next) {
|
for (l = batteries; l != NULL; l = l->next) {
|
||||||
struct psy_battery *bat = l->data;
|
struct psy_battery *bat = l->data;
|
||||||
|
|
||||||
if (tooltip->len)
|
if (tooltip->len)
|
||||||
g_string_append_c(tooltip, '\n');
|
g_string_append_c(tooltip, '\n');
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "%s\n", bat->name);
|
g_string_append_printf(tooltip, "%s\n", bat->name);
|
||||||
|
|
||||||
if (!bat->present) {
|
if (!bat->present) {
|
||||||
g_string_append_printf(tooltip, "\tnot connected");
|
g_string_append_printf(tooltip, "\tnot connected");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *rate = rate_human_readable(bat);
|
gchar *rate = rate_human_readable(bat);
|
||||||
gchar *level = level_human_readable(bat);
|
gchar *level = level_human_readable(bat);
|
||||||
gchar *state = (bat->status == BATTERY_UNKNOWN) ? "energy" : chargestate2str(bat->status);
|
gchar *state = (bat->status == BATTERY_UNKNOWN) ? "energy" : chargestate2str(bat->status);
|
||||||
|
|
||||||
guint8 percentage = level_to_percent(bat->level_now, bat->level_full);
|
guint8 percentage = level_to_percent(bat->level_now, bat->level_full);
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "\t%s: %s (%u %%)\n\trate: %s", state, level, percentage, rate);
|
g_string_append_printf(tooltip, "\t%s: %s (%u %%)\n\trate: %s", state, level, percentage, rate);
|
||||||
|
|
||||||
g_free(rate);
|
g_free(rate);
|
||||||
g_free(level);
|
g_free(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = mains; l != NULL; l = l->next) {
|
for (l = mains; l != NULL; l = l->next) {
|
||||||
struct psy_mains *ac = l->data;
|
struct psy_mains *ac = l->data;
|
||||||
|
|
||||||
if (tooltip->len)
|
if (tooltip->len)
|
||||||
g_string_append_c(tooltip, '\n');
|
g_string_append_c(tooltip, '\n');
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "%s\n", ac->name);
|
g_string_append_printf(tooltip, "%s\n", ac->name);
|
||||||
g_string_append_printf(tooltip, ac->online ? "\tConnected" : "\tDisconnected");
|
g_string_append_printf(tooltip, ac->online ? "\tConnected" : "\tDisconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
result = tooltip->str;
|
result = tooltip->str;
|
||||||
g_string_free(tooltip, FALSE);
|
g_string_free(tooltip, FALSE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,78 +31,78 @@ int apm_fd = -1;
|
|||||||
|
|
||||||
gboolean battery_os_init()
|
gboolean battery_os_init()
|
||||||
{
|
{
|
||||||
if (apm_fd > 0)
|
if (apm_fd > 0)
|
||||||
close(apm_fd);
|
close(apm_fd);
|
||||||
|
|
||||||
apm_fd = open("/dev/apm", O_RDONLY);
|
apm_fd = open("/dev/apm", O_RDONLY);
|
||||||
|
|
||||||
if (apm_fd < 0) {
|
if (apm_fd < 0) {
|
||||||
warn("ERROR: battery applet cannot open /dev/apm.");
|
warn("ERROR: battery applet cannot open /dev/apm.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void battery_os_free()
|
void battery_os_free()
|
||||||
{
|
{
|
||||||
if ((apm_fd != -1) && (close(apm_fd) == -1))
|
if ((apm_fd != -1) && (close(apm_fd) == -1))
|
||||||
warn("cannot close /dev/apm");
|
warn("cannot close /dev/apm");
|
||||||
apm_fd = -1;
|
apm_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int battery_os_update(BatteryState *state)
|
int battery_os_update(BatteryState *state)
|
||||||
{
|
{
|
||||||
struct apm_power_info info;
|
struct apm_power_info info;
|
||||||
|
|
||||||
if (apm_fd > 0 && ioctl(apm_fd, APM_IOC_GETPOWER, &(info)) == 0) {
|
if (apm_fd > 0 && ioctl(apm_fd, APM_IOC_GETPOWER, &(info)) == 0) {
|
||||||
// best attempt at mapping to Linux battery states
|
// best attempt at mapping to Linux battery states
|
||||||
switch (info.battery_state) {
|
switch (info.battery_state) {
|
||||||
case APM_BATT_CHARGING:
|
case APM_BATT_CHARGING:
|
||||||
state->state = BATTERY_CHARGING;
|
state->state = BATTERY_CHARGING;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
state->state = BATTERY_DISCHARGING;
|
state->state = BATTERY_DISCHARGING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.battery_life > 100)
|
if (info.battery_life > 100)
|
||||||
info.battery_life = 100;
|
info.battery_life = 100;
|
||||||
if (info.battery_life == 100)
|
if (info.battery_life == 100)
|
||||||
state->state = BATTERY_FULL;
|
state->state = BATTERY_FULL;
|
||||||
|
|
||||||
state->percentage = info.battery_life;
|
state->percentage = info.battery_life;
|
||||||
if (info.minutes_left != -1)
|
if (info.minutes_left != -1)
|
||||||
battery_state_set_time(state, info.minutes_left * 60);
|
battery_state_set_time(state, info.minutes_left * 60);
|
||||||
|
|
||||||
state->ac_connected = info.ac_state == APM_AC_ON;
|
state->ac_connected = info.ac_state == APM_AC_ON;
|
||||||
} else {
|
} else {
|
||||||
warn("power update: APM_IOC_GETPOWER");
|
warn("power update: APM_IOC_GETPOWER");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *battery_os_tooltip()
|
char *battery_os_tooltip()
|
||||||
{
|
{
|
||||||
GString *tooltip = g_string_new("");
|
GString *tooltip = g_string_new("");
|
||||||
gchar *result;
|
gchar *result;
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "Battery\n");
|
g_string_append_printf(tooltip, "Battery\n");
|
||||||
|
|
||||||
gchar *state = (battery_state.state == BATTERY_UNKNOWN) ? "Level" : chargestate2str(battery_state.state);
|
gchar *state = (battery_state.state == BATTERY_UNKNOWN) ? "Level" : chargestate2str(battery_state.state);
|
||||||
|
|
||||||
g_string_append_printf(tooltip, "\t%s: %d%%", state, battery_state.percentage);
|
g_string_append_printf(tooltip, "\t%s: %d%%", state, battery_state.percentage);
|
||||||
|
|
||||||
g_string_append_c(tooltip, '\n');
|
g_string_append_c(tooltip, '\n');
|
||||||
g_string_append_printf(tooltip, "AC\n");
|
g_string_append_printf(tooltip, "AC\n");
|
||||||
g_string_append_printf(tooltip, battery_state.ac_connected ? "\tConnected" : "\tDisconnected");
|
g_string_append_printf(tooltip, battery_state.ac_connected ? "\tConnected" : "\tDisconnected");
|
||||||
|
|
||||||
result = tooltip->str;
|
result = tooltip->str;
|
||||||
g_string_free(tooltip, FALSE);
|
g_string_free(tooltip, FALSE);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
1021
src/button/button.c
1021
src/button/button.c
File diff suppressed because it is too large
Load Diff
@@ -17,55 +17,56 @@
|
|||||||
// backend's config and state variables.
|
// backend's config and state variables.
|
||||||
|
|
||||||
typedef struct ButtonBackend {
|
typedef struct ButtonBackend {
|
||||||
// Config:
|
// Config:
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
char *text;
|
char *text;
|
||||||
char *tooltip;
|
char *tooltip;
|
||||||
gboolean centered;
|
gboolean centered;
|
||||||
int max_icon_size;
|
int max_icon_size;
|
||||||
gboolean has_font;
|
gboolean has_font;
|
||||||
PangoFontDescription *font_desc;
|
PangoFontDescription *font_desc;
|
||||||
Color font_color;
|
Color font_color;
|
||||||
char *lclick_command;
|
char *lclick_command;
|
||||||
char *mclick_command;
|
char *mclick_command;
|
||||||
char *rclick_command;
|
char *rclick_command;
|
||||||
char *uwheel_command;
|
char *uwheel_command;
|
||||||
char *dwheel_command;
|
char *dwheel_command;
|
||||||
// paddingxlr = horizontal padding left/right
|
// paddingxlr = horizontal padding left/right
|
||||||
// paddingx = horizontal padding between childs
|
// paddingx = horizontal padding between childs
|
||||||
int paddingxlr, paddingx, paddingy;
|
int paddingxlr, paddingx, paddingy;
|
||||||
Background *bg;
|
Background *bg;
|
||||||
|
|
||||||
// List of Button which are frontends for this backend, one for each panel
|
// List of Button which are frontends for this backend, one for each panel
|
||||||
GList *instances;
|
GList *instances;
|
||||||
} ButtonBackend;
|
} ButtonBackend;
|
||||||
|
|
||||||
typedef struct ButtonFrontend {
|
typedef struct ButtonFrontend {
|
||||||
// Frontend state:
|
// Frontend state:
|
||||||
Imlib_Image icon;
|
Imlib_Image icon;
|
||||||
Imlib_Image icon_hover;
|
Imlib_Image icon_hover;
|
||||||
Imlib_Image icon_pressed;
|
Imlib_Image icon_pressed;
|
||||||
int icon_load_size;
|
int icon_load_size;
|
||||||
int iconx;
|
int iconx;
|
||||||
int icony;
|
int icony;
|
||||||
int iconw;
|
int iconw;
|
||||||
int iconh;
|
int iconh;
|
||||||
int textx;
|
int textx;
|
||||||
int texty;
|
int texty;
|
||||||
int textw;
|
int textw;
|
||||||
int texth;
|
int texth;
|
||||||
} ButtonFrontend;
|
} ButtonFrontend;
|
||||||
|
|
||||||
typedef struct Button {
|
typedef struct Button {
|
||||||
Area area;
|
Area area;
|
||||||
// All elements have the backend pointer set. However only backend elements have ownership.
|
// All elements have the backend pointer set. However only backend elements have ownership.
|
||||||
ButtonBackend *backend;
|
ButtonBackend *backend;
|
||||||
// Set only for frontend Button items.
|
// Set only for frontend Button items.
|
||||||
ButtonFrontend *frontend;
|
ButtonFrontend *frontend;
|
||||||
} Button;
|
} Button;
|
||||||
|
|
||||||
// Called before the config is read and panel_config/panels are created.
|
// Called before the config is read and panel_config/panels are created.
|
||||||
// Afterwards, the config parsing code creates the array of Button in panel_config and populates the configuration fields
|
// Afterwards, the config parsing code creates the array of Button in panel_config and populates the configuration
|
||||||
|
// fields
|
||||||
// in the backend.
|
// in the backend.
|
||||||
// Probably does nothing.
|
// Probably does nothing.
|
||||||
void default_button();
|
void default_button();
|
||||||
|
|||||||
@@ -60,105 +60,105 @@ void clock_dump_geometry(void *obj, int indent);
|
|||||||
|
|
||||||
void default_clock()
|
void default_clock()
|
||||||
{
|
{
|
||||||
clock_enabled = 0;
|
clock_enabled = 0;
|
||||||
clock_timeout = NULL;
|
clock_timeout = NULL;
|
||||||
time1_format = NULL;
|
time1_format = NULL;
|
||||||
time1_timezone = NULL;
|
time1_timezone = NULL;
|
||||||
time2_format = NULL;
|
time2_format = NULL;
|
||||||
time2_timezone = NULL;
|
time2_timezone = NULL;
|
||||||
time_tooltip_format = NULL;
|
time_tooltip_format = NULL;
|
||||||
time_tooltip_timezone = NULL;
|
time_tooltip_timezone = NULL;
|
||||||
clock_lclick_command = NULL;
|
clock_lclick_command = NULL;
|
||||||
clock_mclick_command = NULL;
|
clock_mclick_command = NULL;
|
||||||
clock_rclick_command = NULL;
|
clock_rclick_command = NULL;
|
||||||
clock_uwheel_command = NULL;
|
clock_uwheel_command = NULL;
|
||||||
clock_dwheel_command = NULL;
|
clock_dwheel_command = NULL;
|
||||||
time1_has_font = FALSE;
|
time1_has_font = FALSE;
|
||||||
time1_font_desc = NULL;
|
time1_font_desc = NULL;
|
||||||
time2_has_font = FALSE;
|
time2_has_font = FALSE;
|
||||||
time2_font_desc = NULL;
|
time2_font_desc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_clock()
|
void cleanup_clock()
|
||||||
{
|
{
|
||||||
pango_font_description_free(time1_font_desc);
|
pango_font_description_free(time1_font_desc);
|
||||||
time1_font_desc = NULL;
|
time1_font_desc = NULL;
|
||||||
pango_font_description_free(time2_font_desc);
|
pango_font_description_free(time2_font_desc);
|
||||||
time2_font_desc = NULL;
|
time2_font_desc = NULL;
|
||||||
free(time1_format);
|
free(time1_format);
|
||||||
time1_format = NULL;
|
time1_format = NULL;
|
||||||
free(time2_format);
|
free(time2_format);
|
||||||
time2_format = NULL;
|
time2_format = NULL;
|
||||||
free(time_tooltip_format);
|
free(time_tooltip_format);
|
||||||
time_tooltip_format = NULL;
|
time_tooltip_format = NULL;
|
||||||
free(time1_timezone);
|
free(time1_timezone);
|
||||||
time1_timezone = NULL;
|
time1_timezone = NULL;
|
||||||
free(time2_timezone);
|
free(time2_timezone);
|
||||||
time2_timezone = NULL;
|
time2_timezone = NULL;
|
||||||
free(time_tooltip_timezone);
|
free(time_tooltip_timezone);
|
||||||
time_tooltip_timezone = NULL;
|
time_tooltip_timezone = NULL;
|
||||||
free(clock_lclick_command);
|
free(clock_lclick_command);
|
||||||
clock_lclick_command = NULL;
|
clock_lclick_command = NULL;
|
||||||
free(clock_mclick_command);
|
free(clock_mclick_command);
|
||||||
clock_mclick_command = NULL;
|
clock_mclick_command = NULL;
|
||||||
free(clock_rclick_command);
|
free(clock_rclick_command);
|
||||||
clock_rclick_command = NULL;
|
clock_rclick_command = NULL;
|
||||||
free(clock_uwheel_command);
|
free(clock_uwheel_command);
|
||||||
clock_uwheel_command = NULL;
|
clock_uwheel_command = NULL;
|
||||||
free(clock_dwheel_command);
|
free(clock_dwheel_command);
|
||||||
clock_dwheel_command = NULL;
|
clock_dwheel_command = NULL;
|
||||||
stop_timeout(clock_timeout);
|
stop_timeout(clock_timeout);
|
||||||
clock_timeout = NULL;
|
clock_timeout = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_clocks_sec(void *arg)
|
void update_clocks_sec(void *arg)
|
||||||
{
|
{
|
||||||
gettimeofday(&time_clock, 0);
|
gettimeofday(&time_clock, 0);
|
||||||
if (time1_format) {
|
if (time1_format) {
|
||||||
for (int i = 0; i < num_panels; i++)
|
for (int i = 0; i < num_panels; i++)
|
||||||
panels[i].clock.area.resize_needed = 1;
|
panels[i].clock.area.resize_needed = 1;
|
||||||
}
|
}
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_clocks_min(void *arg)
|
void update_clocks_min(void *arg)
|
||||||
{
|
{
|
||||||
// remember old_sec because after suspend/hibernate the clock should be updated directly, and not
|
// remember old_sec because after suspend/hibernate the clock should be updated directly, and not
|
||||||
// on next minute change
|
// on next minute change
|
||||||
time_t old_sec = time_clock.tv_sec;
|
time_t old_sec = time_clock.tv_sec;
|
||||||
gettimeofday(&time_clock, 0);
|
gettimeofday(&time_clock, 0);
|
||||||
if (time_clock.tv_sec % 60 == 0 || time_clock.tv_sec - old_sec > 60) {
|
if (time_clock.tv_sec % 60 == 0 || time_clock.tv_sec - old_sec > 60) {
|
||||||
if (time1_format) {
|
if (time1_format) {
|
||||||
for (int i = 0; i < num_panels; i++)
|
for (int i = 0; i < num_panels; i++)
|
||||||
panels[i].clock.area.resize_needed = 1;
|
panels[i].clock.area.resize_needed = 1;
|
||||||
}
|
}
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tm *clock_gettime_for_tz(const char *timezone)
|
struct tm *clock_gettime_for_tz(const char *timezone)
|
||||||
{
|
{
|
||||||
if (timezone) {
|
if (timezone) {
|
||||||
const char *old_tz = getenv("TZ");
|
const char *old_tz = getenv("TZ");
|
||||||
setenv("TZ", timezone, 1);
|
setenv("TZ", timezone, 1);
|
||||||
struct tm *result = localtime(&time_clock.tv_sec);
|
struct tm *result = localtime(&time_clock.tv_sec);
|
||||||
if (old_tz)
|
if (old_tz)
|
||||||
setenv("TZ", old_tz, 1);
|
setenv("TZ", old_tz, 1);
|
||||||
else
|
else
|
||||||
unsetenv("TZ");
|
unsetenv("TZ");
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
return localtime(&time_clock.tv_sec);
|
return localtime(&time_clock.tv_sec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean time_format_needs_sec_ticks(char *time_format)
|
gboolean time_format_needs_sec_ticks(char *time_format)
|
||||||
{
|
{
|
||||||
if (!time_format)
|
if (!time_format)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (strchr(time_format, 'S') || strchr(time_format, 'T') || strchr(time_format, 'r'))
|
if (strchr(time_format, 'S') || strchr(time_format, 'T') || strchr(time_format, 'r'))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_clock()
|
void init_clock()
|
||||||
@@ -167,80 +167,80 @@ void init_clock()
|
|||||||
|
|
||||||
void init_clock_panel(void *p)
|
void init_clock_panel(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
Clock *clock = &panel->clock;
|
Clock *clock = &panel->clock;
|
||||||
|
|
||||||
if (!clock_timeout) {
|
if (!clock_timeout) {
|
||||||
if (time_format_needs_sec_ticks(time1_format) || time_format_needs_sec_ticks(time2_format)) {
|
if (time_format_needs_sec_ticks(time1_format) || time_format_needs_sec_ticks(time2_format)) {
|
||||||
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0, &clock_timeout);
|
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0, &clock_timeout);
|
||||||
} else {
|
} else {
|
||||||
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0, &clock_timeout);
|
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0, &clock_timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clock->area.bg)
|
if (!clock->area.bg)
|
||||||
clock->area.bg = &g_array_index(backgrounds, Background, 0);
|
clock->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
clock_init_fonts();
|
clock_init_fonts();
|
||||||
clock->area.parent = p;
|
clock->area.parent = p;
|
||||||
clock->area.panel = p;
|
clock->area.panel = p;
|
||||||
snprintf(clock->area.name, sizeof(clock->area.name), "Clock");
|
snprintf(clock->area.name, sizeof(clock->area.name), "Clock");
|
||||||
clock->area._is_under_mouse = full_width_area_is_under_mouse;
|
clock->area._is_under_mouse = full_width_area_is_under_mouse;
|
||||||
clock->area.has_mouse_press_effect = clock->area.has_mouse_over_effect =
|
clock->area.has_mouse_press_effect = clock->area.has_mouse_over_effect =
|
||||||
panel_config.mouse_effects && (clock_lclick_command || clock_mclick_command || clock_rclick_command ||
|
panel_config.mouse_effects && (clock_lclick_command || clock_mclick_command || clock_rclick_command ||
|
||||||
clock_uwheel_command || clock_dwheel_command);
|
clock_uwheel_command || clock_dwheel_command);
|
||||||
clock->area._draw_foreground = draw_clock;
|
clock->area._draw_foreground = draw_clock;
|
||||||
clock->area.size_mode = LAYOUT_FIXED;
|
clock->area.size_mode = LAYOUT_FIXED;
|
||||||
clock->area._resize = resize_clock;
|
clock->area._resize = resize_clock;
|
||||||
clock->area._compute_desired_size = clock_compute_desired_size;
|
clock->area._compute_desired_size = clock_compute_desired_size;
|
||||||
clock->area._dump_geometry = clock_dump_geometry;
|
clock->area._dump_geometry = clock_dump_geometry;
|
||||||
// check consistency
|
// check consistency
|
||||||
if (!time1_format)
|
if (!time1_format)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clock->area.resize_needed = 1;
|
clock->area.resize_needed = 1;
|
||||||
clock->area.on_screen = TRUE;
|
clock->area.on_screen = TRUE;
|
||||||
instantiate_area_gradients(&clock->area);
|
instantiate_area_gradients(&clock->area);
|
||||||
|
|
||||||
if (time_tooltip_format) {
|
if (time_tooltip_format) {
|
||||||
clock->area._get_tooltip_text = clock_get_tooltip;
|
clock->area._get_tooltip_text = clock_get_tooltip;
|
||||||
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_init_fonts()
|
void clock_init_fonts()
|
||||||
{
|
{
|
||||||
if (!time1_font_desc) {
|
if (!time1_font_desc) {
|
||||||
time1_font_desc = pango_font_description_from_string(get_default_font());
|
time1_font_desc = pango_font_description_from_string(get_default_font());
|
||||||
pango_font_description_set_weight(time1_font_desc, PANGO_WEIGHT_BOLD);
|
pango_font_description_set_weight(time1_font_desc, PANGO_WEIGHT_BOLD);
|
||||||
pango_font_description_set_size(time1_font_desc, pango_font_description_get_size(time1_font_desc));
|
pango_font_description_set_size(time1_font_desc, pango_font_description_get_size(time1_font_desc));
|
||||||
}
|
}
|
||||||
if (!time2_font_desc) {
|
if (!time2_font_desc) {
|
||||||
time2_font_desc = pango_font_description_from_string(get_default_font());
|
time2_font_desc = pango_font_description_from_string(get_default_font());
|
||||||
pango_font_description_set_size(time2_font_desc,
|
pango_font_description_set_size(time2_font_desc,
|
||||||
pango_font_description_get_size(time2_font_desc) - PANGO_SCALE);
|
pango_font_description_get_size(time2_font_desc) - PANGO_SCALE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_default_font_changed()
|
void clock_default_font_changed()
|
||||||
{
|
{
|
||||||
if (!clock_enabled)
|
if (!clock_enabled)
|
||||||
return;
|
return;
|
||||||
if (time1_has_font && time2_has_font)
|
if (time1_has_font && time2_has_font)
|
||||||
return;
|
return;
|
||||||
if (!time1_has_font) {
|
if (!time1_has_font) {
|
||||||
pango_font_description_free(time1_font_desc);
|
pango_font_description_free(time1_font_desc);
|
||||||
time1_font_desc = NULL;
|
time1_font_desc = NULL;
|
||||||
}
|
}
|
||||||
if (!time2_has_font) {
|
if (!time2_has_font) {
|
||||||
pango_font_description_free(time2_font_desc);
|
pango_font_description_free(time2_font_desc);
|
||||||
time2_font_desc = NULL;
|
time2_font_desc = NULL;
|
||||||
}
|
}
|
||||||
clock_init_fonts();
|
clock_init_fonts();
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
panels[i].clock.area.resize_needed = TRUE;
|
panels[i].clock.area.resize_needed = TRUE;
|
||||||
schedule_redraw(&panels[i].clock.area);
|
schedule_redraw(&panels[i].clock.area);
|
||||||
}
|
}
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_compute_text_geometry(Panel *panel,
|
void clock_compute_text_geometry(Panel *panel,
|
||||||
@@ -251,167 +251,167 @@ void clock_compute_text_geometry(Panel *panel,
|
|||||||
int *date_height,
|
int *date_height,
|
||||||
int *date_width)
|
int *date_width)
|
||||||
{
|
{
|
||||||
*date_height = *date_width = 0;
|
*date_height = *date_width = 0;
|
||||||
strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone));
|
strftime(buf_time, sizeof(buf_time), time1_format, clock_gettime_for_tz(time1_timezone));
|
||||||
get_text_size2(time1_font_desc,
|
get_text_size2(time1_font_desc,
|
||||||
time_height_ink,
|
time_height_ink,
|
||||||
time_height,
|
time_height,
|
||||||
time_width,
|
time_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
buf_time,
|
buf_time,
|
||||||
strlen(buf_time),
|
strlen(buf_time),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (time2_format) {
|
if (time2_format) {
|
||||||
strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone));
|
strftime(buf_date, sizeof(buf_date), time2_format, clock_gettime_for_tz(time2_timezone));
|
||||||
get_text_size2(time2_font_desc,
|
get_text_size2(time2_font_desc,
|
||||||
date_height_ink,
|
date_height_ink,
|
||||||
date_height,
|
date_height,
|
||||||
date_width,
|
date_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
buf_date,
|
buf_date,
|
||||||
strlen(buf_date),
|
strlen(buf_date),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int clock_compute_desired_size(void *obj)
|
int clock_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
Clock *clock = (Clock *)obj;
|
Clock *clock = (Clock *)obj;
|
||||||
Panel *panel = (Panel *)clock->area.panel;
|
Panel *panel = (Panel *)clock->area.panel;
|
||||||
int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width;
|
int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width;
|
||||||
clock_compute_text_geometry(panel,
|
clock_compute_text_geometry(panel,
|
||||||
&time_height_ink,
|
&time_height_ink,
|
||||||
&time_height,
|
&time_height,
|
||||||
&time_width,
|
&time_width,
|
||||||
&date_height_ink,
|
&date_height_ink,
|
||||||
&date_height,
|
&date_height,
|
||||||
&date_width);
|
&date_width);
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
int new_size = (time_width > date_width) ? time_width : date_width;
|
int new_size = (time_width > date_width) ? time_width : date_width;
|
||||||
new_size += 2 * clock->area.paddingxlr + left_right_border_width(&clock->area);
|
new_size += 2 * clock->area.paddingxlr + left_right_border_width(&clock->area);
|
||||||
return new_size;
|
return new_size;
|
||||||
} else {
|
} else {
|
||||||
int new_size = time_height + date_height + 2 * clock->area.paddingxlr + top_bottom_border_width(&clock->area);
|
int new_size = time_height + date_height + 2 * clock->area.paddingxlr + top_bottom_border_width(&clock->area);
|
||||||
return new_size;
|
return new_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_clock(void *obj)
|
gboolean resize_clock(void *obj)
|
||||||
{
|
{
|
||||||
Clock *clock = (Clock *)obj;
|
Clock *clock = (Clock *)obj;
|
||||||
Panel *panel = (Panel *)clock->area.panel;
|
Panel *panel = (Panel *)clock->area.panel;
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
|
|
||||||
schedule_redraw(&clock->area);
|
schedule_redraw(&clock->area);
|
||||||
|
|
||||||
int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width;
|
int time_height_ink, time_height, time_width, date_height_ink, date_height, date_width;
|
||||||
clock_compute_text_geometry(panel,
|
clock_compute_text_geometry(panel,
|
||||||
&time_height_ink,
|
&time_height_ink,
|
||||||
&time_height,
|
&time_height,
|
||||||
&time_width,
|
&time_width,
|
||||||
&date_height_ink,
|
&date_height_ink,
|
||||||
&date_height,
|
&date_height,
|
||||||
&date_width);
|
&date_width);
|
||||||
|
|
||||||
int new_size = clock_compute_desired_size(clock);
|
int new_size = clock_compute_desired_size(clock);
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (new_size > clock->area.width || new_size < (clock->area.width - 6)) {
|
if (new_size > clock->area.width || new_size < (clock->area.width - 6)) {
|
||||||
// we try to limit the number of resizes
|
// we try to limit the number of resizes
|
||||||
clock->area.width = new_size + 1;
|
clock->area.width = new_size + 1;
|
||||||
clock->time1_posy = (clock->area.height - time_height) / 2;
|
clock->time1_posy = (clock->area.height - time_height) / 2;
|
||||||
if (time2_format) {
|
if (time2_format) {
|
||||||
clock->time1_posy -= (date_height) / 2;
|
clock->time1_posy -= (date_height) / 2;
|
||||||
clock->time2_posy = clock->time1_posy + time_height;
|
clock->time2_posy = clock->time1_posy + time_height;
|
||||||
}
|
}
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (new_size != clock->area.height) {
|
if (new_size != clock->area.height) {
|
||||||
// we try to limit the number of resizes
|
// we try to limit the number of resizes
|
||||||
clock->area.height = new_size;
|
clock->area.height = new_size;
|
||||||
clock->time1_posy = (clock->area.height - time_height) / 2;
|
clock->time1_posy = (clock->area.height - time_height) / 2;
|
||||||
if (time2_format) {
|
if (time2_format) {
|
||||||
clock->time1_posy -= (date_height) / 2;
|
clock->time1_posy -= (date_height) / 2;
|
||||||
clock->time2_posy = clock->time1_posy + time_height;
|
clock->time2_posy = clock->time1_posy + time_height;
|
||||||
}
|
}
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_clock(void *obj, cairo_t *c)
|
void draw_clock(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
Clock *clock = obj;
|
Clock *clock = obj;
|
||||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||||
|
|
||||||
pango_layout_set_font_description(layout, time1_font_desc);
|
pango_layout_set_font_description(layout, time1_font_desc);
|
||||||
pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
|
pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
|
||||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||||
pango_layout_set_text(layout, buf_time, strlen(buf_time));
|
pango_layout_set_text(layout, buf_time, strlen(buf_time));
|
||||||
|
|
||||||
cairo_set_source_rgba(c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha);
|
cairo_set_source_rgba(c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha);
|
||||||
|
|
||||||
pango_cairo_update_layout(c, layout);
|
pango_cairo_update_layout(c, layout);
|
||||||
draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
|
draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
|
||||||
|
|
||||||
if (time2_format) {
|
if (time2_format) {
|
||||||
pango_layout_set_font_description(layout, time2_font_desc);
|
pango_layout_set_font_description(layout, time2_font_desc);
|
||||||
pango_layout_set_indent(layout, 0);
|
pango_layout_set_indent(layout, 0);
|
||||||
pango_layout_set_text(layout, buf_date, strlen(buf_date));
|
pango_layout_set_text(layout, buf_date, strlen(buf_date));
|
||||||
pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
|
pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
|
||||||
|
|
||||||
pango_cairo_update_layout(c, layout);
|
pango_cairo_update_layout(c, layout);
|
||||||
draw_text(layout, c, 0, clock->time2_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
|
draw_text(layout, c, 0, clock->time2_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_dump_geometry(void *obj, int indent)
|
void clock_dump_geometry(void *obj, int indent)
|
||||||
{
|
{
|
||||||
Clock *clock = (Clock *)obj;
|
Clock *clock = (Clock *)obj;
|
||||||
fprintf(stderr, "%*sText 1: y = %d, text = %s\n", indent, "", clock->time1_posy, buf_time);
|
fprintf(stderr, "%*sText 1: y = %d, text = %s\n", indent, "", clock->time1_posy, buf_time);
|
||||||
if (time2_format) {
|
if (time2_format) {
|
||||||
fprintf(stderr, "%*sText 2: y = %d, text = %s\n", indent, "", clock->time2_posy, buf_date);
|
fprintf(stderr, "%*sText 2: y = %d, text = %s\n", indent, "", clock->time2_posy, buf_date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *clock_get_tooltip(void *obj)
|
char *clock_get_tooltip(void *obj)
|
||||||
{
|
{
|
||||||
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
strftime(buf_tooltip, sizeof(buf_tooltip), time_tooltip_format, clock_gettime_for_tz(time_tooltip_timezone));
|
||||||
return strdup(buf_tooltip);
|
return strdup(buf_tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_action(int button)
|
void clock_action(int button)
|
||||||
{
|
{
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case 1:
|
case 1:
|
||||||
command = clock_lclick_command;
|
command = clock_lclick_command;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
command = clock_mclick_command;
|
command = clock_mclick_command;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
command = clock_rclick_command;
|
command = clock_rclick_command;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
command = clock_uwheel_command;
|
command = clock_uwheel_command;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
command = clock_dwheel_command;
|
command = clock_dwheel_command;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tint_exec(command);
|
tint_exec(command);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
|
||||||
typedef struct Clock {
|
typedef struct Clock {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
|
|
||||||
Color font;
|
Color font;
|
||||||
int time1_posy;
|
int time1_posy;
|
||||||
int time2_posy;
|
int time2_posy;
|
||||||
} Clock;
|
} Clock;
|
||||||
|
|
||||||
extern char *time1_format;
|
extern char *time1_format;
|
||||||
|
|||||||
2361
src/config.c
2361
src/config.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -17,78 +17,78 @@
|
|||||||
// backend's config and state variables.
|
// backend's config and state variables.
|
||||||
|
|
||||||
typedef struct ExecpBackend {
|
typedef struct ExecpBackend {
|
||||||
// Config:
|
// Config:
|
||||||
// Command to execute at a specified interval
|
// Command to execute at a specified interval
|
||||||
char *command;
|
char *command;
|
||||||
// Interval in seconds
|
// Interval in seconds
|
||||||
int interval;
|
int interval;
|
||||||
// 1 if first line of output is an icon path
|
// 1 if first line of output is an icon path
|
||||||
gboolean has_icon;
|
gboolean has_icon;
|
||||||
gboolean cache_icon;
|
gboolean cache_icon;
|
||||||
int icon_w;
|
int icon_w;
|
||||||
int icon_h;
|
int icon_h;
|
||||||
char *tooltip;
|
char *tooltip;
|
||||||
gboolean centered;
|
gboolean centered;
|
||||||
gboolean has_font;
|
gboolean has_font;
|
||||||
PangoFontDescription *font_desc;
|
PangoFontDescription *font_desc;
|
||||||
Color font_color;
|
Color font_color;
|
||||||
int continuous;
|
int continuous;
|
||||||
gboolean has_markup;
|
gboolean has_markup;
|
||||||
char *lclick_command;
|
char *lclick_command;
|
||||||
char *mclick_command;
|
char *mclick_command;
|
||||||
char *rclick_command;
|
char *rclick_command;
|
||||||
char *uwheel_command;
|
char *uwheel_command;
|
||||||
char *dwheel_command;
|
char *dwheel_command;
|
||||||
// paddingxlr = horizontal padding left/right
|
// paddingxlr = horizontal padding left/right
|
||||||
// paddingx = horizontal padding between childs
|
// paddingx = horizontal padding between childs
|
||||||
int paddingxlr, paddingx, paddingy;
|
int paddingxlr, paddingx, paddingy;
|
||||||
Background *bg;
|
Background *bg;
|
||||||
|
|
||||||
// Backend state:
|
// Backend state:
|
||||||
timeout *timer;
|
timeout *timer;
|
||||||
int child_pipe;
|
int child_pipe;
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
|
||||||
// Command output buffer
|
// Command output buffer
|
||||||
char *buf_output;
|
char *buf_output;
|
||||||
int buf_length;
|
int buf_length;
|
||||||
int buf_capacity;
|
int buf_capacity;
|
||||||
|
|
||||||
// Text extracted from the output buffer
|
// Text extracted from the output buffer
|
||||||
char *text;
|
char *text;
|
||||||
// Icon path extracted from the output buffer
|
// Icon path extracted from the output buffer
|
||||||
char *icon_path;
|
char *icon_path;
|
||||||
Imlib_Image icon;
|
Imlib_Image icon;
|
||||||
char tooltip_text[512];
|
char tooltip_text[512];
|
||||||
|
|
||||||
// The time the last command was started
|
// The time the last command was started
|
||||||
time_t last_update_start_time;
|
time_t last_update_start_time;
|
||||||
// The time the last output was obtained
|
// The time the last output was obtained
|
||||||
time_t last_update_finish_time;
|
time_t last_update_finish_time;
|
||||||
// The time it took to execute last command
|
// The time it took to execute last command
|
||||||
time_t last_update_duration;
|
time_t last_update_duration;
|
||||||
|
|
||||||
// List of Execp which are frontends for this backend, one for each panel
|
// List of Execp which are frontends for this backend, one for each panel
|
||||||
GList *instances;
|
GList *instances;
|
||||||
GTree *cmd_pids;
|
GTree *cmd_pids;
|
||||||
} ExecpBackend;
|
} ExecpBackend;
|
||||||
|
|
||||||
typedef struct ExecpFrontend {
|
typedef struct ExecpFrontend {
|
||||||
// Frontend state:
|
// Frontend state:
|
||||||
int iconx;
|
int iconx;
|
||||||
int icony;
|
int icony;
|
||||||
int textx;
|
int textx;
|
||||||
int texty;
|
int texty;
|
||||||
int textw;
|
int textw;
|
||||||
int texth;
|
int texth;
|
||||||
} ExecpFrontend;
|
} ExecpFrontend;
|
||||||
|
|
||||||
typedef struct Execp {
|
typedef struct Execp {
|
||||||
Area area;
|
Area area;
|
||||||
// All elements have the backend pointer set. However only backend elements have ownership.
|
// All elements have the backend pointer set. However only backend elements have ownership.
|
||||||
ExecpBackend *backend;
|
ExecpBackend *backend;
|
||||||
// Set only for frontend Execp items.
|
// Set only for frontend Execp items.
|
||||||
ExecpFrontend *frontend;
|
ExecpFrontend *frontend;
|
||||||
} Execp;
|
} Execp;
|
||||||
|
|
||||||
// Called before the config is read and panel_config/panels are created.
|
// Called before the config is read and panel_config/panels are created.
|
||||||
|
|||||||
@@ -34,93 +34,93 @@ int freespace_area_compute_desired_size(void *obj);
|
|||||||
|
|
||||||
void init_freespace_panel(void *p)
|
void init_freespace_panel(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
|
|
||||||
// Make sure this is only done once if there are multiple items
|
// Make sure this is only done once if there are multiple items
|
||||||
if (panel->freespace_list)
|
if (panel->freespace_list)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t k = 0; k < strlen(panel_items_order); k++) {
|
for (size_t k = 0; k < strlen(panel_items_order); k++) {
|
||||||
if (panel_items_order[k] == 'F') {
|
if (panel_items_order[k] == 'F') {
|
||||||
FreeSpace *freespace = (FreeSpace *) calloc(1, sizeof(FreeSpace));
|
FreeSpace *freespace = (FreeSpace *)calloc(1, sizeof(FreeSpace));
|
||||||
panel->freespace_list = g_list_append(panel->freespace_list, freespace);
|
panel->freespace_list = g_list_append(panel->freespace_list, freespace);
|
||||||
if (!freespace->area.bg)
|
if (!freespace->area.bg)
|
||||||
freespace->area.bg = &g_array_index(backgrounds, Background, 0);
|
freespace->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
freespace->area.parent = p;
|
freespace->area.parent = p;
|
||||||
freespace->area.panel = p;
|
freespace->area.panel = p;
|
||||||
snprintf(freespace->area.name, sizeof(freespace->area.name), "Freespace");
|
snprintf(freespace->area.name, sizeof(freespace->area.name), "Freespace");
|
||||||
freespace->area.size_mode = LAYOUT_FIXED;
|
freespace->area.size_mode = LAYOUT_FIXED;
|
||||||
freespace->area.resize_needed = 1;
|
freespace->area.resize_needed = 1;
|
||||||
freespace->area.on_screen = TRUE;
|
freespace->area.on_screen = TRUE;
|
||||||
freespace->area._resize = resize_freespace;
|
freespace->area._resize = resize_freespace;
|
||||||
freespace->area._compute_desired_size = freespace_area_compute_desired_size;
|
freespace->area._compute_desired_size = freespace_area_compute_desired_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_freespace(Panel *panel)
|
void cleanup_freespace(Panel *panel)
|
||||||
{
|
{
|
||||||
if (panel->freespace_list)
|
if (panel->freespace_list)
|
||||||
g_list_free_full(panel->freespace_list, free);
|
g_list_free_full(panel->freespace_list, free);
|
||||||
panel->freespace_list = NULL;
|
panel->freespace_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int freespace_get_max_size(Panel *p)
|
int freespace_get_max_size(Panel *p)
|
||||||
{
|
{
|
||||||
if (panel_shrink)
|
if (panel_shrink)
|
||||||
return 0;
|
return 0;
|
||||||
// Get space used by every element except the freespace
|
// Get space used by every element except the freespace
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int spacers = 0;
|
int spacers = 0;
|
||||||
for (GList *walk = p->area.children; walk; walk = g_list_next(walk)) {
|
for (GList *walk = p->area.children; walk; walk = g_list_next(walk)) {
|
||||||
Area *a = (Area *)walk->data;
|
Area *a = (Area *)walk->data;
|
||||||
|
|
||||||
if (!a->on_screen)
|
if (!a->on_screen)
|
||||||
continue;
|
continue;
|
||||||
if (a->_resize == resize_freespace) {
|
if (a->_resize == resize_freespace) {
|
||||||
spacers++;
|
spacers++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panel_horizontal)
|
if (panel_horizontal)
|
||||||
size += a->width + p->area.paddingx;
|
size += a->width + p->area.paddingx;
|
||||||
else
|
else
|
||||||
size += a->height + p->area.paddingy;
|
size += a->height + p->area.paddingy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panel_horizontal)
|
if (panel_horizontal)
|
||||||
size = p->area.width - size - left_right_border_width(&p->area) - p->area.paddingxlr;
|
size = p->area.width - size - left_right_border_width(&p->area) - p->area.paddingxlr;
|
||||||
else
|
else
|
||||||
size = p->area.height - size - top_bottom_border_width(&p->area) - p->area.paddingxlr;
|
size = p->area.height - size - top_bottom_border_width(&p->area) - p->area.paddingxlr;
|
||||||
|
|
||||||
return size / spacers;
|
return size / spacers;
|
||||||
}
|
}
|
||||||
|
|
||||||
int freespace_area_compute_desired_size(void *obj)
|
int freespace_area_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
FreeSpace *freespace = (FreeSpace *) obj;
|
FreeSpace *freespace = (FreeSpace *)obj;
|
||||||
return freespace_get_max_size((Panel *)freespace->area.panel);
|
return freespace_get_max_size((Panel *)freespace->area.panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_freespace(void *obj)
|
gboolean resize_freespace(void *obj)
|
||||||
{
|
{
|
||||||
FreeSpace *freespace = (FreeSpace *)obj;
|
FreeSpace *freespace = (FreeSpace *)obj;
|
||||||
Panel *panel = (Panel *)freespace->area.panel;
|
Panel *panel = (Panel *)freespace->area.panel;
|
||||||
if (!freespace->area.on_screen)
|
if (!freespace->area.on_screen)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
int old_size = panel_horizontal ? freespace->area.width : freespace->area.height;
|
int old_size = panel_horizontal ? freespace->area.width : freespace->area.height;
|
||||||
int size = freespace_get_max_size(panel);
|
int size = freespace_get_max_size(panel);
|
||||||
if (old_size == size)
|
if (old_size == size)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
freespace->area.width = size;
|
freespace->area.width = size;
|
||||||
} else {
|
} else {
|
||||||
freespace->area.height = size;
|
freespace->area.height = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_redraw(&freespace->area);
|
schedule_redraw(&freespace->area);
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
|
||||||
typedef struct FreeSpace {
|
typedef struct FreeSpace {
|
||||||
Area area;
|
Area area;
|
||||||
} FreeSpace;
|
} FreeSpace;
|
||||||
|
|
||||||
struct Panel;
|
struct Panel;
|
||||||
|
|||||||
@@ -30,280 +30,280 @@
|
|||||||
|
|
||||||
static gint compare_strings(gconstpointer a, gconstpointer b)
|
static gint compare_strings(gconstpointer a, gconstpointer b)
|
||||||
{
|
{
|
||||||
return strnatcasecmp((const char *)a, (const char *)b);
|
return strnatcasecmp((const char *)a, (const char *)b);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_dektop_line(char *line, char **key, char **value)
|
int parse_dektop_line(char *line, char **key, char **value)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
*key = line;
|
*key = line;
|
||||||
for (p = line; *p; p++) {
|
for (p = line; *p; p++) {
|
||||||
if (*p == '=') {
|
if (*p == '=') {
|
||||||
*value = p + 1;
|
*value = p + 1;
|
||||||
*p = 0;
|
*p = 0;
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
return 0;
|
return 0;
|
||||||
if (found && (strlen(*key) == 0 || strlen(*value) == 0))
|
if (found && (strlen(*key) == 0 || strlen(*value) == 0))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void expand_exec(DesktopEntry *entry, const char *path)
|
void expand_exec(DesktopEntry *entry, const char *path)
|
||||||
{
|
{
|
||||||
// Expand % in exec
|
// Expand % in exec
|
||||||
// %i -> --icon Icon
|
// %i -> --icon Icon
|
||||||
// %c -> Name
|
// %c -> Name
|
||||||
// %k -> path
|
// %k -> path
|
||||||
if (entry->exec) {
|
if (entry->exec) {
|
||||||
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
|
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) +
|
||||||
(entry->icon ? strlen(entry->icon) : 1) + 100,
|
(entry->icon ? strlen(entry->icon) : 1) + 100,
|
||||||
1);
|
1);
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
// p will never point to an escaped char
|
// p will never point to an escaped char
|
||||||
for (p = entry->exec, q = exec2; *p; p++, q++) {
|
for (p = entry->exec, q = exec2; *p; p++, q++) {
|
||||||
*q = *p; // Copy
|
*q = *p; // Copy
|
||||||
if (*p == '\\') {
|
if (*p == '\\') {
|
||||||
p++, q++;
|
p++, q++;
|
||||||
// Copy the escaped char
|
// Copy the escaped char
|
||||||
if (*p == '%') // For % we delete the backslash, i.e. write % over it
|
if (*p == '%') // For % we delete the backslash, i.e. write % over it
|
||||||
q--;
|
q--;
|
||||||
*q = *p;
|
*q = *p;
|
||||||
if (!*p)
|
if (!*p)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*p == '%') {
|
if (*p == '%') {
|
||||||
p++;
|
p++;
|
||||||
if (!*p)
|
if (!*p)
|
||||||
break;
|
break;
|
||||||
if (*p == 'i' && entry->icon != NULL) {
|
if (*p == 'i' && entry->icon != NULL) {
|
||||||
sprintf(q, "--icon '%s'", entry->icon);
|
sprintf(q, "--icon '%s'", entry->icon);
|
||||||
q += strlen("--icon ''");
|
q += strlen("--icon ''");
|
||||||
q += strlen(entry->icon);
|
q += strlen(entry->icon);
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else if (*p == 'c' && entry->name != NULL) {
|
} else if (*p == 'c' && entry->name != NULL) {
|
||||||
sprintf(q, "'%s'", entry->name);
|
sprintf(q, "'%s'", entry->name);
|
||||||
q += strlen("''");
|
q += strlen("''");
|
||||||
q += strlen(entry->name);
|
q += strlen(entry->name);
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else if (*p == 'c') {
|
} else if (*p == 'c') {
|
||||||
sprintf(q, "'%s'", path);
|
sprintf(q, "'%s'", path);
|
||||||
q += strlen("''");
|
q += strlen("''");
|
||||||
q += strlen(path);
|
q += strlen(path);
|
||||||
q--; // To balance the q++ in the for
|
q--; // To balance the q++ in the for
|
||||||
} else {
|
} else {
|
||||||
// We don't care about other expansions
|
// We don't care about other expansions
|
||||||
q--; // Delete the last % from q
|
q--; // Delete the last % from q
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
free(entry->exec);
|
free(entry->exec);
|
||||||
entry->exec = exec2;
|
entry->exec = exec2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean read_desktop_file_full_path(const char *path, DesktopEntry *entry)
|
gboolean read_desktop_file_full_path(const char *path, DesktopEntry *entry)
|
||||||
{
|
{
|
||||||
entry->name = entry->generic_name = entry->icon = entry->exec = entry->cwd = NULL;
|
entry->name = entry->generic_name = entry->icon = entry->exec = entry->cwd = NULL;
|
||||||
entry->hidden_from_menus = FALSE;
|
entry->hidden_from_menus = FALSE;
|
||||||
|
|
||||||
FILE *fp = fopen(path, "rt");
|
FILE *fp = fopen(path, "rt");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
fprintf(stderr, "Could not open file %s\n", path);
|
fprintf(stderr, "Could not open file %s\n", path);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar **languages = (const gchar **)g_get_language_names();
|
const gchar **languages = (const gchar **)g_get_language_names();
|
||||||
// lang_index is the index of the language for the best Name key in the language vector
|
// lang_index is the index of the language for the best Name key in the language vector
|
||||||
// lang_index_default is a constant that encodes the Name key without a language
|
// lang_index_default is a constant that encodes the Name key without a language
|
||||||
int lang_index_default = 1;
|
int lang_index_default = 1;
|
||||||
#define LANG_DBG 0
|
#define LANG_DBG 0
|
||||||
if (LANG_DBG)
|
if (LANG_DBG)
|
||||||
printf("Languages:");
|
printf("Languages:");
|
||||||
for (int i = 0; languages[i]; i++) {
|
for (int i = 0; languages[i]; i++) {
|
||||||
lang_index_default = i + 1;
|
lang_index_default = i + 1;
|
||||||
if (LANG_DBG)
|
if (LANG_DBG)
|
||||||
printf(" %s", languages[i]);
|
printf(" %s", languages[i]);
|
||||||
}
|
}
|
||||||
if (LANG_DBG)
|
if (LANG_DBG)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
// we currently do not know about any Name key at all, so use an invalid index
|
// we currently do not know about any Name key at all, so use an invalid index
|
||||||
int lang_index_name = lang_index_default + 1;
|
int lang_index_name = lang_index_default + 1;
|
||||||
int lang_index_generic_name = lang_index_default + 1;
|
int lang_index_generic_name = lang_index_default + 1;
|
||||||
|
|
||||||
gboolean inside_desktop_entry = 0;
|
gboolean inside_desktop_entry = 0;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t line_size;
|
size_t line_size;
|
||||||
while (getline(&line, &line_size, fp) >= 0) {
|
while (getline(&line, &line_size, fp) >= 0) {
|
||||||
int len = strlen(line);
|
int len = strlen(line);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
continue;
|
continue;
|
||||||
if (line[len - 1] == '\n')
|
if (line[len - 1] == '\n')
|
||||||
line[len - 1] = '\0';
|
line[len - 1] = '\0';
|
||||||
if (line[0] == '[') {
|
if (line[0] == '[') {
|
||||||
inside_desktop_entry = (strcmp(line, "[Desktop Entry]") == 0);
|
inside_desktop_entry = (strcmp(line, "[Desktop Entry]") == 0);
|
||||||
}
|
}
|
||||||
char *key, *value;
|
char *key, *value;
|
||||||
if (inside_desktop_entry && parse_dektop_line(line, &key, &value)) {
|
if (inside_desktop_entry && parse_dektop_line(line, &key, &value)) {
|
||||||
if (strstr(key, "Name") == key) {
|
if (strstr(key, "Name") == key) {
|
||||||
if (strcmp(key, "Name") == 0 && lang_index_name > lang_index_default) {
|
if (strcmp(key, "Name") == 0 && lang_index_name > lang_index_default) {
|
||||||
entry->name = strdup(value);
|
entry->name = strdup(value);
|
||||||
lang_index_name = lang_index_default;
|
lang_index_name = lang_index_default;
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; languages[i] && i < lang_index_name; i++) {
|
for (int i = 0; languages[i] && i < lang_index_name; i++) {
|
||||||
gchar *localized_key = g_strdup_printf("Name[%s]", languages[i]);
|
gchar *localized_key = g_strdup_printf("Name[%s]", languages[i]);
|
||||||
if (strcmp(key, localized_key) == 0) {
|
if (strcmp(key, localized_key) == 0) {
|
||||||
if (entry->name)
|
if (entry->name)
|
||||||
free(entry->name);
|
free(entry->name);
|
||||||
entry->name = strdup(value);
|
entry->name = strdup(value);
|
||||||
lang_index_name = i;
|
lang_index_name = i;
|
||||||
}
|
}
|
||||||
g_free(localized_key);
|
g_free(localized_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strstr(key, "GenericName") == key) {
|
} else if (strstr(key, "GenericName") == key) {
|
||||||
if (strcmp(key, "GenericName") == 0 && lang_index_generic_name > lang_index_default) {
|
if (strcmp(key, "GenericName") == 0 && lang_index_generic_name > lang_index_default) {
|
||||||
entry->generic_name = strdup(value);
|
entry->generic_name = strdup(value);
|
||||||
lang_index_generic_name = lang_index_default;
|
lang_index_generic_name = lang_index_default;
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; languages[i] && i < lang_index_generic_name; i++) {
|
for (int i = 0; languages[i] && i < lang_index_generic_name; i++) {
|
||||||
gchar *localized_key = g_strdup_printf("GenericName[%s]", languages[i]);
|
gchar *localized_key = g_strdup_printf("GenericName[%s]", languages[i]);
|
||||||
if (strcmp(key, localized_key) == 0) {
|
if (strcmp(key, localized_key) == 0) {
|
||||||
if (entry->generic_name)
|
if (entry->generic_name)
|
||||||
free(entry->generic_name);
|
free(entry->generic_name);
|
||||||
entry->generic_name = strdup(value);
|
entry->generic_name = strdup(value);
|
||||||
lang_index_generic_name = i;
|
lang_index_generic_name = i;
|
||||||
}
|
}
|
||||||
g_free(localized_key);
|
g_free(localized_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!entry->exec && strcmp(key, "Exec") == 0) {
|
} else if (!entry->exec && strcmp(key, "Exec") == 0) {
|
||||||
entry->exec = strdup(value);
|
entry->exec = strdup(value);
|
||||||
} else if (!entry->cwd && strcmp(key, "Path") == 0) {
|
} else if (!entry->cwd && strcmp(key, "Path") == 0) {
|
||||||
entry->cwd = strdup(value);
|
entry->cwd = strdup(value);
|
||||||
} else if (!entry->icon && strcmp(key, "Icon") == 0) {
|
} else if (!entry->icon && strcmp(key, "Icon") == 0) {
|
||||||
entry->icon = strdup(value);
|
entry->icon = strdup(value);
|
||||||
} else if (strcmp(key, "NoDisplay") == 0) {
|
} else if (strcmp(key, "NoDisplay") == 0) {
|
||||||
entry->hidden_from_menus = strcasecmp(value, "true") == 0;
|
entry->hidden_from_menus = strcasecmp(value, "true") == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
// From this point:
|
// From this point:
|
||||||
// entry->name, entry->generic_name, entry->icon, entry->exec will never be empty strings (can be NULL though)
|
// entry->name, entry->generic_name, entry->icon, entry->exec will never be empty strings (can be NULL though)
|
||||||
|
|
||||||
expand_exec(entry, entry->path);
|
expand_exec(entry, entry->path);
|
||||||
|
|
||||||
free(line);
|
free(line);
|
||||||
return entry->exec != NULL;
|
return entry->exec != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean read_desktop_file_from_dir(const char *path, const char *file_name, DesktopEntry *entry)
|
gboolean read_desktop_file_from_dir(const char *path, const char *file_name, DesktopEntry *entry)
|
||||||
{
|
{
|
||||||
gchar *full_path = g_build_filename(path, file_name, NULL);
|
gchar *full_path = g_build_filename(path, file_name, NULL);
|
||||||
if (read_desktop_file_full_path(full_path, entry)) {
|
if (read_desktop_file_full_path(full_path, entry)) {
|
||||||
g_free(full_path);
|
g_free(full_path);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
free_and_null(entry->name);
|
free_and_null(entry->name);
|
||||||
free_and_null(entry->generic_name);
|
free_and_null(entry->generic_name);
|
||||||
free_and_null(entry->icon);
|
free_and_null(entry->icon);
|
||||||
free_and_null(entry->exec);
|
free_and_null(entry->exec);
|
||||||
free_and_null(entry->cwd);
|
free_and_null(entry->cwd);
|
||||||
|
|
||||||
GList *subdirs = NULL;
|
GList *subdirs = NULL;
|
||||||
|
|
||||||
GDir *d = g_dir_open(path, 0, NULL);
|
GDir *d = g_dir_open(path, 0, NULL);
|
||||||
if (d) {
|
if (d) {
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
while ((name = g_dir_read_name(d))) {
|
while ((name = g_dir_read_name(d))) {
|
||||||
gchar *child = g_build_filename(path, name, NULL);
|
gchar *child = g_build_filename(path, name, NULL);
|
||||||
if (g_file_test(child, G_FILE_TEST_IS_DIR)) {
|
if (g_file_test(child, G_FILE_TEST_IS_DIR)) {
|
||||||
subdirs = g_list_append(subdirs, child);
|
subdirs = g_list_append(subdirs, child);
|
||||||
} else {
|
} else {
|
||||||
g_free(child);
|
g_free(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_dir_close(d);
|
g_dir_close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
subdirs = g_list_sort(subdirs, compare_strings);
|
subdirs = g_list_sort(subdirs, compare_strings);
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
for (GList *l = subdirs; l; l = g_list_next(l)) {
|
for (GList *l = subdirs; l; l = g_list_next(l)) {
|
||||||
if (read_desktop_file_from_dir(l->data, file_name, entry)) {
|
if (read_desktop_file_from_dir(l->data, file_name, entry)) {
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GList *l = subdirs; l; l = g_list_next(l)) {
|
for (GList *l = subdirs; l; l = g_list_next(l)) {
|
||||||
g_free(l->data);
|
g_free(l->data);
|
||||||
}
|
}
|
||||||
g_list_free(subdirs);
|
g_list_free(subdirs);
|
||||||
g_free(full_path);
|
g_free(full_path);
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean read_desktop_file(const char *path, DesktopEntry *entry)
|
gboolean read_desktop_file(const char *path, DesktopEntry *entry)
|
||||||
{
|
{
|
||||||
entry->path = strdup(path);
|
entry->path = strdup(path);
|
||||||
entry->name = entry->generic_name = entry->icon = entry->exec = entry->cwd = NULL;
|
entry->name = entry->generic_name = entry->icon = entry->exec = entry->cwd = NULL;
|
||||||
|
|
||||||
if (strchr(path, '/'))
|
if (strchr(path, '/'))
|
||||||
return read_desktop_file_full_path(path, entry);
|
return read_desktop_file_full_path(path, entry);
|
||||||
for (const GSList *location = get_apps_locations(); location; location = g_slist_next(location)) {
|
for (const GSList *location = get_apps_locations(); location; location = g_slist_next(location)) {
|
||||||
if (read_desktop_file_from_dir(location->data, path, entry))
|
if (read_desktop_file_from_dir(location->data, path, entry))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_desktop_entry(DesktopEntry *entry)
|
void free_desktop_entry(DesktopEntry *entry)
|
||||||
{
|
{
|
||||||
free_and_null(entry->name);
|
free_and_null(entry->name);
|
||||||
free_and_null(entry->generic_name);
|
free_and_null(entry->generic_name);
|
||||||
free_and_null(entry->icon);
|
free_and_null(entry->icon);
|
||||||
free_and_null(entry->exec);
|
free_and_null(entry->exec);
|
||||||
free_and_null(entry->path);
|
free_and_null(entry->path);
|
||||||
free_and_null(entry->cwd);
|
free_and_null(entry->cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_read_desktop_file()
|
void test_read_desktop_file()
|
||||||
{
|
{
|
||||||
fprintf(stdout, "\033[1;33m");
|
fprintf(stdout, "\033[1;33m");
|
||||||
DesktopEntry entry;
|
DesktopEntry entry;
|
||||||
read_desktop_file("/usr/share/applications/firefox.desktop", &entry);
|
read_desktop_file("/usr/share/applications/firefox.desktop", &entry);
|
||||||
printf("Name:%s GenericName:%s Icon:%s Exec:%s\n", entry.name, entry.generic_name, entry.icon, entry.exec);
|
printf("Name:%s GenericName:%s Icon:%s Exec:%s\n", entry.name, entry.generic_name, entry.icon, entry.exec);
|
||||||
fprintf(stdout, "\033[0m");
|
fprintf(stdout, "\033[0m");
|
||||||
}
|
}
|
||||||
|
|
||||||
GSList *apps_locations = NULL;
|
GSList *apps_locations = NULL;
|
||||||
// Do not free the result.
|
// Do not free the result.
|
||||||
const GSList *get_apps_locations()
|
const GSList *get_apps_locations()
|
||||||
{
|
{
|
||||||
if (apps_locations)
|
if (apps_locations)
|
||||||
return apps_locations;
|
return apps_locations;
|
||||||
|
|
||||||
apps_locations = load_locations_from_env(apps_locations, "XDG_DATA_HOME", "applications", NULL);
|
apps_locations = load_locations_from_env(apps_locations, "XDG_DATA_HOME", "applications", NULL);
|
||||||
|
|
||||||
apps_locations =
|
apps_locations =
|
||||||
g_slist_append(apps_locations, g_build_filename(g_get_home_dir(), ".local/share/applications", NULL));
|
g_slist_append(apps_locations, g_build_filename(g_get_home_dir(), ".local/share/applications", NULL));
|
||||||
|
|
||||||
apps_locations = load_locations_from_env(apps_locations, "XDG_DATA_DIRS", "applications", NULL);
|
apps_locations = load_locations_from_env(apps_locations, "XDG_DATA_DIRS", "applications", NULL);
|
||||||
|
|
||||||
apps_locations = g_slist_append(apps_locations, g_strdup("/usr/local/share/applications"));
|
apps_locations = g_slist_append(apps_locations, g_strdup("/usr/local/share/applications"));
|
||||||
apps_locations = g_slist_append(apps_locations, g_strdup("/usr/share/applications"));
|
apps_locations = g_slist_append(apps_locations, g_strdup("/usr/share/applications"));
|
||||||
apps_locations = g_slist_append(apps_locations, g_strdup("/opt/share/applications"));
|
apps_locations = g_slist_append(apps_locations, g_strdup("/opt/share/applications"));
|
||||||
|
|
||||||
apps_locations = slist_remove_duplicates(apps_locations, g_str_equal, g_free);
|
apps_locations = slist_remove_duplicates(apps_locations, g_str_equal, g_free);
|
||||||
|
|
||||||
return apps_locations;
|
return apps_locations;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct DesktopEntry {
|
typedef struct DesktopEntry {
|
||||||
char *name;
|
char *name;
|
||||||
char *generic_name;
|
char *generic_name;
|
||||||
char *exec;
|
char *exec;
|
||||||
char *icon;
|
char *icon;
|
||||||
char *path;
|
char *path;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
gboolean hidden_from_menus;
|
gboolean hidden_from_menus;
|
||||||
} DesktopEntry;
|
} DesktopEntry;
|
||||||
|
|
||||||
// Parses a line of the form "key = value". Modifies the line.
|
// Parses a line of the form "key = value". Modifies the line.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -10,27 +10,27 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
typedef struct IconThemeWrapper {
|
typedef struct IconThemeWrapper {
|
||||||
// The icon theme name for which this wrapper was created
|
// The icon theme name for which this wrapper was created
|
||||||
char *icon_theme_name;
|
char *icon_theme_name;
|
||||||
// List of IconTheme*
|
// List of IconTheme*
|
||||||
GSList *themes;
|
GSList *themes;
|
||||||
// Themes are loaded lazily when needed.
|
// Themes are loaded lazily when needed.
|
||||||
gboolean _themes_loaded;
|
gboolean _themes_loaded;
|
||||||
// List of IconTheme*
|
// List of IconTheme*
|
||||||
GSList *themes_fallback;
|
GSList *themes_fallback;
|
||||||
// Fallback themes are loaded lazily when needed.
|
// Fallback themes are loaded lazily when needed.
|
||||||
gboolean _fallback_loaded;
|
gboolean _fallback_loaded;
|
||||||
Cache _cache;
|
Cache _cache;
|
||||||
// List of icon theme names that have been queued for loading.
|
// List of icon theme names that have been queued for loading.
|
||||||
// Used to avoid loading the same theme twice, and to avoid cycles.
|
// Used to avoid loading the same theme twice, and to avoid cycles.
|
||||||
GSList *_queued;
|
GSList *_queued;
|
||||||
} IconThemeWrapper;
|
} IconThemeWrapper;
|
||||||
|
|
||||||
typedef struct IconTheme {
|
typedef struct IconTheme {
|
||||||
char *name;
|
char *name;
|
||||||
char *description;
|
char *description;
|
||||||
GSList *list_inherits; // each item is a char* (theme name)
|
GSList *list_inherits; // each item is a char* (theme name)
|
||||||
GSList *list_directories; // each item is an IconThemeDir*
|
GSList *list_directories; // each item is an IconThemeDir*
|
||||||
} IconTheme;
|
} IconTheme;
|
||||||
|
|
||||||
// Parses a line of the form "key = value". Modifies the line.
|
// Parses a line of the form "key = value". Modifies the line.
|
||||||
|
|||||||
@@ -67,18 +67,18 @@ int launcher_compute_desired_size(void *obj);
|
|||||||
|
|
||||||
void default_launcher()
|
void default_launcher()
|
||||||
{
|
{
|
||||||
launcher_enabled = 0;
|
launcher_enabled = 0;
|
||||||
launcher_max_icon_size = 0;
|
launcher_max_icon_size = 0;
|
||||||
launcher_tooltip_enabled = 0;
|
launcher_tooltip_enabled = 0;
|
||||||
launcher_alpha = 100;
|
launcher_alpha = 100;
|
||||||
launcher_saturation = 0;
|
launcher_saturation = 0;
|
||||||
launcher_brightness = 0;
|
launcher_brightness = 0;
|
||||||
icon_theme_name_config = NULL;
|
icon_theme_name_config = NULL;
|
||||||
icon_theme_name_xsettings = NULL;
|
icon_theme_name_xsettings = NULL;
|
||||||
launcher_icon_theme_override = 0;
|
launcher_icon_theme_override = 0;
|
||||||
startup_notifications = 0;
|
startup_notifications = 0;
|
||||||
launcher_icon_bg = NULL;
|
launcher_icon_bg = NULL;
|
||||||
launcher_icon_gradients = NULL;
|
launcher_icon_gradients = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_launcher()
|
void init_launcher()
|
||||||
@@ -87,97 +87,97 @@ void init_launcher()
|
|||||||
|
|
||||||
void init_launcher_panel(void *p)
|
void init_launcher_panel(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
Launcher *launcher = &panel->launcher;
|
Launcher *launcher = &panel->launcher;
|
||||||
|
|
||||||
launcher->area.parent = p;
|
launcher->area.parent = p;
|
||||||
launcher->area.panel = p;
|
launcher->area.panel = p;
|
||||||
snprintf(launcher->area.name, sizeof(launcher->area.name), "Launcher");
|
snprintf(launcher->area.name, sizeof(launcher->area.name), "Launcher");
|
||||||
launcher->area._draw_foreground = NULL;
|
launcher->area._draw_foreground = NULL;
|
||||||
launcher->area.size_mode = LAYOUT_FIXED;
|
launcher->area.size_mode = LAYOUT_FIXED;
|
||||||
launcher->area._resize = resize_launcher;
|
launcher->area._resize = resize_launcher;
|
||||||
launcher->area._compute_desired_size = launcher_compute_desired_size;
|
launcher->area._compute_desired_size = launcher_compute_desired_size;
|
||||||
launcher->area.resize_needed = 1;
|
launcher->area.resize_needed = 1;
|
||||||
schedule_redraw(&launcher->area);
|
schedule_redraw(&launcher->area);
|
||||||
if (!launcher->area.bg)
|
if (!launcher->area.bg)
|
||||||
launcher->area.bg = &g_array_index(backgrounds, Background, 0);
|
launcher->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
|
|
||||||
if (!launcher_icon_bg)
|
if (!launcher_icon_bg)
|
||||||
launcher_icon_bg = &g_array_index(backgrounds, Background, 0);
|
launcher_icon_bg = &g_array_index(backgrounds, Background, 0);
|
||||||
|
|
||||||
// check consistency
|
// check consistency
|
||||||
if (launcher->list_apps == NULL)
|
if (launcher->list_apps == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// This will be recomputed on resize, we just initialize to a non-zero value
|
// This will be recomputed on resize, we just initialize to a non-zero value
|
||||||
launcher->icon_size = launcher_max_icon_size > 0 ? launcher_max_icon_size : 24;
|
launcher->icon_size = launcher_max_icon_size > 0 ? launcher_max_icon_size : 24;
|
||||||
|
|
||||||
launcher->area.on_screen = TRUE;
|
launcher->area.on_screen = TRUE;
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
instantiate_area_gradients(&launcher->area);
|
instantiate_area_gradients(&launcher->area);
|
||||||
|
|
||||||
load_icon_themes();
|
load_icon_themes();
|
||||||
launcher_load_icons(launcher);
|
launcher_load_icons(launcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_icon_themes()
|
void free_icon_themes()
|
||||||
{
|
{
|
||||||
free_themes(icon_theme_wrapper);
|
free_themes(icon_theme_wrapper);
|
||||||
icon_theme_wrapper = NULL;
|
icon_theme_wrapper = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_launcher()
|
void cleanup_launcher()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
Panel *panel = &panels[i];
|
Panel *panel = &panels[i];
|
||||||
Launcher *launcher = &panel->launcher;
|
Launcher *launcher = &panel->launcher;
|
||||||
cleanup_launcher_theme(launcher);
|
cleanup_launcher_theme(launcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GSList *l = panel_config.launcher.list_apps; l; l = l->next) {
|
for (GSList *l = panel_config.launcher.list_apps; l; l = l->next) {
|
||||||
free(l->data);
|
free(l->data);
|
||||||
}
|
}
|
||||||
g_slist_free(panel_config.launcher.list_apps);
|
g_slist_free(panel_config.launcher.list_apps);
|
||||||
panel_config.launcher.list_apps = NULL;
|
panel_config.launcher.list_apps = NULL;
|
||||||
|
|
||||||
free(icon_theme_name_config);
|
free(icon_theme_name_config);
|
||||||
icon_theme_name_config = NULL;
|
icon_theme_name_config = NULL;
|
||||||
|
|
||||||
free(icon_theme_name_xsettings);
|
free(icon_theme_name_xsettings);
|
||||||
icon_theme_name_xsettings = NULL;
|
icon_theme_name_xsettings = NULL;
|
||||||
|
|
||||||
launcher_enabled = FALSE;
|
launcher_enabled = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_launcher_theme(Launcher *launcher)
|
void cleanup_launcher_theme(Launcher *launcher)
|
||||||
{
|
{
|
||||||
free_area(&launcher->area);
|
free_area(&launcher->area);
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (launcherIcon) {
|
if (launcherIcon) {
|
||||||
free_icon(launcherIcon->image);
|
free_icon(launcherIcon->image);
|
||||||
free_icon(launcherIcon->image_hover);
|
free_icon(launcherIcon->image_hover);
|
||||||
free_icon(launcherIcon->image_pressed);
|
free_icon(launcherIcon->image_pressed);
|
||||||
free(launcherIcon->icon_name);
|
free(launcherIcon->icon_name);
|
||||||
free(launcherIcon->icon_path);
|
free(launcherIcon->icon_path);
|
||||||
free(launcherIcon->cmd);
|
free(launcherIcon->cmd);
|
||||||
g_free(launcherIcon->icon_tooltip);
|
g_free(launcherIcon->icon_tooltip);
|
||||||
free(launcherIcon->config_path);
|
free(launcherIcon->config_path);
|
||||||
}
|
}
|
||||||
free(launcherIcon);
|
free(launcherIcon);
|
||||||
}
|
}
|
||||||
g_slist_free(launcher->list_icons);
|
g_slist_free(launcher->list_icons);
|
||||||
launcher->list_icons = NULL;
|
launcher->list_icons = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launcher_compute_icon_size(Launcher *launcher)
|
int launcher_compute_icon_size(Launcher *launcher)
|
||||||
{
|
{
|
||||||
int icon_size = panel_horizontal ? launcher->area.height : launcher->area.width;
|
int icon_size = panel_horizontal ? launcher->area.height : launcher->area.width;
|
||||||
icon_size = icon_size - MAX(left_right_border_width(&launcher->area), top_bottom_border_width(&launcher->area)) -
|
icon_size = icon_size - MAX(left_right_border_width(&launcher->area), top_bottom_border_width(&launcher->area)) -
|
||||||
(2 * launcher->area.paddingy);
|
(2 * launcher->area.paddingy);
|
||||||
if (launcher_max_icon_size > 0 && icon_size > launcher_max_icon_size)
|
if (launcher_max_icon_size > 0 && icon_size > launcher_max_icon_size)
|
||||||
icon_size = launcher_max_icon_size;
|
icon_size = launcher_max_icon_size;
|
||||||
return icon_size;
|
return icon_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_compute_geometry(Launcher *launcher,
|
void launcher_compute_geometry(Launcher *launcher,
|
||||||
@@ -187,438 +187,436 @@ void launcher_compute_geometry(Launcher *launcher,
|
|||||||
int *icons_per_row,
|
int *icons_per_row,
|
||||||
int *margin)
|
int *margin)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (launcherIcon->area.on_screen)
|
if (launcherIcon->area.on_screen)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*icon_size = launcher_compute_icon_size(launcher);
|
*icon_size = launcher_compute_icon_size(launcher);
|
||||||
*icons_per_column = 1;
|
*icons_per_column = 1;
|
||||||
*icons_per_row = 1;
|
*icons_per_row = 1;
|
||||||
*margin = 0;
|
*margin = 0;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (!count) {
|
if (!count) {
|
||||||
*size = 0;
|
*size = 0;
|
||||||
} else {
|
} else {
|
||||||
int height = launcher->area.height - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy;
|
int height = launcher->area.height - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy;
|
||||||
// here icons_per_column always higher than 0
|
// here icons_per_column always higher than 0
|
||||||
*icons_per_column = (height + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx);
|
*icons_per_column = (height + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx);
|
||||||
*margin = height - (*icons_per_column - 1) * (*icon_size + launcher->area.paddingx) - *icon_size;
|
*margin = height - (*icons_per_column - 1) * (*icon_size + launcher->area.paddingx) - *icon_size;
|
||||||
*icons_per_row = count / *icons_per_column + (count % *icons_per_column != 0);
|
*icons_per_row = count / *icons_per_column + (count % *icons_per_column != 0);
|
||||||
*size = left_right_border_width(&launcher->area) + 2 * launcher->area.paddingxlr +
|
*size = left_right_border_width(&launcher->area) + 2 * launcher->area.paddingxlr +
|
||||||
(*icon_size * *icons_per_row) + ((*icons_per_row - 1) * launcher->area.paddingx);
|
(*icon_size * *icons_per_row) + ((*icons_per_row - 1) * launcher->area.paddingx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!count) {
|
if (!count) {
|
||||||
*size = 0;
|
*size = 0;
|
||||||
} else {
|
} else {
|
||||||
int width = launcher->area.width - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy;
|
int width = launcher->area.width - top_bottom_border_width(&launcher->area) - 2 * launcher->area.paddingy;
|
||||||
// here icons_per_row always higher than 0
|
// here icons_per_row always higher than 0
|
||||||
*icons_per_row = (width + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx);
|
*icons_per_row = (width + launcher->area.paddingx) / (*icon_size + launcher->area.paddingx);
|
||||||
*margin = width - (*icons_per_row - 1) * (*icon_size + launcher->area.paddingx) - *icon_size;
|
*margin = width - (*icons_per_row - 1) * (*icon_size + launcher->area.paddingx) - *icon_size;
|
||||||
*icons_per_column = count / *icons_per_row + (count % *icons_per_row != 0);
|
*icons_per_column = count / *icons_per_row + (count % *icons_per_row != 0);
|
||||||
*size = top_bottom_border_width(&launcher->area) + 2 * launcher->area.paddingxlr +
|
*size = top_bottom_border_width(&launcher->area) + 2 * launcher->area.paddingxlr +
|
||||||
(*icon_size * *icons_per_column) + ((*icons_per_column - 1) * launcher->area.paddingx);
|
(*icon_size * *icons_per_column) + ((*icons_per_column - 1) * launcher->area.paddingx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int launcher_compute_desired_size(void *obj)
|
int launcher_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
Launcher *launcher = (Launcher *)obj;
|
Launcher *launcher = (Launcher *)obj;
|
||||||
|
|
||||||
int size, icon_size, icons_per_column, icons_per_row, margin;
|
int size, icon_size, icons_per_column, icons_per_row, margin;
|
||||||
launcher_compute_geometry(launcher, &size, &icon_size, &icons_per_column, &icons_per_row, &margin);
|
launcher_compute_geometry(launcher, &size, &icon_size, &icons_per_column, &icons_per_row, &margin);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_launcher(void *obj)
|
gboolean resize_launcher(void *obj)
|
||||||
{
|
{
|
||||||
Launcher *launcher = (Launcher *)obj;
|
Launcher *launcher = (Launcher *)obj;
|
||||||
|
|
||||||
int size, icons_per_column, icons_per_row, margin;
|
int size, icons_per_column, icons_per_row, margin;
|
||||||
launcher_compute_geometry(launcher, &size, &launcher->icon_size, &icons_per_column, &icons_per_row, &margin);
|
launcher_compute_geometry(launcher, &size, &launcher->icon_size, &icons_per_column, &icons_per_row, &margin);
|
||||||
|
|
||||||
// Resize icons if necessary
|
// Resize icons if necessary
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (launcherIcon->icon_size != launcher->icon_size || !launcherIcon->image) {
|
if (launcherIcon->icon_size != launcher->icon_size || !launcherIcon->image) {
|
||||||
launcherIcon->icon_size = launcher->icon_size;
|
launcherIcon->icon_size = launcher->icon_size;
|
||||||
launcherIcon->area.width = launcherIcon->icon_size;
|
launcherIcon->area.width = launcherIcon->icon_size;
|
||||||
launcherIcon->area.height = launcherIcon->icon_size;
|
launcherIcon->area.height = launcherIcon->icon_size;
|
||||||
launcher_reload_icon_image(launcher, launcherIcon);
|
launcher_reload_icon_image(launcher, launcherIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
save_icon_cache(icon_theme_wrapper);
|
save_icon_cache(icon_theme_wrapper);
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
gboolean needs_repositioning = FALSE;
|
gboolean needs_repositioning = FALSE;
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (launcherIcon->area.on_screen) {
|
if (launcherIcon->area.on_screen) {
|
||||||
count++;
|
count++;
|
||||||
if (launcherIcon->area.posx < 0 || launcherIcon->area.posy < 0)
|
if (launcherIcon->area.posx < 0 || launcherIcon->area.posy < 0)
|
||||||
needs_repositioning = TRUE;
|
needs_repositioning = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needs_repositioning) {
|
if (!needs_repositioning) {
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (launcher->area.width == size)
|
if (launcher->area.width == size)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
launcher->area.width = size;
|
launcher->area.width = size;
|
||||||
} else {
|
} else {
|
||||||
if (launcher->area.height == size)
|
if (launcher->area.height == size)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
launcher->area.height = size;
|
launcher->area.height = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int posx, posy;
|
int posx, posy;
|
||||||
int start;
|
int start;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
posy = start = top_border_width(&launcher->area) + launcher->area.paddingy + margin / 2;
|
posy = start = top_border_width(&launcher->area) + launcher->area.paddingy + margin / 2;
|
||||||
posx = left_border_width(&launcher->area) + launcher->area.paddingxlr;
|
posx = left_border_width(&launcher->area) + launcher->area.paddingxlr;
|
||||||
} else {
|
} else {
|
||||||
posx = start = left_border_width(&launcher->area) + launcher->area.paddingy + margin / 2;
|
posx = start = left_border_width(&launcher->area) + launcher->area.paddingy + margin / 2;
|
||||||
posy = top_border_width(&launcher->area) + launcher->area.paddingxlr;
|
posy = top_border_width(&launcher->area) + launcher->area.paddingxlr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (!launcherIcon->area.on_screen)
|
if (!launcherIcon->area.on_screen)
|
||||||
continue;
|
continue;
|
||||||
i++;
|
i++;
|
||||||
launcherIcon->y = posy;
|
launcherIcon->y = posy;
|
||||||
launcherIcon->x = posx;
|
launcherIcon->x = posx;
|
||||||
launcher_icon_on_change_layout(launcherIcon);
|
launcher_icon_on_change_layout(launcherIcon);
|
||||||
// printf("launcher %d : %d,%d\n", i, posx, posy);
|
// printf("launcher %d : %d,%d\n", i, posx, posy);
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (i % icons_per_column) {
|
if (i % icons_per_column) {
|
||||||
posy += launcher->icon_size + launcher->area.paddingx;
|
posy += launcher->icon_size + launcher->area.paddingx;
|
||||||
} else {
|
} else {
|
||||||
posy = start;
|
posy = start;
|
||||||
posx += (launcher->icon_size + launcher->area.paddingx);
|
posx += (launcher->icon_size + launcher->area.paddingx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (i % icons_per_row) {
|
if (i % icons_per_row) {
|
||||||
posx += launcher->icon_size + launcher->area.paddingx;
|
posx += launcher->icon_size + launcher->area.paddingx;
|
||||||
} else {
|
} else {
|
||||||
posx = start;
|
posx = start;
|
||||||
posy += (launcher->icon_size + launcher->area.paddingx);
|
posy += (launcher->icon_size + launcher->area.paddingx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((panel_horizontal && icons_per_column == 1) || (!panel_horizontal && icons_per_row == 1)) {
|
if ((panel_horizontal && icons_per_column == 1) || (!panel_horizontal && icons_per_row == 1)) {
|
||||||
launcher->area._is_under_mouse = full_width_area_is_under_mouse;
|
launcher->area._is_under_mouse = full_width_area_is_under_mouse;
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next)
|
for (GSList *l = launcher->list_icons; l; l = l->next)
|
||||||
((LauncherIcon *)l->data)->area._is_under_mouse = full_width_area_is_under_mouse;
|
((LauncherIcon *)l->data)->area._is_under_mouse = full_width_area_is_under_mouse;
|
||||||
} else {
|
} else {
|
||||||
launcher->area._is_under_mouse = NULL;
|
launcher->area._is_under_mouse = NULL;
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next)
|
for (GSList *l = launcher->list_icons; l; l = l->next)
|
||||||
((LauncherIcon *)l->data)->area._is_under_mouse = NULL;
|
((LauncherIcon *)l->data)->area._is_under_mouse = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we override the default layout of the icons; normally Area layouts its children
|
// Here we override the default layout of the icons; normally Area layouts its children
|
||||||
// in a stack; we need to layout them in a kind of table
|
// in a stack; we need to layout them in a kind of table
|
||||||
void launcher_icon_on_change_layout(void *obj)
|
void launcher_icon_on_change_layout(void *obj)
|
||||||
{
|
{
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||||
launcherIcon->area.posy = ((Area *)launcherIcon->area.parent)->posy + launcherIcon->y;
|
launcherIcon->area.posy = ((Area *)launcherIcon->area.parent)->posy + launcherIcon->y;
|
||||||
launcherIcon->area.posx = ((Area *)launcherIcon->area.parent)->posx + launcherIcon->x;
|
launcherIcon->area.posx = ((Area *)launcherIcon->area.parent)->posx + launcherIcon->x;
|
||||||
launcherIcon->area.width = launcherIcon->icon_size;
|
launcherIcon->area.width = launcherIcon->icon_size;
|
||||||
launcherIcon->area.height = launcherIcon->icon_size;
|
launcherIcon->area.height = launcherIcon->icon_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int launcher_icon_compute_desired_size(void *obj)
|
int launcher_icon_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
LauncherIcon *icon = (LauncherIcon *)obj;
|
LauncherIcon *icon = (LauncherIcon *)obj;
|
||||||
return icon->icon_size;
|
return icon->icon_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *launcher_icon_get_tooltip_text(void *obj)
|
char *launcher_icon_get_tooltip_text(void *obj)
|
||||||
{
|
{
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||||
return strdup(launcherIcon->icon_tooltip);
|
return strdup(launcherIcon->icon_tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_launcher_icon(void *obj, cairo_t *c)
|
void draw_launcher_icon(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||||
|
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
// Render
|
// Render
|
||||||
if (panel_config.mouse_effects) {
|
if (panel_config.mouse_effects) {
|
||||||
if (launcherIcon->area.mouse_state == MOUSE_OVER)
|
if (launcherIcon->area.mouse_state == MOUSE_OVER)
|
||||||
image = launcherIcon->image_hover ? launcherIcon->image_hover : launcherIcon->image;
|
image = launcherIcon->image_hover ? launcherIcon->image_hover : launcherIcon->image;
|
||||||
else if (launcherIcon->area.mouse_state == MOUSE_DOWN)
|
else if (launcherIcon->area.mouse_state == MOUSE_DOWN)
|
||||||
image = launcherIcon->image_pressed ? launcherIcon->image_pressed : launcherIcon->image;
|
image = launcherIcon->image_pressed ? launcherIcon->image_pressed : launcherIcon->image;
|
||||||
else
|
else
|
||||||
image = launcherIcon->image;
|
image = launcherIcon->image;
|
||||||
} else {
|
} else {
|
||||||
image = launcherIcon->image;
|
image = launcherIcon->image;
|
||||||
}
|
}
|
||||||
imlib_context_set_image(image);
|
imlib_context_set_image(image);
|
||||||
render_image(launcherIcon->area.pix, 0, 0);
|
render_image(launcherIcon->area.pix, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_icon_dump_geometry(void *obj, int indent)
|
void launcher_icon_dump_geometry(void *obj, int indent)
|
||||||
{
|
{
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
LauncherIcon *launcherIcon = (LauncherIcon *)obj;
|
||||||
fprintf(stderr, "%*sIcon: w = h = %d, name = %s\n", indent, "", launcherIcon->icon_size, launcherIcon->icon_name);
|
fprintf(stderr, "%*sIcon: w = h = %d, name = %s\n", indent, "", launcherIcon->icon_size, launcherIcon->icon_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Imlib_Image scale_icon(Imlib_Image original, int icon_size)
|
Imlib_Image scale_icon(Imlib_Image original, int icon_size)
|
||||||
{
|
{
|
||||||
Imlib_Image icon_scaled;
|
Imlib_Image icon_scaled;
|
||||||
if (original) {
|
if (original) {
|
||||||
imlib_context_set_image(original);
|
imlib_context_set_image(original);
|
||||||
icon_scaled = imlib_create_cropped_scaled_image(0,
|
icon_scaled = imlib_create_cropped_scaled_image(0,
|
||||||
0,
|
0,
|
||||||
imlib_image_get_width(),
|
imlib_image_get_width(),
|
||||||
imlib_image_get_height(),
|
imlib_image_get_height(),
|
||||||
icon_size,
|
icon_size,
|
||||||
icon_size);
|
icon_size);
|
||||||
|
|
||||||
imlib_context_set_image(icon_scaled);
|
imlib_context_set_image(icon_scaled);
|
||||||
imlib_image_set_has_alpha(1);
|
imlib_image_set_has_alpha(1);
|
||||||
DATA32 *data = imlib_image_get_data();
|
DATA32 *data = imlib_image_get_data();
|
||||||
adjust_asb(data,
|
adjust_asb(data,
|
||||||
icon_size,
|
icon_size,
|
||||||
icon_size,
|
icon_size,
|
||||||
launcher_alpha / 100.0,
|
launcher_alpha / 100.0,
|
||||||
launcher_saturation / 100.0,
|
launcher_saturation / 100.0,
|
||||||
launcher_brightness / 100.0);
|
launcher_brightness / 100.0);
|
||||||
imlib_image_put_back_data(data);
|
imlib_image_put_back_data(data);
|
||||||
|
|
||||||
imlib_context_set_image(icon_scaled);
|
imlib_context_set_image(icon_scaled);
|
||||||
} else {
|
} else {
|
||||||
icon_scaled = imlib_create_image(icon_size, icon_size);
|
icon_scaled = imlib_create_image(icon_size, icon_size);
|
||||||
imlib_context_set_image(icon_scaled);
|
imlib_context_set_image(icon_scaled);
|
||||||
imlib_context_set_color(255, 255, 255, 255);
|
imlib_context_set_color(255, 255, 255, 255);
|
||||||
imlib_image_fill_rectangle(0, 0, icon_size, icon_size);
|
imlib_image_fill_rectangle(0, 0, icon_size, icon_size);
|
||||||
}
|
}
|
||||||
return icon_scaled;
|
return icon_scaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_icon(Imlib_Image icon)
|
void free_icon(Imlib_Image icon)
|
||||||
{
|
{
|
||||||
if (icon) {
|
if (icon) {
|
||||||
imlib_context_set_image(icon);
|
imlib_context_set_image(icon);
|
||||||
imlib_free_image();
|
imlib_free_image();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_action(LauncherIcon *icon, XEvent *evt)
|
void launcher_action(LauncherIcon *icon, XEvent *evt)
|
||||||
{
|
{
|
||||||
launcher_reload_icon((Launcher *)icon->area.parent, icon);
|
launcher_reload_icon((Launcher *)icon->area.parent, icon);
|
||||||
launcher_reload_hidden_icons((Launcher *)icon->area.parent);
|
launcher_reload_hidden_icons((Launcher *)icon->area.parent);
|
||||||
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
|
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
|
||||||
sprintf(cmd, "(%s&)", icon->cmd);
|
sprintf(cmd, "(%s&)", icon->cmd);
|
||||||
#if HAVE_SN
|
#if HAVE_SN
|
||||||
SnLauncherContext *ctx = 0;
|
SnLauncherContext *ctx = 0;
|
||||||
Time time;
|
Time time;
|
||||||
if (startup_notifications) {
|
if (startup_notifications) {
|
||||||
ctx = sn_launcher_context_new(server.sn_display, server.screen);
|
ctx = sn_launcher_context_new(server.sn_display, server.screen);
|
||||||
sn_launcher_context_set_name(ctx, icon->icon_tooltip);
|
sn_launcher_context_set_name(ctx, icon->icon_tooltip);
|
||||||
sn_launcher_context_set_description(ctx, "Application launched from tint2");
|
sn_launcher_context_set_description(ctx, "Application launched from tint2");
|
||||||
sn_launcher_context_set_binary_name(ctx, icon->cmd);
|
sn_launcher_context_set_binary_name(ctx, icon->cmd);
|
||||||
// Get a timestamp from the X event
|
// Get a timestamp from the X event
|
||||||
if (evt->type == ButtonPress || evt->type == ButtonRelease) {
|
if (evt->type == ButtonPress || evt->type == ButtonRelease) {
|
||||||
time = evt->xbutton.time;
|
time = evt->xbutton.time;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown X event: %d\n", evt->type);
|
fprintf(stderr, "Unknown X event: %d\n", evt->type);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sn_launcher_context_initiate(ctx, "tint2", icon->cmd, time);
|
sn_launcher_context_initiate(ctx, "tint2", icon->cmd, time);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SN */
|
#endif /* HAVE_SN */
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
fprintf(stderr, "Could not fork\n");
|
fprintf(stderr, "Could not fork\n");
|
||||||
} else if (pid == 0) {
|
} else if (pid == 0) {
|
||||||
// Child process
|
// Child process
|
||||||
#if HAVE_SN
|
#if HAVE_SN
|
||||||
if (startup_notifications) {
|
if (startup_notifications) {
|
||||||
sn_launcher_context_setup_child_process(ctx);
|
sn_launcher_context_setup_child_process(ctx);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SN
|
#endif // HAVE_SN
|
||||||
// Allow children to exist after parent destruction
|
// Allow children to exist after parent destruction
|
||||||
setsid();
|
setsid();
|
||||||
// Run the command
|
// Run the command
|
||||||
if (icon->cwd)
|
if (icon->cwd)
|
||||||
chdir(icon->cwd);
|
chdir(icon->cwd);
|
||||||
execl("/bin/sh", "/bin/sh", "-c", icon->cmd, NULL);
|
execl("/bin/sh", "/bin/sh", "-c", icon->cmd, NULL);
|
||||||
fprintf(stderr, "Failed to execlp %s\n", icon->cmd);
|
fprintf(stderr, "Failed to execlp %s\n", icon->cmd);
|
||||||
#if HAVE_SN
|
#if HAVE_SN
|
||||||
if (startup_notifications) {
|
if (startup_notifications) {
|
||||||
sn_launcher_context_unref(ctx);
|
sn_launcher_context_unref(ctx);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SN
|
#endif // HAVE_SN
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
// Parent process
|
// Parent process
|
||||||
#if HAVE_SN
|
#if HAVE_SN
|
||||||
if (startup_notifications) {
|
if (startup_notifications) {
|
||||||
g_tree_insert(server.pids, GINT_TO_POINTER(pid), ctx);
|
g_tree_insert(server.pids, GINT_TO_POINTER(pid), ctx);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SN
|
#endif // HAVE_SN
|
||||||
}
|
}
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Populates the list_icons list from the list_apps list
|
// Populates the list_icons list from the list_apps list
|
||||||
void launcher_load_icons(Launcher *launcher)
|
void launcher_load_icons(Launcher *launcher)
|
||||||
{
|
{
|
||||||
// Load apps (.desktop style launcher items)
|
// Load apps (.desktop style launcher items)
|
||||||
GSList *app = launcher->list_apps;
|
GSList *app = launcher->list_apps;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (app != NULL) {
|
while (app != NULL) {
|
||||||
index++;
|
index++;
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)calloc(1, sizeof(LauncherIcon));
|
LauncherIcon *launcherIcon = (LauncherIcon *)calloc(1, sizeof(LauncherIcon));
|
||||||
launcherIcon->area.panel = launcher->area.panel;
|
launcherIcon->area.panel = launcher->area.panel;
|
||||||
launcherIcon->area._draw_foreground = draw_launcher_icon;
|
launcherIcon->area._draw_foreground = draw_launcher_icon;
|
||||||
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
launcherIcon->area.size_mode = LAYOUT_FIXED;
|
||||||
launcherIcon->area._resize = NULL;
|
launcherIcon->area._resize = NULL;
|
||||||
launcherIcon->area._compute_desired_size = launcher_icon_compute_desired_size;
|
launcherIcon->area._compute_desired_size = launcher_icon_compute_desired_size;
|
||||||
sprintf(launcherIcon->area.name, "LauncherIcon %d", index);
|
sprintf(launcherIcon->area.name, "LauncherIcon %d", index);
|
||||||
launcherIcon->area.resize_needed = 0;
|
launcherIcon->area.resize_needed = 0;
|
||||||
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
|
launcherIcon->area.has_mouse_over_effect = panel_config.mouse_effects;
|
||||||
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;
|
launcherIcon->area.has_mouse_press_effect = launcherIcon->area.has_mouse_over_effect;
|
||||||
launcherIcon->area.bg = launcher_icon_bg;
|
launcherIcon->area.bg = launcher_icon_bg;
|
||||||
launcherIcon->area.on_screen = TRUE;
|
launcherIcon->area.on_screen = TRUE;
|
||||||
launcherIcon->area.posx = -1;
|
launcherIcon->area.posx = -1;
|
||||||
launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
|
launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
|
||||||
launcherIcon->area._dump_geometry = launcher_icon_dump_geometry;
|
launcherIcon->area._dump_geometry = launcher_icon_dump_geometry;
|
||||||
if (launcher_tooltip_enabled) {
|
if (launcher_tooltip_enabled) {
|
||||||
launcherIcon->area._get_tooltip_text = launcher_icon_get_tooltip_text;
|
launcherIcon->area._get_tooltip_text = launcher_icon_get_tooltip_text;
|
||||||
} else {
|
} else {
|
||||||
launcherIcon->area._get_tooltip_text = NULL;
|
launcherIcon->area._get_tooltip_text = NULL;
|
||||||
}
|
}
|
||||||
launcherIcon->config_path = strdup(app->data);
|
launcherIcon->config_path = strdup(app->data);
|
||||||
add_area(&launcherIcon->area, (Area *)launcher);
|
add_area(&launcherIcon->area, (Area *)launcher);
|
||||||
launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
|
launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
|
||||||
launcherIcon->icon_size = launcher->icon_size;
|
launcherIcon->icon_size = launcher->icon_size;
|
||||||
launcher_reload_icon(launcher, launcherIcon);
|
launcher_reload_icon(launcher, launcherIcon);
|
||||||
instantiate_area_gradients(&launcherIcon->area);
|
instantiate_area_gradients(&launcherIcon->area);
|
||||||
app = g_slist_next(app);
|
app = g_slist_next(app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_reload_icon(Launcher *launcher, LauncherIcon *launcherIcon)
|
void launcher_reload_icon(Launcher *launcher, LauncherIcon *launcherIcon)
|
||||||
{
|
{
|
||||||
DesktopEntry entry;
|
DesktopEntry entry;
|
||||||
if (read_desktop_file(launcherIcon->config_path, &entry) && entry.exec) {
|
if (read_desktop_file(launcherIcon->config_path, &entry) && entry.exec) {
|
||||||
schedule_redraw(&launcherIcon->area);
|
schedule_redraw(&launcherIcon->area);
|
||||||
if (launcherIcon->cmd)
|
if (launcherIcon->cmd)
|
||||||
free(launcherIcon->cmd);
|
free(launcherIcon->cmd);
|
||||||
launcherIcon->cmd = strdup(entry.exec);
|
launcherIcon->cmd = strdup(entry.exec);
|
||||||
if (launcherIcon->cwd)
|
if (launcherIcon->cwd)
|
||||||
free(launcherIcon->cwd);
|
free(launcherIcon->cwd);
|
||||||
if (entry.cwd)
|
if (entry.cwd)
|
||||||
launcherIcon->cwd = strdup(entry.cwd);
|
launcherIcon->cwd = strdup(entry.cwd);
|
||||||
else
|
else
|
||||||
launcherIcon->cwd = NULL;
|
launcherIcon->cwd = NULL;
|
||||||
if (launcherIcon->icon_name)
|
if (launcherIcon->icon_name)
|
||||||
free(launcherIcon->icon_name);
|
free(launcherIcon->icon_name);
|
||||||
launcherIcon->icon_name = entry.icon ? strdup(entry.icon) : strdup(DEFAULT_ICON);
|
launcherIcon->icon_name = entry.icon ? strdup(entry.icon) : strdup(DEFAULT_ICON);
|
||||||
if (entry.name) {
|
if (entry.name) {
|
||||||
if (entry.generic_name) {
|
if (entry.generic_name) {
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s (%s)", entry.name, entry.generic_name);
|
launcherIcon->icon_tooltip = g_strdup_printf("%s (%s)", entry.name, entry.generic_name);
|
||||||
} else {
|
} else {
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.name);
|
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (entry.generic_name) {
|
if (entry.generic_name) {
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.generic_name);
|
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.generic_name);
|
||||||
} else if (entry.exec) {
|
} else if (entry.exec) {
|
||||||
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.exec);
|
launcherIcon->icon_tooltip = g_strdup_printf("%s", entry.exec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
launcher_reload_icon_image(launcher, launcherIcon);
|
launcher_reload_icon_image(launcher, launcherIcon);
|
||||||
show(&launcherIcon->area);
|
show(&launcherIcon->area);
|
||||||
} else {
|
} else {
|
||||||
hide(&launcherIcon->area);
|
hide(&launcherIcon->area);
|
||||||
}
|
}
|
||||||
free_desktop_entry(&entry);
|
free_desktop_entry(&entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_reload_hidden_icons(Launcher *launcher)
|
void launcher_reload_hidden_icons(Launcher *launcher)
|
||||||
{
|
{
|
||||||
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
for (GSList *l = launcher->list_icons; l; l = l->next) {
|
||||||
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
|
||||||
if (!launcherIcon->area.on_screen)
|
if (!launcherIcon->area.on_screen)
|
||||||
launcher_reload_icon(launcher, launcherIcon);
|
launcher_reload_icon(launcher, launcherIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon)
|
void launcher_reload_icon_image(Launcher *launcher, LauncherIcon *launcherIcon)
|
||||||
{
|
{
|
||||||
free_icon(launcherIcon->image);
|
free_icon(launcherIcon->image);
|
||||||
free_icon(launcherIcon->image_hover);
|
free_icon(launcherIcon->image_hover);
|
||||||
free_icon(launcherIcon->image_pressed);
|
free_icon(launcherIcon->image_pressed);
|
||||||
launcherIcon->image = NULL;
|
launcherIcon->image = NULL;
|
||||||
|
|
||||||
char *new_icon_path = get_icon_path(icon_theme_wrapper, launcherIcon->icon_name, launcherIcon->icon_size, TRUE);
|
char *new_icon_path = get_icon_path(icon_theme_wrapper, launcherIcon->icon_name, launcherIcon->icon_size, TRUE);
|
||||||
if (new_icon_path)
|
if (new_icon_path)
|
||||||
launcherIcon->image = load_image(new_icon_path, TRUE);
|
launcherIcon->image = load_image(new_icon_path, TRUE);
|
||||||
// On loading error, fallback to default
|
// On loading error, fallback to default
|
||||||
if (!launcherIcon->image) {
|
if (!launcherIcon->image) {
|
||||||
free(new_icon_path);
|
free(new_icon_path);
|
||||||
new_icon_path = get_icon_path(icon_theme_wrapper, DEFAULT_ICON, launcherIcon->icon_size, TRUE);
|
new_icon_path = get_icon_path(icon_theme_wrapper, DEFAULT_ICON, launcherIcon->icon_size, TRUE);
|
||||||
if (new_icon_path)
|
if (new_icon_path)
|
||||||
launcherIcon->image = load_image(new_icon_path, TRUE);
|
launcherIcon->image = load_image(new_icon_path, TRUE);
|
||||||
}
|
}
|
||||||
Imlib_Image original = launcherIcon->image;
|
Imlib_Image original = launcherIcon->image;
|
||||||
launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size);
|
launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size);
|
||||||
free_icon(original);
|
free_icon(original);
|
||||||
free(launcherIcon->icon_path);
|
free(launcherIcon->icon_path);
|
||||||
launcherIcon->icon_path = new_icon_path;
|
launcherIcon->icon_path = new_icon_path;
|
||||||
// fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
// fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path);
|
||||||
|
|
||||||
if (panel_config.mouse_effects) {
|
if (panel_config.mouse_effects) {
|
||||||
launcherIcon->image_hover = adjust_icon(launcherIcon->image,
|
launcherIcon->image_hover = adjust_icon(launcherIcon->image,
|
||||||
panel_config.mouse_over_alpha,
|
panel_config.mouse_over_alpha,
|
||||||
panel_config.mouse_over_saturation,
|
panel_config.mouse_over_saturation,
|
||||||
panel_config.mouse_over_brightness);
|
panel_config.mouse_over_brightness);
|
||||||
launcherIcon->image_pressed = adjust_icon(launcherIcon->image,
|
launcherIcon->image_pressed = adjust_icon(launcherIcon->image,
|
||||||
panel_config.mouse_pressed_alpha,
|
panel_config.mouse_pressed_alpha,
|
||||||
panel_config.mouse_pressed_saturation,
|
panel_config.mouse_pressed_saturation,
|
||||||
panel_config.mouse_pressed_brightness);
|
panel_config.mouse_pressed_brightness);
|
||||||
}
|
}
|
||||||
schedule_redraw(&launcherIcon->area);
|
schedule_redraw(&launcherIcon->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_icon_themes()
|
void load_icon_themes()
|
||||||
{
|
{
|
||||||
if (icon_theme_wrapper)
|
if (icon_theme_wrapper)
|
||||||
return;
|
return;
|
||||||
icon_theme_wrapper =
|
icon_theme_wrapper =
|
||||||
load_themes(launcher_icon_theme_override
|
load_themes(launcher_icon_theme_override
|
||||||
? (icon_theme_name_config ? icon_theme_name_config
|
? (icon_theme_name_config ? icon_theme_name_config
|
||||||
: icon_theme_name_xsettings ? icon_theme_name_xsettings : "hicolor")
|
: icon_theme_name_xsettings ? icon_theme_name_xsettings : "hicolor")
|
||||||
: (icon_theme_name_xsettings ? icon_theme_name_xsettings
|
: (icon_theme_name_xsettings ? icon_theme_name_xsettings
|
||||||
: icon_theme_name_config ? icon_theme_name_config : "hicolor"));
|
: icon_theme_name_config ? icon_theme_name_config : "hicolor"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void launcher_default_icon_theme_changed()
|
void launcher_default_icon_theme_changed()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
Launcher *launcher = &panels[i].launcher;
|
Launcher *launcher = &panels[i].launcher;
|
||||||
cleanup_launcher_theme(launcher);
|
cleanup_launcher_theme(launcher);
|
||||||
launcher_load_icons(launcher);
|
launcher_load_icons(launcher);
|
||||||
launcher->area.resize_needed = 1;
|
launcher->area.resize_needed = 1;
|
||||||
}
|
}
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,27 +17,27 @@ void load_icon_themes();
|
|||||||
void free_icon_themes();
|
void free_icon_themes();
|
||||||
|
|
||||||
typedef struct Launcher {
|
typedef struct Launcher {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
GSList *list_apps; // List of char*, each is a path to a app.desktop file
|
GSList *list_apps; // List of char*, each is a path to a app.desktop file
|
||||||
GSList *list_icons; // List of LauncherIcon*
|
GSList *list_icons; // List of LauncherIcon*
|
||||||
int icon_size;
|
int icon_size;
|
||||||
} Launcher;
|
} Launcher;
|
||||||
|
|
||||||
typedef struct LauncherIcon {
|
typedef struct LauncherIcon {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
char *config_path;
|
char *config_path;
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
Imlib_Image image_hover;
|
Imlib_Image image_hover;
|
||||||
Imlib_Image image_pressed;
|
Imlib_Image image_pressed;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char *cwd;
|
char *cwd;
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
char *icon_path;
|
char *icon_path;
|
||||||
char *icon_tooltip;
|
char *icon_tooltip;
|
||||||
int icon_size;
|
int icon_size;
|
||||||
int x, y;
|
int x, y;
|
||||||
} LauncherIcon;
|
} LauncherIcon;
|
||||||
|
|
||||||
extern gboolean launcher_enabled;
|
extern gboolean launcher_enabled;
|
||||||
|
|||||||
@@ -34,78 +34,78 @@
|
|||||||
#include "launcher.h"
|
#include "launcher.h"
|
||||||
|
|
||||||
struct _XSettingsClient {
|
struct _XSettingsClient {
|
||||||
Display *display;
|
Display *display;
|
||||||
int screen;
|
int screen;
|
||||||
XSettingsNotifyFunc notify;
|
XSettingsNotifyFunc notify;
|
||||||
XSettingsWatchFunc watch;
|
XSettingsWatchFunc watch;
|
||||||
void *cb_data;
|
void *cb_data;
|
||||||
|
|
||||||
Window manager_window;
|
Window manager_window;
|
||||||
XSettingsList *settings;
|
XSettingsList *settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
void xsettings_notify_cb(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
|
void xsettings_notify_cb(const char *name, XSettingsAction action, XSettingsSetting *setting, void *data)
|
||||||
{
|
{
|
||||||
if ((action == XSETTINGS_ACTION_NEW || action == XSETTINGS_ACTION_CHANGED) && name != NULL && setting != NULL) {
|
if ((action == XSETTINGS_ACTION_NEW || action == XSETTINGS_ACTION_CHANGED) && name != NULL && setting != NULL) {
|
||||||
if (strcmp(name, "Net/IconThemeName") == 0 && setting->type == XSETTINGS_TYPE_STRING) {
|
if (strcmp(name, "Net/IconThemeName") == 0 && setting->type == XSETTINGS_TYPE_STRING) {
|
||||||
fprintf(stderr, "xsettings: %s = %s\n", name, setting->data.v_string);
|
fprintf(stderr, "xsettings: %s = %s\n", name, setting->data.v_string);
|
||||||
if (icon_theme_name_xsettings) {
|
if (icon_theme_name_xsettings) {
|
||||||
if (strcmp(icon_theme_name_xsettings, setting->data.v_string) == 0)
|
if (strcmp(icon_theme_name_xsettings, setting->data.v_string) == 0)
|
||||||
return;
|
return;
|
||||||
free(icon_theme_name_xsettings);
|
free(icon_theme_name_xsettings);
|
||||||
}
|
}
|
||||||
icon_theme_name_xsettings = strdup(setting->data.v_string);
|
icon_theme_name_xsettings = strdup(setting->data.v_string);
|
||||||
default_icon_theme_changed();
|
default_icon_theme_changed();
|
||||||
} else if (strcmp(name, "Gtk/FontName") == 0 && setting->type == XSETTINGS_TYPE_STRING) {
|
} else if (strcmp(name, "Gtk/FontName") == 0 && setting->type == XSETTINGS_TYPE_STRING) {
|
||||||
fprintf(stderr, "xsettings: %s = %s\n", name, setting->data.v_string);
|
fprintf(stderr, "xsettings: %s = %s\n", name, setting->data.v_string);
|
||||||
if (default_font) {
|
if (default_font) {
|
||||||
if (strcmp(default_font, setting->data.v_string) == 0)
|
if (strcmp(default_font, setting->data.v_string) == 0)
|
||||||
return;
|
return;
|
||||||
free(default_font);
|
free(default_font);
|
||||||
}
|
}
|
||||||
default_font = strdup(setting->data.v_string);
|
default_font = strdup(setting->data.v_string);
|
||||||
default_font_changed();
|
default_font_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notify_changes(XSettingsClient *client, XSettingsList *old_list)
|
static void notify_changes(XSettingsClient *client, XSettingsList *old_list)
|
||||||
{
|
{
|
||||||
XSettingsList *old_iter = old_list;
|
XSettingsList *old_iter = old_list;
|
||||||
XSettingsList *new_iter = client->settings;
|
XSettingsList *new_iter = client->settings;
|
||||||
|
|
||||||
if (!client->notify)
|
if (!client->notify)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (old_iter || new_iter) {
|
while (old_iter || new_iter) {
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
if (old_iter && new_iter)
|
if (old_iter && new_iter)
|
||||||
cmp = strcmp(old_iter->setting->name, new_iter->setting->name);
|
cmp = strcmp(old_iter->setting->name, new_iter->setting->name);
|
||||||
else if (old_iter)
|
else if (old_iter)
|
||||||
cmp = -1;
|
cmp = -1;
|
||||||
else
|
else
|
||||||
cmp = 1;
|
cmp = 1;
|
||||||
|
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
client->notify(old_iter->setting->name, XSETTINGS_ACTION_DELETED, NULL, client->cb_data);
|
client->notify(old_iter->setting->name, XSETTINGS_ACTION_DELETED, NULL, client->cb_data);
|
||||||
} else if (cmp == 0) {
|
} else if (cmp == 0) {
|
||||||
if (!xsettings_setting_equal(old_iter->setting, new_iter->setting))
|
if (!xsettings_setting_equal(old_iter->setting, new_iter->setting))
|
||||||
client->notify(old_iter->setting->name, XSETTINGS_ACTION_CHANGED, new_iter->setting, client->cb_data);
|
client->notify(old_iter->setting->name, XSETTINGS_ACTION_CHANGED, new_iter->setting, client->cb_data);
|
||||||
} else {
|
} else {
|
||||||
client->notify(new_iter->setting->name, XSETTINGS_ACTION_NEW, new_iter->setting, client->cb_data);
|
client->notify(new_iter->setting->name, XSETTINGS_ACTION_NEW, new_iter->setting, client->cb_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_iter)
|
if (old_iter)
|
||||||
old_iter = old_iter->next;
|
old_iter = old_iter->next;
|
||||||
if (new_iter)
|
if (new_iter)
|
||||||
new_iter = new_iter->next;
|
new_iter = new_iter->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ignore_errors(Display *display, XErrorEvent *event)
|
static int ignore_errors(Display *display, XErrorEvent *event)
|
||||||
{
|
{
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char local_byte_order = '\0';
|
static char local_byte_order = '\0';
|
||||||
@@ -114,364 +114,364 @@ static char local_byte_order = '\0';
|
|||||||
|
|
||||||
static XSettingsResult fetch_card16(XSettingsBuffer *buffer, CARD16 *result)
|
static XSettingsResult fetch_card16(XSettingsBuffer *buffer, CARD16 *result)
|
||||||
{
|
{
|
||||||
CARD16 x;
|
CARD16 x;
|
||||||
|
|
||||||
if (BYTES_LEFT(buffer) < 2)
|
if (BYTES_LEFT(buffer) < 2)
|
||||||
return XSETTINGS_ACCESS;
|
return XSETTINGS_ACCESS;
|
||||||
|
|
||||||
x = *(CARD16 *)buffer->pos;
|
x = *(CARD16 *)buffer->pos;
|
||||||
buffer->pos += 2;
|
buffer->pos += 2;
|
||||||
|
|
||||||
if (buffer->byte_order == local_byte_order)
|
if (buffer->byte_order == local_byte_order)
|
||||||
*result = x;
|
*result = x;
|
||||||
else
|
else
|
||||||
*result = (x << 8) | (x >> 8);
|
*result = (x << 8) | (x >> 8);
|
||||||
|
|
||||||
return XSETTINGS_SUCCESS;
|
return XSETTINGS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XSettingsResult fetch_ushort(XSettingsBuffer *buffer, unsigned short *result)
|
static XSettingsResult fetch_ushort(XSettingsBuffer *buffer, unsigned short *result)
|
||||||
{
|
{
|
||||||
CARD16 x;
|
CARD16 x;
|
||||||
XSettingsResult r;
|
XSettingsResult r;
|
||||||
|
|
||||||
r = fetch_card16(buffer, &x);
|
r = fetch_card16(buffer, &x);
|
||||||
if (r == XSETTINGS_SUCCESS)
|
if (r == XSETTINGS_SUCCESS)
|
||||||
*result = x;
|
*result = x;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XSettingsResult fetch_card32(XSettingsBuffer *buffer, CARD32 *result)
|
static XSettingsResult fetch_card32(XSettingsBuffer *buffer, CARD32 *result)
|
||||||
{
|
{
|
||||||
CARD32 x;
|
CARD32 x;
|
||||||
|
|
||||||
if (BYTES_LEFT(buffer) < 4)
|
if (BYTES_LEFT(buffer) < 4)
|
||||||
return XSETTINGS_ACCESS;
|
return XSETTINGS_ACCESS;
|
||||||
|
|
||||||
x = *(CARD32 *)buffer->pos;
|
x = *(CARD32 *)buffer->pos;
|
||||||
buffer->pos += 4;
|
buffer->pos += 4;
|
||||||
|
|
||||||
if (buffer->byte_order == local_byte_order)
|
if (buffer->byte_order == local_byte_order)
|
||||||
*result = x;
|
*result = x;
|
||||||
else
|
else
|
||||||
*result = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
|
*result = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
|
||||||
|
|
||||||
return XSETTINGS_SUCCESS;
|
return XSETTINGS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XSettingsResult fetch_card8(XSettingsBuffer *buffer, CARD8 *result)
|
static XSettingsResult fetch_card8(XSettingsBuffer *buffer, CARD8 *result)
|
||||||
{
|
{
|
||||||
if (BYTES_LEFT(buffer) < 1)
|
if (BYTES_LEFT(buffer) < 1)
|
||||||
return XSETTINGS_ACCESS;
|
return XSETTINGS_ACCESS;
|
||||||
|
|
||||||
*result = *(CARD8 *)buffer->pos;
|
*result = *(CARD8 *)buffer->pos;
|
||||||
buffer->pos += 1;
|
buffer->pos += 1;
|
||||||
|
|
||||||
return XSETTINGS_SUCCESS;
|
return XSETTINGS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define XSETTINGS_PAD(n, m) ((n + m - 1) & (~(m - 1)))
|
#define XSETTINGS_PAD(n, m) ((n + m - 1) & (~(m - 1)))
|
||||||
|
|
||||||
static XSettingsList *parse_settings(unsigned char *data, size_t len)
|
static XSettingsList *parse_settings(unsigned char *data, size_t len)
|
||||||
{
|
{
|
||||||
XSettingsBuffer buffer;
|
XSettingsBuffer buffer;
|
||||||
XSettingsResult result = XSETTINGS_SUCCESS;
|
XSettingsResult result = XSETTINGS_SUCCESS;
|
||||||
XSettingsList *settings = NULL;
|
XSettingsList *settings = NULL;
|
||||||
CARD32 serial;
|
CARD32 serial;
|
||||||
CARD32 n_entries;
|
CARD32 n_entries;
|
||||||
CARD32 i;
|
CARD32 i;
|
||||||
XSettingsSetting *setting = NULL;
|
XSettingsSetting *setting = NULL;
|
||||||
|
|
||||||
local_byte_order = xsettings_byte_order();
|
local_byte_order = xsettings_byte_order();
|
||||||
|
|
||||||
buffer.byte_order = local_byte_order;
|
buffer.byte_order = local_byte_order;
|
||||||
buffer.pos = buffer.data = data;
|
buffer.pos = buffer.data = data;
|
||||||
buffer.len = len;
|
buffer.len = len;
|
||||||
|
|
||||||
result = fetch_card8(&buffer, (CARD8 *)&buffer.byte_order);
|
result = fetch_card8(&buffer, (CARD8 *)&buffer.byte_order);
|
||||||
if (buffer.byte_order != MSBFirst && buffer.byte_order != LSBFirst) {
|
if (buffer.byte_order != MSBFirst && buffer.byte_order != LSBFirst) {
|
||||||
fprintf(stderr, "Invalid byte order %x in XSETTINGS property\n", buffer.byte_order);
|
fprintf(stderr, "Invalid byte order %x in XSETTINGS property\n", buffer.byte_order);
|
||||||
result = XSETTINGS_FAILED;
|
result = XSETTINGS_FAILED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.pos += 3;
|
buffer.pos += 3;
|
||||||
|
|
||||||
result = fetch_card32(&buffer, &serial);
|
result = fetch_card32(&buffer, &serial);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
result = fetch_card32(&buffer, &n_entries);
|
result = fetch_card32(&buffer, &n_entries);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (i = 0; i < n_entries; i++) {
|
for (i = 0; i < n_entries; i++) {
|
||||||
CARD8 type;
|
CARD8 type;
|
||||||
CARD16 name_len;
|
CARD16 name_len;
|
||||||
CARD32 v_int;
|
CARD32 v_int;
|
||||||
size_t pad_len;
|
size_t pad_len;
|
||||||
|
|
||||||
result = fetch_card8(&buffer, &type);
|
result = fetch_card8(&buffer, &type);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
buffer.pos += 1;
|
buffer.pos += 1;
|
||||||
|
|
||||||
result = fetch_card16(&buffer, &name_len);
|
result = fetch_card16(&buffer, &name_len);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pad_len = XSETTINGS_PAD(name_len, 4);
|
pad_len = XSETTINGS_PAD(name_len, 4);
|
||||||
if (BYTES_LEFT(&buffer) < pad_len) {
|
if (BYTES_LEFT(&buffer) < pad_len) {
|
||||||
result = XSETTINGS_ACCESS;
|
result = XSETTINGS_ACCESS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
setting = calloc(1, sizeof *setting);
|
setting = calloc(1, sizeof *setting);
|
||||||
if (!setting) {
|
if (!setting) {
|
||||||
result = XSETTINGS_NO_MEM;
|
result = XSETTINGS_NO_MEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */
|
setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */
|
||||||
|
|
||||||
setting->name = calloc(name_len + 1, 1);
|
setting->name = calloc(name_len + 1, 1);
|
||||||
if (!setting->name) {
|
if (!setting->name) {
|
||||||
result = XSETTINGS_NO_MEM;
|
result = XSETTINGS_NO_MEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(setting->name, buffer.pos, name_len);
|
memcpy(setting->name, buffer.pos, name_len);
|
||||||
setting->name[name_len] = '\0';
|
setting->name[name_len] = '\0';
|
||||||
buffer.pos += pad_len;
|
buffer.pos += pad_len;
|
||||||
|
|
||||||
result = fetch_card32(&buffer, &v_int);
|
result = fetch_card32(&buffer, &v_int);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
setting->last_change_serial = v_int;
|
setting->last_change_serial = v_int;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case XSETTINGS_TYPE_INT:
|
case XSETTINGS_TYPE_INT:
|
||||||
result = fetch_card32(&buffer, &v_int);
|
result = fetch_card32(&buffer, &v_int);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
setting->data.v_int = (INT32)v_int;
|
setting->data.v_int = (INT32)v_int;
|
||||||
break;
|
break;
|
||||||
case XSETTINGS_TYPE_STRING:
|
case XSETTINGS_TYPE_STRING:
|
||||||
result = fetch_card32(&buffer, &v_int);
|
result = fetch_card32(&buffer, &v_int);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pad_len = XSETTINGS_PAD(v_int, 4);
|
pad_len = XSETTINGS_PAD(v_int, 4);
|
||||||
if (v_int + 1 == 0 || /* Guard against wrap-around */
|
if (v_int + 1 == 0 || /* Guard against wrap-around */
|
||||||
BYTES_LEFT(&buffer) < pad_len) {
|
BYTES_LEFT(&buffer) < pad_len) {
|
||||||
result = XSETTINGS_ACCESS;
|
result = XSETTINGS_ACCESS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
setting->data.v_string = calloc(v_int + 1, 1);
|
setting->data.v_string = calloc(v_int + 1, 1);
|
||||||
if (!setting->data.v_string) {
|
if (!setting->data.v_string) {
|
||||||
result = XSETTINGS_NO_MEM;
|
result = XSETTINGS_NO_MEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(setting->data.v_string, buffer.pos, v_int);
|
memcpy(setting->data.v_string, buffer.pos, v_int);
|
||||||
setting->data.v_string[v_int] = '\0';
|
setting->data.v_string[v_int] = '\0';
|
||||||
buffer.pos += pad_len;
|
buffer.pos += pad_len;
|
||||||
break;
|
break;
|
||||||
case XSETTINGS_TYPE_COLOR:
|
case XSETTINGS_TYPE_COLOR:
|
||||||
result = fetch_ushort(&buffer, &setting->data.v_color.red);
|
result = fetch_ushort(&buffer, &setting->data.v_color.red);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
result = fetch_ushort(&buffer, &setting->data.v_color.green);
|
result = fetch_ushort(&buffer, &setting->data.v_color.green);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
result = fetch_ushort(&buffer, &setting->data.v_color.blue);
|
result = fetch_ushort(&buffer, &setting->data.v_color.blue);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
result = fetch_ushort(&buffer, &setting->data.v_color.alpha);
|
result = fetch_ushort(&buffer, &setting->data.v_color.alpha);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Quietly ignore unknown types */
|
/* Quietly ignore unknown types */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
setting->type = type;
|
setting->type = type;
|
||||||
|
|
||||||
result = xsettings_list_insert(&settings, setting);
|
result = xsettings_list_insert(&settings, setting);
|
||||||
if (result != XSETTINGS_SUCCESS)
|
if (result != XSETTINGS_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
setting = NULL;
|
setting = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
if (result != XSETTINGS_SUCCESS) {
|
if (result != XSETTINGS_SUCCESS) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case XSETTINGS_NO_MEM:
|
case XSETTINGS_NO_MEM:
|
||||||
fprintf(stderr, "Out of memory reading XSETTINGS property\n");
|
fprintf(stderr, "Out of memory reading XSETTINGS property\n");
|
||||||
break;
|
break;
|
||||||
case XSETTINGS_ACCESS:
|
case XSETTINGS_ACCESS:
|
||||||
fprintf(stderr, "Invalid XSETTINGS property (read off end)\n");
|
fprintf(stderr, "Invalid XSETTINGS property (read off end)\n");
|
||||||
break;
|
break;
|
||||||
case XSETTINGS_DUPLICATE_ENTRY:
|
case XSETTINGS_DUPLICATE_ENTRY:
|
||||||
fprintf(stderr, "Duplicate XSETTINGS entry for '%s'\n", setting->name);
|
fprintf(stderr, "Duplicate XSETTINGS entry for '%s'\n", setting->name);
|
||||||
case XSETTINGS_FAILED:
|
case XSETTINGS_FAILED:
|
||||||
case XSETTINGS_SUCCESS:
|
case XSETTINGS_SUCCESS:
|
||||||
case XSETTINGS_NO_ENTRY:
|
case XSETTINGS_NO_ENTRY:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting)
|
if (setting)
|
||||||
xsettings_setting_free(setting);
|
xsettings_setting_free(setting);
|
||||||
|
|
||||||
xsettings_list_free(settings);
|
xsettings_list_free(settings);
|
||||||
settings = NULL;
|
settings = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_settings(XSettingsClient *client)
|
static void read_settings(XSettingsClient *client)
|
||||||
{
|
{
|
||||||
Atom type;
|
Atom type;
|
||||||
int format;
|
int format;
|
||||||
unsigned long n_items;
|
unsigned long n_items;
|
||||||
unsigned long bytes_after;
|
unsigned long bytes_after;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
int (*old_handler)(Display *, XErrorEvent *);
|
int (*old_handler)(Display *, XErrorEvent *);
|
||||||
|
|
||||||
XSettingsList *old_list = client->settings;
|
XSettingsList *old_list = client->settings;
|
||||||
client->settings = NULL;
|
client->settings = NULL;
|
||||||
|
|
||||||
old_handler = XSetErrorHandler(ignore_errors);
|
old_handler = XSetErrorHandler(ignore_errors);
|
||||||
int result = XGetWindowProperty(client->display,
|
int result = XGetWindowProperty(client->display,
|
||||||
client->manager_window,
|
client->manager_window,
|
||||||
server.atom._XSETTINGS_SETTINGS,
|
server.atom._XSETTINGS_SETTINGS,
|
||||||
0,
|
0,
|
||||||
LONG_MAX,
|
LONG_MAX,
|
||||||
False,
|
False,
|
||||||
server.atom._XSETTINGS_SETTINGS,
|
server.atom._XSETTINGS_SETTINGS,
|
||||||
&type,
|
&type,
|
||||||
&format,
|
&format,
|
||||||
&n_items,
|
&n_items,
|
||||||
&bytes_after,
|
&bytes_after,
|
||||||
&data);
|
&data);
|
||||||
XSetErrorHandler(old_handler);
|
XSetErrorHandler(old_handler);
|
||||||
|
|
||||||
if (result == Success && type == server.atom._XSETTINGS_SETTINGS) {
|
if (result == Success && type == server.atom._XSETTINGS_SETTINGS) {
|
||||||
if (format != 8) {
|
if (format != 8) {
|
||||||
fprintf(stderr, "Invalid format for XSETTINGS property %d", format);
|
fprintf(stderr, "Invalid format for XSETTINGS property %d", format);
|
||||||
} else
|
} else
|
||||||
client->settings = parse_settings(data, n_items);
|
client->settings = parse_settings(data, n_items);
|
||||||
XFree(data);
|
XFree(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_changes(client, old_list);
|
notify_changes(client, old_list);
|
||||||
xsettings_list_free(old_list);
|
xsettings_list_free(old_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_manager_window(XSettingsClient *client)
|
static void check_manager_window(XSettingsClient *client)
|
||||||
{
|
{
|
||||||
if (client->manager_window && client->watch)
|
if (client->manager_window && client->watch)
|
||||||
client->watch(client->manager_window, False, 0, client->cb_data);
|
client->watch(client->manager_window, False, 0, client->cb_data);
|
||||||
|
|
||||||
XGrabServer(client->display);
|
XGrabServer(client->display);
|
||||||
|
|
||||||
client->manager_window = XGetSelectionOwner(server.display, server.atom._XSETTINGS_SCREEN);
|
client->manager_window = XGetSelectionOwner(server.display, server.atom._XSETTINGS_SCREEN);
|
||||||
if (client->manager_window)
|
if (client->manager_window)
|
||||||
XSelectInput(server.display, client->manager_window, PropertyChangeMask | StructureNotifyMask);
|
XSelectInput(server.display, client->manager_window, PropertyChangeMask | StructureNotifyMask);
|
||||||
|
|
||||||
XUngrabServer(client->display);
|
XUngrabServer(client->display);
|
||||||
XFlush(client->display);
|
XFlush(client->display);
|
||||||
|
|
||||||
if (client->manager_window && client->watch)
|
if (client->manager_window && client->watch)
|
||||||
client->watch(client->manager_window, True, PropertyChangeMask | StructureNotifyMask, client->cb_data);
|
client->watch(client->manager_window, True, PropertyChangeMask | StructureNotifyMask, client->cb_data);
|
||||||
|
|
||||||
read_settings(client);
|
read_settings(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
XSettingsClient *xsettings_client_new(Display *display,
|
XSettingsClient *xsettings_client_new(Display *display,
|
||||||
int screen,
|
int screen,
|
||||||
XSettingsNotifyFunc notify,
|
XSettingsNotifyFunc notify,
|
||||||
XSettingsWatchFunc watch,
|
XSettingsWatchFunc watch,
|
||||||
void *cb_data)
|
void *cb_data)
|
||||||
{
|
{
|
||||||
XSettingsClient *client = calloc(1, sizeof *client);
|
XSettingsClient *client = calloc(1, sizeof *client);
|
||||||
if (!client)
|
if (!client)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
client->display = display;
|
client->display = display;
|
||||||
client->screen = screen;
|
client->screen = screen;
|
||||||
client->notify = notify;
|
client->notify = notify;
|
||||||
client->watch = watch;
|
client->watch = watch;
|
||||||
client->cb_data = cb_data;
|
client->cb_data = cb_data;
|
||||||
|
|
||||||
client->manager_window = None;
|
client->manager_window = None;
|
||||||
client->settings = NULL;
|
client->settings = NULL;
|
||||||
|
|
||||||
if (client->watch)
|
if (client->watch)
|
||||||
client->watch(RootWindow(display, screen), True, StructureNotifyMask, client->cb_data);
|
client->watch(RootWindow(display, screen), True, StructureNotifyMask, client->cb_data);
|
||||||
|
|
||||||
check_manager_window(client);
|
check_manager_window(client);
|
||||||
|
|
||||||
if (client->manager_window == None) {
|
if (client->manager_window == None) {
|
||||||
printf("No XSETTINGS manager, tint2 uses config option 'launcher_icon_theme'.\n");
|
printf("No XSETTINGS manager, tint2 uses config option 'launcher_icon_theme'.\n");
|
||||||
free(client);
|
free(client);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xsettings_client_destroy(XSettingsClient *client)
|
void xsettings_client_destroy(XSettingsClient *client)
|
||||||
{
|
{
|
||||||
if (!client)
|
if (!client)
|
||||||
return;
|
return;
|
||||||
if (client->watch)
|
if (client->watch)
|
||||||
client->watch(RootWindow(client->display, client->screen), False, 0, client->cb_data);
|
client->watch(RootWindow(client->display, client->screen), False, 0, client->cb_data);
|
||||||
if (client->manager_window && client->watch)
|
if (client->manager_window && client->watch)
|
||||||
client->watch(client->manager_window, False, 0, client->cb_data);
|
client->watch(client->manager_window, False, 0, client->cb_data);
|
||||||
|
|
||||||
xsettings_list_free(client->settings);
|
xsettings_list_free(client->settings);
|
||||||
free(client);
|
free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
XSettingsResult xsettings_client_get_setting(XSettingsClient *client, const char *name, XSettingsSetting **setting)
|
XSettingsResult xsettings_client_get_setting(XSettingsClient *client, const char *name, XSettingsSetting **setting)
|
||||||
{
|
{
|
||||||
XSettingsSetting *search = xsettings_list_lookup(client->settings, name);
|
XSettingsSetting *search = xsettings_list_lookup(client->settings, name);
|
||||||
if (search) {
|
if (search) {
|
||||||
*setting = xsettings_setting_copy(search);
|
*setting = xsettings_setting_copy(search);
|
||||||
return *setting ? XSETTINGS_SUCCESS : XSETTINGS_NO_MEM;
|
return *setting ? XSETTINGS_SUCCESS : XSETTINGS_NO_MEM;
|
||||||
} else
|
} else
|
||||||
return XSETTINGS_NO_ENTRY;
|
return XSETTINGS_NO_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev)
|
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev)
|
||||||
{
|
{
|
||||||
/* The checks here will not unlikely cause us to reread
|
/* The checks here will not unlikely cause us to reread
|
||||||
* the properties from the manager window a number of
|
* the properties from the manager window a number of
|
||||||
* times when the manager changes from A->B. But manager changes
|
* times when the manager changes from A->B. But manager changes
|
||||||
* are going to be pretty rare.
|
* are going to be pretty rare.
|
||||||
*/
|
*/
|
||||||
if (xev->xany.window == RootWindow(server.display, server.screen)) {
|
if (xev->xany.window == RootWindow(server.display, server.screen)) {
|
||||||
if (xev->xany.type == ClientMessage && xev->xclient.message_type == server.atom.MANAGER) {
|
if (xev->xany.type == ClientMessage && xev->xclient.message_type == server.atom.MANAGER) {
|
||||||
check_manager_window(client);
|
check_manager_window(client);
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
} else if (xev->xany.window == client->manager_window) {
|
} else if (xev->xany.window == client->manager_window) {
|
||||||
if (xev->xany.type == DestroyNotify) {
|
if (xev->xany.type == DestroyNotify) {
|
||||||
check_manager_window(client);
|
check_manager_window(client);
|
||||||
return True;
|
return True;
|
||||||
} else if (xev->xany.type == PropertyNotify) {
|
} else if (xev->xany.type == PropertyNotify) {
|
||||||
read_settings(client);
|
read_settings(client);
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ typedef void (*XSettingsNotifyFunc)(const char *name, XSettingsAction action, XS
|
|||||||
typedef void (*XSettingsWatchFunc)(Window window, Bool is_start, long mask, void *cb_data);
|
typedef void (*XSettingsWatchFunc)(Window window, Bool is_start, long mask, void *cb_data);
|
||||||
|
|
||||||
XSettingsClient *xsettings_client_new(Display *display,
|
XSettingsClient *xsettings_client_new(Display *display,
|
||||||
int screen,
|
int screen,
|
||||||
XSettingsNotifyFunc notify,
|
XSettingsNotifyFunc notify,
|
||||||
XSettingsWatchFunc watch,
|
XSettingsWatchFunc watch,
|
||||||
void *cb_data);
|
void *cb_data);
|
||||||
void xsettings_client_destroy(XSettingsClient *client);
|
void xsettings_client_destroy(XSettingsClient *client);
|
||||||
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev);
|
Bool xsettings_client_process_event(XSettingsClient *client, XEvent *xev);
|
||||||
|
|
||||||
|
|||||||
@@ -30,216 +30,216 @@
|
|||||||
|
|
||||||
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting)
|
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting)
|
||||||
{
|
{
|
||||||
XSettingsSetting *result;
|
XSettingsSetting *result;
|
||||||
size_t str_len;
|
size_t str_len;
|
||||||
|
|
||||||
result = calloc(1, sizeof *result);
|
result = calloc(1, sizeof *result);
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
str_len = strlen(setting->name);
|
str_len = strlen(setting->name);
|
||||||
result->name = calloc(str_len + 1, 1);
|
result->name = calloc(str_len + 1, 1);
|
||||||
if (!result->name)
|
if (!result->name)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
memcpy(result->name, setting->name, str_len + 1);
|
memcpy(result->name, setting->name, str_len + 1);
|
||||||
|
|
||||||
result->type = setting->type;
|
result->type = setting->type;
|
||||||
|
|
||||||
switch (setting->type) {
|
switch (setting->type) {
|
||||||
case XSETTINGS_TYPE_INT:
|
case XSETTINGS_TYPE_INT:
|
||||||
result->data.v_int = setting->data.v_int;
|
result->data.v_int = setting->data.v_int;
|
||||||
break;
|
break;
|
||||||
case XSETTINGS_TYPE_COLOR:
|
case XSETTINGS_TYPE_COLOR:
|
||||||
result->data.v_color = setting->data.v_color;
|
result->data.v_color = setting->data.v_color;
|
||||||
break;
|
break;
|
||||||
case XSETTINGS_TYPE_STRING:
|
case XSETTINGS_TYPE_STRING:
|
||||||
str_len = strlen(setting->data.v_string);
|
str_len = strlen(setting->data.v_string);
|
||||||
result->data.v_string = calloc(str_len + 1, 1);
|
result->data.v_string = calloc(str_len + 1, 1);
|
||||||
if (!result->data.v_string)
|
if (!result->data.v_string)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
memcpy(result->data.v_string, setting->data.v_string, str_len + 1);
|
memcpy(result->data.v_string, setting->data.v_string, str_len + 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->last_change_serial = setting->last_change_serial;
|
result->last_change_serial = setting->last_change_serial;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (result->name)
|
if (result->name)
|
||||||
free(result->name);
|
free(result->name);
|
||||||
free(result);
|
free(result);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSettingsList *xsettings_list_copy(XSettingsList *list)
|
XSettingsList *xsettings_list_copy(XSettingsList *list)
|
||||||
{
|
{
|
||||||
XSettingsList *new = NULL;
|
XSettingsList *new = NULL;
|
||||||
XSettingsList *old_iter = list;
|
XSettingsList *old_iter = list;
|
||||||
XSettingsList *new_iter = NULL;
|
XSettingsList *new_iter = NULL;
|
||||||
|
|
||||||
while (old_iter) {
|
while (old_iter) {
|
||||||
XSettingsList *new_node;
|
XSettingsList *new_node;
|
||||||
|
|
||||||
new_node = calloc(1, sizeof *new_node);
|
new_node = calloc(1, sizeof *new_node);
|
||||||
if (!new_node)
|
if (!new_node)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
new_node->setting = xsettings_setting_copy(old_iter->setting);
|
new_node->setting = xsettings_setting_copy(old_iter->setting);
|
||||||
if (!new_node->setting) {
|
if (!new_node->setting) {
|
||||||
free(new_node);
|
free(new_node);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_iter)
|
if (new_iter)
|
||||||
new_iter->next = new_node;
|
new_iter->next = new_node;
|
||||||
else
|
else
|
||||||
new = new_node;
|
new = new_node;
|
||||||
|
|
||||||
new_iter = new_node;
|
new_iter = new_node;
|
||||||
|
|
||||||
old_iter = old_iter->next;
|
old_iter = old_iter->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
xsettings_list_free(new);
|
xsettings_list_free(new);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xsettings_setting_equal(XSettingsSetting *setting_a, XSettingsSetting *setting_b)
|
int xsettings_setting_equal(XSettingsSetting *setting_a, XSettingsSetting *setting_b)
|
||||||
{
|
{
|
||||||
if (setting_a->type != setting_b->type)
|
if (setting_a->type != setting_b->type)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (strcmp(setting_a->name, setting_b->name) != 0)
|
if (strcmp(setting_a->name, setting_b->name) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (setting_a->type) {
|
switch (setting_a->type) {
|
||||||
case XSETTINGS_TYPE_INT:
|
case XSETTINGS_TYPE_INT:
|
||||||
return setting_a->data.v_int == setting_b->data.v_int;
|
return setting_a->data.v_int == setting_b->data.v_int;
|
||||||
case XSETTINGS_TYPE_COLOR:
|
case XSETTINGS_TYPE_COLOR:
|
||||||
return (setting_a->data.v_color.red == setting_b->data.v_color.red &&
|
return (setting_a->data.v_color.red == setting_b->data.v_color.red &&
|
||||||
setting_a->data.v_color.green == setting_b->data.v_color.green &&
|
setting_a->data.v_color.green == setting_b->data.v_color.green &&
|
||||||
setting_a->data.v_color.blue == setting_b->data.v_color.blue &&
|
setting_a->data.v_color.blue == setting_b->data.v_color.blue &&
|
||||||
setting_a->data.v_color.alpha == setting_b->data.v_color.alpha);
|
setting_a->data.v_color.alpha == setting_b->data.v_color.alpha);
|
||||||
case XSETTINGS_TYPE_STRING:
|
case XSETTINGS_TYPE_STRING:
|
||||||
return strcmp(setting_a->data.v_string, setting_b->data.v_string) == 0;
|
return strcmp(setting_a->data.v_string, setting_b->data.v_string) == 0;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xsettings_setting_free(XSettingsSetting *setting)
|
void xsettings_setting_free(XSettingsSetting *setting)
|
||||||
{
|
{
|
||||||
if (setting->type == XSETTINGS_TYPE_STRING)
|
if (setting->type == XSETTINGS_TYPE_STRING)
|
||||||
free(setting->data.v_string);
|
free(setting->data.v_string);
|
||||||
|
|
||||||
if (setting->name)
|
if (setting->name)
|
||||||
free(setting->name);
|
free(setting->name);
|
||||||
|
|
||||||
free(setting);
|
free(setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xsettings_list_free(XSettingsList *list)
|
void xsettings_list_free(XSettingsList *list)
|
||||||
{
|
{
|
||||||
while (list) {
|
while (list) {
|
||||||
XSettingsList *next = list->next;
|
XSettingsList *next = list->next;
|
||||||
|
|
||||||
xsettings_setting_free(list->setting);
|
xsettings_setting_free(list->setting);
|
||||||
free(list);
|
free(list);
|
||||||
|
|
||||||
list = next;
|
list = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XSettingsResult xsettings_list_insert(XSettingsList **list, XSettingsSetting *setting)
|
XSettingsResult xsettings_list_insert(XSettingsList **list, XSettingsSetting *setting)
|
||||||
{
|
{
|
||||||
XSettingsList *node;
|
XSettingsList *node;
|
||||||
XSettingsList *iter;
|
XSettingsList *iter;
|
||||||
XSettingsList *last = NULL;
|
XSettingsList *last = NULL;
|
||||||
|
|
||||||
node = calloc(1, sizeof *node);
|
node = calloc(1, sizeof *node);
|
||||||
if (!node)
|
if (!node)
|
||||||
return XSETTINGS_NO_MEM;
|
return XSETTINGS_NO_MEM;
|
||||||
node->setting = setting;
|
node->setting = setting;
|
||||||
|
|
||||||
iter = *list;
|
iter = *list;
|
||||||
while (iter) {
|
while (iter) {
|
||||||
int cmp = strcmp(setting->name, iter->setting->name);
|
int cmp = strcmp(setting->name, iter->setting->name);
|
||||||
|
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
break;
|
break;
|
||||||
else if (cmp == 0) {
|
else if (cmp == 0) {
|
||||||
free(node);
|
free(node);
|
||||||
return XSETTINGS_DUPLICATE_ENTRY;
|
return XSETTINGS_DUPLICATE_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
last = iter;
|
last = iter;
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last)
|
if (last)
|
||||||
last->next = node;
|
last->next = node;
|
||||||
else
|
else
|
||||||
*list = node;
|
*list = node;
|
||||||
|
|
||||||
node->next = iter;
|
node->next = iter;
|
||||||
|
|
||||||
return XSETTINGS_SUCCESS;
|
return XSETTINGS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSettingsResult xsettings_list_delete(XSettingsList **list, const char *name)
|
XSettingsResult xsettings_list_delete(XSettingsList **list, const char *name)
|
||||||
{
|
{
|
||||||
XSettingsList *iter;
|
XSettingsList *iter;
|
||||||
XSettingsList *last = NULL;
|
XSettingsList *last = NULL;
|
||||||
|
|
||||||
iter = *list;
|
iter = *list;
|
||||||
while (iter) {
|
while (iter) {
|
||||||
if (strcmp(name, iter->setting->name) == 0) {
|
if (strcmp(name, iter->setting->name) == 0) {
|
||||||
if (last)
|
if (last)
|
||||||
last->next = iter->next;
|
last->next = iter->next;
|
||||||
else
|
else
|
||||||
*list = iter->next;
|
*list = iter->next;
|
||||||
|
|
||||||
xsettings_setting_free(iter->setting);
|
xsettings_setting_free(iter->setting);
|
||||||
free(iter);
|
free(iter);
|
||||||
|
|
||||||
return XSETTINGS_SUCCESS;
|
return XSETTINGS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
last = iter;
|
last = iter;
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return XSETTINGS_FAILED;
|
return XSETTINGS_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSettingsSetting *xsettings_list_lookup(XSettingsList *list, const char *name)
|
XSettingsSetting *xsettings_list_lookup(XSettingsList *list, const char *name)
|
||||||
{
|
{
|
||||||
XSettingsList *iter;
|
XSettingsList *iter;
|
||||||
|
|
||||||
iter = list;
|
iter = list;
|
||||||
while (iter) {
|
while (iter) {
|
||||||
if (strcmp(name, iter->setting->name) == 0)
|
if (strcmp(name, iter->setting->name) == 0)
|
||||||
return iter->setting;
|
return iter->setting;
|
||||||
|
|
||||||
iter = iter->next;
|
iter = iter->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char xsettings_byte_order(void)
|
char xsettings_byte_order(void)
|
||||||
{
|
{
|
||||||
CARD32 myint = 0x01020304;
|
CARD32 myint = 0x01020304;
|
||||||
return (*(char *)&myint == 1) ? MSBFirst : LSBFirst;
|
return (*(char *)&myint == 1) ? MSBFirst : LSBFirst;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,48 +36,48 @@ typedef struct _XSettingsSetting XSettingsSetting;
|
|||||||
* protocol values.
|
* protocol values.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XSETTINGS_TYPE_INT = 0,
|
XSETTINGS_TYPE_INT = 0,
|
||||||
XSETTINGS_TYPE_STRING = 1,
|
XSETTINGS_TYPE_STRING = 1,
|
||||||
XSETTINGS_TYPE_COLOR = 2,
|
XSETTINGS_TYPE_COLOR = 2,
|
||||||
XSETTINGS_TYPE_NONE = 0xff
|
XSETTINGS_TYPE_NONE = 0xff
|
||||||
} XSettingsType;
|
} XSettingsType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XSETTINGS_SUCCESS,
|
XSETTINGS_SUCCESS,
|
||||||
XSETTINGS_NO_MEM,
|
XSETTINGS_NO_MEM,
|
||||||
XSETTINGS_ACCESS,
|
XSETTINGS_ACCESS,
|
||||||
XSETTINGS_FAILED,
|
XSETTINGS_FAILED,
|
||||||
XSETTINGS_NO_ENTRY,
|
XSETTINGS_NO_ENTRY,
|
||||||
XSETTINGS_DUPLICATE_ENTRY
|
XSETTINGS_DUPLICATE_ENTRY
|
||||||
} XSettingsResult;
|
} XSettingsResult;
|
||||||
|
|
||||||
struct _XSettingsBuffer {
|
struct _XSettingsBuffer {
|
||||||
char byte_order;
|
char byte_order;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
unsigned char *pos;
|
unsigned char *pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _XSettingsColor {
|
struct _XSettingsColor {
|
||||||
unsigned short red, green, blue, alpha;
|
unsigned short red, green, blue, alpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _XSettingsList {
|
struct _XSettingsList {
|
||||||
XSettingsSetting *setting;
|
XSettingsSetting *setting;
|
||||||
XSettingsList *next;
|
XSettingsList *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _XSettingsSetting {
|
struct _XSettingsSetting {
|
||||||
char *name;
|
char *name;
|
||||||
XSettingsType type;
|
XSettingsType type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int v_int;
|
int v_int;
|
||||||
char *v_string;
|
char *v_string;
|
||||||
XSettingsColor v_color;
|
XSettingsColor v_color;
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
unsigned long last_change_serial;
|
unsigned long last_change_serial;
|
||||||
};
|
};
|
||||||
|
|
||||||
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting);
|
XSettingsSetting *xsettings_setting_copy(XSettingsSetting *setting);
|
||||||
|
|||||||
1706
src/panel.c
1706
src/panel.c
File diff suppressed because it is too large
Load Diff
102
src/panel.h
102
src/panel.h
@@ -42,29 +42,29 @@ extern MouseAction mouse_tilt_right;
|
|||||||
|
|
||||||
// panel mode
|
// panel mode
|
||||||
typedef enum TaskbarMode {
|
typedef enum TaskbarMode {
|
||||||
SINGLE_DESKTOP = 0,
|
SINGLE_DESKTOP = 0,
|
||||||
MULTI_DESKTOP,
|
MULTI_DESKTOP,
|
||||||
} TaskbarMode;
|
} TaskbarMode;
|
||||||
|
|
||||||
typedef enum Layer {
|
typedef enum Layer {
|
||||||
BOTTOM_LAYER,
|
BOTTOM_LAYER,
|
||||||
NORMAL_LAYER,
|
NORMAL_LAYER,
|
||||||
TOP_LAYER,
|
TOP_LAYER,
|
||||||
} Layer;
|
} Layer;
|
||||||
|
|
||||||
// panel position
|
// panel position
|
||||||
typedef enum PanelPosition {
|
typedef enum PanelPosition {
|
||||||
LEFT = 0x01,
|
LEFT = 0x01,
|
||||||
RIGHT = 0x02,
|
RIGHT = 0x02,
|
||||||
CENTER = 0X04,
|
CENTER = 0X04,
|
||||||
TOP = 0X08,
|
TOP = 0X08,
|
||||||
BOTTOM = 0x10,
|
BOTTOM = 0x10,
|
||||||
} PanelPosition;
|
} PanelPosition;
|
||||||
|
|
||||||
typedef enum Strut {
|
typedef enum Strut {
|
||||||
STRUT_MINIMUM,
|
STRUT_MINIMUM,
|
||||||
STRUT_FOLLOW_SIZE,
|
STRUT_FOLLOW_SIZE,
|
||||||
STRUT_NONE,
|
STRUT_NONE,
|
||||||
} Strut;
|
} Strut;
|
||||||
|
|
||||||
extern TaskbarMode taskbar_mode;
|
extern TaskbarMode taskbar_mode;
|
||||||
@@ -95,54 +95,54 @@ extern gboolean debug_fps;
|
|||||||
extern gboolean debug_frames;
|
extern gboolean debug_frames;
|
||||||
|
|
||||||
typedef struct Panel {
|
typedef struct Panel {
|
||||||
Area area;
|
Area area;
|
||||||
|
|
||||||
Window main_win;
|
Window main_win;
|
||||||
Pixmap temp_pmap;
|
Pixmap temp_pmap;
|
||||||
|
|
||||||
// position relative to root window
|
// position relative to root window
|
||||||
int posx, posy;
|
int posx, posy;
|
||||||
int marginx, marginy;
|
int marginx, marginy;
|
||||||
gboolean fractional_width, fractional_height;
|
gboolean fractional_width, fractional_height;
|
||||||
int max_size;
|
int max_size;
|
||||||
int monitor;
|
int monitor;
|
||||||
int font_shadow;
|
int font_shadow;
|
||||||
gboolean mouse_effects;
|
gboolean mouse_effects;
|
||||||
// Mouse effects for icons
|
// Mouse effects for icons
|
||||||
int mouse_over_alpha;
|
int mouse_over_alpha;
|
||||||
int mouse_over_saturation;
|
int mouse_over_saturation;
|
||||||
int mouse_over_brightness;
|
int mouse_over_brightness;
|
||||||
int mouse_pressed_alpha;
|
int mouse_pressed_alpha;
|
||||||
int mouse_pressed_saturation;
|
int mouse_pressed_saturation;
|
||||||
int mouse_pressed_brightness;
|
int mouse_pressed_brightness;
|
||||||
|
|
||||||
// Per-panel parameters and states for Taskbar and Task
|
// Per-panel parameters and states for Taskbar and Task
|
||||||
GlobalTaskbar g_taskbar;
|
GlobalTaskbar g_taskbar;
|
||||||
GlobalTask g_task;
|
GlobalTask g_task;
|
||||||
|
|
||||||
// Array of Taskbar, with num_desktops items
|
// Array of Taskbar, with num_desktops items
|
||||||
Taskbar *taskbar;
|
Taskbar *taskbar;
|
||||||
int num_desktops;
|
int num_desktops;
|
||||||
gboolean taskbarname_has_font;
|
gboolean taskbarname_has_font;
|
||||||
PangoFontDescription *taskbarname_font_desc;
|
PangoFontDescription *taskbarname_font_desc;
|
||||||
|
|
||||||
Clock clock;
|
Clock clock;
|
||||||
|
|
||||||
#ifdef ENABLE_BATTERY
|
#ifdef ENABLE_BATTERY
|
||||||
Battery battery;
|
Battery battery;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Launcher launcher;
|
Launcher launcher;
|
||||||
GList *freespace_list;
|
GList *freespace_list;
|
||||||
GList *separator_list;
|
GList *separator_list;
|
||||||
GList *execp_list;
|
GList *execp_list;
|
||||||
GList *button_list;
|
GList *button_list;
|
||||||
|
|
||||||
// Autohide
|
// Autohide
|
||||||
gboolean is_hidden;
|
gboolean is_hidden;
|
||||||
int hidden_width, hidden_height;
|
int hidden_width, hidden_height;
|
||||||
Pixmap hidden_pixmap;
|
Pixmap hidden_pixmap;
|
||||||
timeout *autohide_timeout;
|
timeout *autohide_timeout;
|
||||||
} Panel;
|
} Panel;
|
||||||
|
|
||||||
extern Panel panel_config;
|
extern Panel panel_config;
|
||||||
|
|||||||
@@ -19,132 +19,132 @@ int separator_compute_desired_size(void *obj);
|
|||||||
|
|
||||||
Separator *create_separator()
|
Separator *create_separator()
|
||||||
{
|
{
|
||||||
Separator *separator = (Separator *)calloc(1, sizeof(Separator));
|
Separator *separator = (Separator *)calloc(1, sizeof(Separator));
|
||||||
separator->color.rgb[0] = 0.5;
|
separator->color.rgb[0] = 0.5;
|
||||||
separator->color.rgb[1] = 0.5;
|
separator->color.rgb[1] = 0.5;
|
||||||
separator->color.rgb[2] = 0.5;
|
separator->color.rgb[2] = 0.5;
|
||||||
separator->color.alpha = 0.9;
|
separator->color.alpha = 0.9;
|
||||||
separator->style = SEPARATOR_DOTS;
|
separator->style = SEPARATOR_DOTS;
|
||||||
separator->thickness = 3;
|
separator->thickness = 3;
|
||||||
separator->area.paddingxlr = 1;
|
separator->area.paddingxlr = 1;
|
||||||
return separator;
|
return separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_separator(void *obj)
|
void destroy_separator(void *obj)
|
||||||
{
|
{
|
||||||
Separator *separator = (Separator *)obj;
|
Separator *separator = (Separator *)obj;
|
||||||
remove_area(&separator->area);
|
remove_area(&separator->area);
|
||||||
free_area(&separator->area);
|
free_area(&separator->area);
|
||||||
free_and_null(separator);
|
free_and_null(separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer copy_separator(gconstpointer arg, gpointer data)
|
gpointer copy_separator(gconstpointer arg, gpointer data)
|
||||||
{
|
{
|
||||||
Separator *old = (Separator *)arg;
|
Separator *old = (Separator *)arg;
|
||||||
Separator *copy = (Separator *)calloc(1, sizeof(Separator));
|
Separator *copy = (Separator *)calloc(1, sizeof(Separator));
|
||||||
memcpy(copy, old, sizeof(Separator));
|
memcpy(copy, old, sizeof(Separator));
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_separator()
|
void init_separator()
|
||||||
{
|
{
|
||||||
GList *to_remove = panel_config.separator_list;
|
GList *to_remove = panel_config.separator_list;
|
||||||
for (int k = 0; k < strlen(panel_items_order) && to_remove; k++) {
|
for (int k = 0; k < strlen(panel_items_order) && to_remove; k++) {
|
||||||
if (panel_items_order[k] == ':') {
|
if (panel_items_order[k] == ':') {
|
||||||
to_remove = to_remove->next;
|
to_remove = to_remove->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_remove) {
|
if (to_remove) {
|
||||||
if (to_remove == panel_config.separator_list) {
|
if (to_remove == panel_config.separator_list) {
|
||||||
g_list_free_full(to_remove, destroy_separator);
|
g_list_free_full(to_remove, destroy_separator);
|
||||||
panel_config.separator_list = NULL;
|
panel_config.separator_list = NULL;
|
||||||
} else {
|
} else {
|
||||||
// Cut panel_config.separator_list
|
// Cut panel_config.separator_list
|
||||||
if (to_remove->prev)
|
if (to_remove->prev)
|
||||||
to_remove->prev->next = NULL;
|
to_remove->prev->next = NULL;
|
||||||
to_remove->prev = NULL;
|
to_remove->prev = NULL;
|
||||||
// Remove all elements of to_remove and to_remove itself
|
// Remove all elements of to_remove and to_remove itself
|
||||||
g_list_free_full(to_remove, destroy_separator);
|
g_list_free_full(to_remove, destroy_separator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_separator_panel(void *p)
|
void init_separator_panel(void *p)
|
||||||
{
|
{
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
|
|
||||||
// Make sure this is only done once if there are multiple items
|
// Make sure this is only done once if there are multiple items
|
||||||
if (panel->separator_list)
|
if (panel->separator_list)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// panel->separator_list is now a copy of the pointer panel_config.separator_list
|
// panel->separator_list is now a copy of the pointer panel_config.separator_list
|
||||||
// We make it a deep copy
|
// We make it a deep copy
|
||||||
panel->separator_list = g_list_copy_deep(panel_config.separator_list, copy_separator, NULL);
|
panel->separator_list = g_list_copy_deep(panel_config.separator_list, copy_separator, NULL);
|
||||||
|
|
||||||
for (GList *l = panel->separator_list; l; l = l->next) {
|
for (GList *l = panel->separator_list; l; l = l->next) {
|
||||||
Separator *separator = (Separator *)l->data;
|
Separator *separator = (Separator *)l->data;
|
||||||
if (!separator->area.bg)
|
if (!separator->area.bg)
|
||||||
separator->area.bg = &g_array_index(backgrounds, Background, 0);
|
separator->area.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
separator->area.parent = p;
|
separator->area.parent = p;
|
||||||
separator->area.panel = p;
|
separator->area.panel = p;
|
||||||
snprintf(separator->area.name, sizeof(separator->area.name), "separator");
|
snprintf(separator->area.name, sizeof(separator->area.name), "separator");
|
||||||
separator->area.size_mode = LAYOUT_FIXED;
|
separator->area.size_mode = LAYOUT_FIXED;
|
||||||
separator->area.resize_needed = 1;
|
separator->area.resize_needed = 1;
|
||||||
separator->area.on_screen = TRUE;
|
separator->area.on_screen = TRUE;
|
||||||
separator->area._resize = resize_separator;
|
separator->area._resize = resize_separator;
|
||||||
separator->area._compute_desired_size = separator_compute_desired_size;
|
separator->area._compute_desired_size = separator_compute_desired_size;
|
||||||
separator->area._draw_foreground = draw_separator;
|
separator->area._draw_foreground = draw_separator;
|
||||||
instantiate_area_gradients(&separator->area);
|
instantiate_area_gradients(&separator->area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_separator()
|
void cleanup_separator()
|
||||||
{
|
{
|
||||||
// Cleanup frontends
|
// Cleanup frontends
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
g_list_free_full(panels[i].separator_list, destroy_separator);
|
g_list_free_full(panels[i].separator_list, destroy_separator);
|
||||||
panels[i].separator_list = NULL;
|
panels[i].separator_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup backends
|
// Cleanup backends
|
||||||
g_list_free_full(panel_config.separator_list, destroy_separator);
|
g_list_free_full(panel_config.separator_list, destroy_separator);
|
||||||
panel_config.separator_list = NULL;
|
panel_config.separator_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int separator_compute_desired_size(void *obj)
|
int separator_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
Separator *separator = (Separator *)obj;
|
Separator *separator = (Separator *)obj;
|
||||||
if (!separator->area.on_screen)
|
if (!separator->area.on_screen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (panel_horizontal)
|
if (panel_horizontal)
|
||||||
return separator->thickness + 2 * separator->area.paddingxlr + left_right_border_width(&separator->area);
|
return separator->thickness + 2 * separator->area.paddingxlr + left_right_border_width(&separator->area);
|
||||||
else
|
else
|
||||||
return separator->thickness + 2 * separator->area.paddingxlr + top_bottom_border_width(&separator->area);
|
return separator->thickness + 2 * separator->area.paddingxlr + top_bottom_border_width(&separator->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_separator(void *obj)
|
gboolean resize_separator(void *obj)
|
||||||
{
|
{
|
||||||
Separator *separator = (Separator *)obj;
|
Separator *separator = (Separator *)obj;
|
||||||
if (!separator->area.on_screen)
|
if (!separator->area.on_screen)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
separator->area.width =
|
separator->area.width =
|
||||||
separator->thickness + 2 * separator->area.paddingxlr + left_right_border_width(&separator->area);
|
separator->thickness + 2 * separator->area.paddingxlr + left_right_border_width(&separator->area);
|
||||||
separator->length =
|
separator->length =
|
||||||
separator->area.height - 2 * separator->area.paddingy - top_bottom_border_width(&separator->area);
|
separator->area.height - 2 * separator->area.paddingy - top_bottom_border_width(&separator->area);
|
||||||
} else {
|
} else {
|
||||||
separator->area.height =
|
separator->area.height =
|
||||||
separator->thickness + 2 * separator->area.paddingxlr + top_bottom_border_width(&separator->area);
|
separator->thickness + 2 * separator->area.paddingxlr + top_bottom_border_width(&separator->area);
|
||||||
separator->length =
|
separator->length =
|
||||||
separator->area.width - 2 * separator->area.paddingy - left_right_border_width(&separator->area);
|
separator->area.width - 2 * separator->area.paddingy - left_right_border_width(&separator->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_redraw(&separator->area);
|
schedule_redraw(&separator->area);
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_separator_line(void *obj, cairo_t *c);
|
void draw_separator_line(void *obj, cairo_t *c);
|
||||||
@@ -152,80 +152,80 @@ void draw_separator_dots(void *obj, cairo_t *c);
|
|||||||
|
|
||||||
void draw_separator(void *obj, cairo_t *c)
|
void draw_separator(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
Separator *separator = (Separator *)obj;
|
Separator *separator = (Separator *)obj;
|
||||||
|
|
||||||
if (separator->style == SEPARATOR_EMPTY)
|
if (separator->style == SEPARATOR_EMPTY)
|
||||||
return;
|
return;
|
||||||
else if (separator->style == SEPARATOR_LINE)
|
else if (separator->style == SEPARATOR_LINE)
|
||||||
draw_separator_line(separator, c);
|
draw_separator_line(separator, c);
|
||||||
else if (separator->style == SEPARATOR_DOTS)
|
else if (separator->style == SEPARATOR_DOTS)
|
||||||
draw_separator_dots(separator, c);
|
draw_separator_dots(separator, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_separator_line(void *obj, cairo_t *c)
|
void draw_separator_line(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
Separator *separator = (Separator *)obj;
|
Separator *separator = (Separator *)obj;
|
||||||
|
|
||||||
if (separator->thickness <= 0)
|
if (separator->thickness <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cairo_set_source_rgba(c,
|
cairo_set_source_rgba(c,
|
||||||
separator->color.rgb[0],
|
separator->color.rgb[0],
|
||||||
separator->color.rgb[1],
|
separator->color.rgb[1],
|
||||||
separator->color.rgb[2],
|
separator->color.rgb[2],
|
||||||
separator->color.alpha);
|
separator->color.alpha);
|
||||||
cairo_set_line_width(c, separator->thickness);
|
cairo_set_line_width(c, separator->thickness);
|
||||||
cairo_set_line_cap(c, CAIRO_LINE_CAP_ROUND);
|
cairo_set_line_cap(c, CAIRO_LINE_CAP_ROUND);
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
cairo_move_to(c, separator->area.width / 2.0, separator->area.height / 2.0 - separator->length / 2.0);
|
cairo_move_to(c, separator->area.width / 2.0, separator->area.height / 2.0 - separator->length / 2.0);
|
||||||
cairo_line_to(c, separator->area.width / 2.0, separator->area.height / 2.0 + separator->length / 2.0);
|
cairo_line_to(c, separator->area.width / 2.0, separator->area.height / 2.0 + separator->length / 2.0);
|
||||||
} else {
|
} else {
|
||||||
cairo_move_to(c, separator->area.width / 2.0 - separator->length / 2.0, separator->area.height / 2.0);
|
cairo_move_to(c, separator->area.width / 2.0 - separator->length / 2.0, separator->area.height / 2.0);
|
||||||
cairo_line_to(c, separator->area.width / 2.0 + separator->length / 2.0, separator->area.height / 2.0);
|
cairo_line_to(c, separator->area.width / 2.0 + separator->length / 2.0, separator->area.height / 2.0);
|
||||||
}
|
}
|
||||||
cairo_stroke(c);
|
cairo_stroke(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_separator_dots(void *obj, cairo_t *c)
|
void draw_separator_dots(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
const double PI = 3.14159265359;
|
const double PI = 3.14159265359;
|
||||||
Separator *separator = (Separator *)obj;
|
Separator *separator = (Separator *)obj;
|
||||||
if (separator->thickness <= 0)
|
if (separator->thickness <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cairo_set_source_rgba(c,
|
cairo_set_source_rgba(c,
|
||||||
separator->color.rgb[0],
|
separator->color.rgb[0],
|
||||||
separator->color.rgb[1],
|
separator->color.rgb[1],
|
||||||
separator->color.rgb[2],
|
separator->color.rgb[2],
|
||||||
separator->color.alpha);
|
separator->color.alpha);
|
||||||
cairo_set_line_width(c, 0);
|
cairo_set_line_width(c, 0);
|
||||||
|
|
||||||
int num_circles = separator->length / (1.618 * separator->thickness - 1);
|
int num_circles = separator->length / (1.618 * separator->thickness - 1);
|
||||||
double spacing = (separator->length - num_circles * separator->thickness) / MAX(1.0, num_circles - 1.0);
|
double spacing = (separator->length - num_circles * separator->thickness) / MAX(1.0, num_circles - 1.0);
|
||||||
if (spacing > separator->thickness)
|
if (spacing > separator->thickness)
|
||||||
num_circles++;
|
num_circles++;
|
||||||
spacing = (separator->length - num_circles * separator->thickness) / MAX(1.0, num_circles - 1.0);
|
spacing = (separator->length - num_circles * separator->thickness) / MAX(1.0, num_circles - 1.0);
|
||||||
double offset = (panel_horizontal ? separator->area.height : separator->area.width) / 2.0 - separator->length / 2.0;
|
double offset = (panel_horizontal ? separator->area.height : separator->area.width) / 2.0 - separator->length / 2.0;
|
||||||
if (num_circles == 1)
|
if (num_circles == 1)
|
||||||
offset += spacing / 2.0;
|
offset += spacing / 2.0;
|
||||||
for (int i = 0; i < num_circles; i++) {
|
for (int i = 0; i < num_circles; i++) {
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
cairo_arc(c,
|
cairo_arc(c,
|
||||||
separator->area.width / 2.0,
|
separator->area.width / 2.0,
|
||||||
offset + separator->thickness / 2.0,
|
offset + separator->thickness / 2.0,
|
||||||
separator->thickness / 2.0,
|
separator->thickness / 2.0,
|
||||||
0,
|
0,
|
||||||
2 * PI);
|
2 * PI);
|
||||||
} else {
|
} else {
|
||||||
cairo_arc(c,
|
cairo_arc(c,
|
||||||
offset + separator->thickness / 2.0,
|
offset + separator->thickness / 2.0,
|
||||||
separator->area.height / 2.0,
|
separator->area.height / 2.0,
|
||||||
separator->thickness / 2.0,
|
separator->thickness / 2.0,
|
||||||
0,
|
0,
|
||||||
2 * PI);
|
2 * PI);
|
||||||
}
|
}
|
||||||
cairo_stroke_preserve(c);
|
cairo_stroke_preserve(c);
|
||||||
cairo_fill(c);
|
cairo_fill(c);
|
||||||
offset += separator->thickness + spacing;
|
offset += separator->thickness + spacing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,14 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
|
||||||
typedef enum SeparatorStyle {
|
typedef enum SeparatorStyle { SEPARATOR_EMPTY = 0, SEPARATOR_LINE, SEPARATOR_DOTS } SeparatorStyle;
|
||||||
SEPARATOR_EMPTY = 0,
|
|
||||||
SEPARATOR_LINE,
|
|
||||||
SEPARATOR_DOTS
|
|
||||||
} SeparatorStyle;
|
|
||||||
|
|
||||||
typedef struct Separator {
|
typedef struct Separator {
|
||||||
Area area;
|
Area area;
|
||||||
SeparatorStyle style;
|
SeparatorStyle style;
|
||||||
Color color;
|
Color color;
|
||||||
int thickness;
|
int thickness;
|
||||||
int length;
|
int length;
|
||||||
} Separator;
|
} Separator;
|
||||||
|
|
||||||
Separator *create_separator();
|
Separator *create_separator();
|
||||||
|
|||||||
916
src/server.c
916
src/server.c
File diff suppressed because it is too large
Load Diff
214
src/server.h
214
src/server.h
@@ -21,123 +21,123 @@
|
|||||||
extern gboolean primary_monitor_first;
|
extern gboolean primary_monitor_first;
|
||||||
|
|
||||||
typedef struct Global_atom {
|
typedef struct Global_atom {
|
||||||
Atom _XROOTPMAP_ID;
|
Atom _XROOTPMAP_ID;
|
||||||
Atom _XROOTMAP_ID;
|
Atom _XROOTMAP_ID;
|
||||||
Atom _NET_CURRENT_DESKTOP;
|
Atom _NET_CURRENT_DESKTOP;
|
||||||
Atom _NET_NUMBER_OF_DESKTOPS;
|
Atom _NET_NUMBER_OF_DESKTOPS;
|
||||||
Atom _NET_DESKTOP_NAMES;
|
Atom _NET_DESKTOP_NAMES;
|
||||||
Atom _NET_DESKTOP_GEOMETRY;
|
Atom _NET_DESKTOP_GEOMETRY;
|
||||||
Atom _NET_DESKTOP_VIEWPORT;
|
Atom _NET_DESKTOP_VIEWPORT;
|
||||||
Atom _NET_WORKAREA;
|
Atom _NET_WORKAREA;
|
||||||
Atom _NET_ACTIVE_WINDOW;
|
Atom _NET_ACTIVE_WINDOW;
|
||||||
Atom _NET_WM_WINDOW_TYPE;
|
Atom _NET_WM_WINDOW_TYPE;
|
||||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||||
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
||||||
Atom _NET_WM_STATE_STICKY;
|
Atom _NET_WM_STATE_STICKY;
|
||||||
Atom _NET_WM_STATE_DEMANDS_ATTENTION;
|
Atom _NET_WM_STATE_DEMANDS_ATTENTION;
|
||||||
Atom _NET_WM_WINDOW_TYPE_DOCK;
|
Atom _NET_WM_WINDOW_TYPE_DOCK;
|
||||||
Atom _NET_WM_WINDOW_TYPE_DESKTOP;
|
Atom _NET_WM_WINDOW_TYPE_DESKTOP;
|
||||||
Atom _NET_WM_WINDOW_TYPE_TOOLBAR;
|
Atom _NET_WM_WINDOW_TYPE_TOOLBAR;
|
||||||
Atom _NET_WM_WINDOW_TYPE_MENU;
|
Atom _NET_WM_WINDOW_TYPE_MENU;
|
||||||
Atom _NET_WM_WINDOW_TYPE_SPLASH;
|
Atom _NET_WM_WINDOW_TYPE_SPLASH;
|
||||||
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
||||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
Atom _NET_WM_DESKTOP;
|
Atom _NET_WM_DESKTOP;
|
||||||
Atom WM_STATE;
|
Atom WM_STATE;
|
||||||
Atom _NET_WM_STATE;
|
Atom _NET_WM_STATE;
|
||||||
Atom _NET_WM_STATE_MAXIMIZED_VERT;
|
Atom _NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
|
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
Atom _NET_WM_STATE_SHADED;
|
Atom _NET_WM_STATE_SHADED;
|
||||||
Atom _NET_WM_STATE_HIDDEN;
|
Atom _NET_WM_STATE_HIDDEN;
|
||||||
Atom _NET_WM_STATE_BELOW;
|
Atom _NET_WM_STATE_BELOW;
|
||||||
Atom _NET_WM_STATE_ABOVE;
|
Atom _NET_WM_STATE_ABOVE;
|
||||||
Atom _NET_WM_STATE_MODAL;
|
Atom _NET_WM_STATE_MODAL;
|
||||||
Atom _NET_CLIENT_LIST;
|
Atom _NET_CLIENT_LIST;
|
||||||
Atom _NET_WM_NAME;
|
Atom _NET_WM_NAME;
|
||||||
Atom _NET_WM_VISIBLE_NAME;
|
Atom _NET_WM_VISIBLE_NAME;
|
||||||
Atom _NET_WM_STRUT;
|
Atom _NET_WM_STRUT;
|
||||||
Atom _NET_WM_ICON;
|
Atom _NET_WM_ICON;
|
||||||
Atom _NET_WM_ICON_GEOMETRY;
|
Atom _NET_WM_ICON_GEOMETRY;
|
||||||
Atom _NET_WM_ICON_NAME;
|
Atom _NET_WM_ICON_NAME;
|
||||||
Atom _NET_CLOSE_WINDOW;
|
Atom _NET_CLOSE_WINDOW;
|
||||||
Atom UTF8_STRING;
|
Atom UTF8_STRING;
|
||||||
Atom _NET_SUPPORTING_WM_CHECK;
|
Atom _NET_SUPPORTING_WM_CHECK;
|
||||||
Atom _NET_WM_CM_S0;
|
Atom _NET_WM_CM_S0;
|
||||||
Atom _NET_WM_STRUT_PARTIAL;
|
Atom _NET_WM_STRUT_PARTIAL;
|
||||||
Atom WM_NAME;
|
Atom WM_NAME;
|
||||||
Atom __SWM_VROOT;
|
Atom __SWM_VROOT;
|
||||||
Atom _MOTIF_WM_HINTS;
|
Atom _MOTIF_WM_HINTS;
|
||||||
Atom WM_HINTS;
|
Atom WM_HINTS;
|
||||||
Atom _NET_SYSTEM_TRAY_SCREEN;
|
Atom _NET_SYSTEM_TRAY_SCREEN;
|
||||||
Atom _NET_SYSTEM_TRAY_OPCODE;
|
Atom _NET_SYSTEM_TRAY_OPCODE;
|
||||||
Atom MANAGER;
|
Atom MANAGER;
|
||||||
Atom _NET_SYSTEM_TRAY_MESSAGE_DATA;
|
Atom _NET_SYSTEM_TRAY_MESSAGE_DATA;
|
||||||
Atom _NET_SYSTEM_TRAY_ORIENTATION;
|
Atom _NET_SYSTEM_TRAY_ORIENTATION;
|
||||||
Atom _NET_SYSTEM_TRAY_ICON_SIZE;
|
Atom _NET_SYSTEM_TRAY_ICON_SIZE;
|
||||||
Atom _NET_SYSTEM_TRAY_PADDING;
|
Atom _NET_SYSTEM_TRAY_PADDING;
|
||||||
Atom _XEMBED;
|
Atom _XEMBED;
|
||||||
Atom _XEMBED_INFO;
|
Atom _XEMBED_INFO;
|
||||||
Atom _NET_WM_PID;
|
Atom _NET_WM_PID;
|
||||||
Atom _XSETTINGS_SCREEN;
|
Atom _XSETTINGS_SCREEN;
|
||||||
Atom _XSETTINGS_SETTINGS;
|
Atom _XSETTINGS_SETTINGS;
|
||||||
Atom XdndAware;
|
Atom XdndAware;
|
||||||
Atom XdndEnter;
|
Atom XdndEnter;
|
||||||
Atom XdndPosition;
|
Atom XdndPosition;
|
||||||
Atom XdndStatus;
|
Atom XdndStatus;
|
||||||
Atom XdndDrop;
|
Atom XdndDrop;
|
||||||
Atom XdndLeave;
|
Atom XdndLeave;
|
||||||
Atom XdndSelection;
|
Atom XdndSelection;
|
||||||
Atom XdndTypeList;
|
Atom XdndTypeList;
|
||||||
Atom XdndActionCopy;
|
Atom XdndActionCopy;
|
||||||
Atom XdndFinished;
|
Atom XdndFinished;
|
||||||
Atom TARGETS;
|
Atom TARGETS;
|
||||||
} Global_atom;
|
} Global_atom;
|
||||||
|
|
||||||
typedef struct Monitor {
|
typedef struct Monitor {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
gboolean primary;
|
gboolean primary;
|
||||||
gchar **names;
|
gchar **names;
|
||||||
} Monitor;
|
} Monitor;
|
||||||
|
|
||||||
typedef struct Viewport {
|
typedef struct Viewport {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
} Viewport;
|
} Viewport;
|
||||||
|
|
||||||
typedef struct Server {
|
typedef struct Server {
|
||||||
Display *display;
|
Display *display;
|
||||||
Window root_win;
|
Window root_win;
|
||||||
Window composite_manager;
|
Window composite_manager;
|
||||||
gboolean real_transparency;
|
gboolean real_transparency;
|
||||||
gboolean disable_transparency;
|
gboolean disable_transparency;
|
||||||
// current desktop
|
// current desktop
|
||||||
int desktop;
|
int desktop;
|
||||||
int screen;
|
int screen;
|
||||||
int depth;
|
int depth;
|
||||||
int num_desktops;
|
int num_desktops;
|
||||||
// number of monitor (without monitor included into another one)
|
// number of monitor (without monitor included into another one)
|
||||||
int num_monitors;
|
int num_monitors;
|
||||||
// Non-null only if WM uses viewports (compiz) and number of viewports > 1.
|
// Non-null only if WM uses viewports (compiz) and number of viewports > 1.
|
||||||
// In that case there are num_desktops viewports.
|
// In that case there are num_desktops viewports.
|
||||||
Viewport *viewports;
|
Viewport *viewports;
|
||||||
Monitor *monitors;
|
Monitor *monitors;
|
||||||
gboolean got_root_win;
|
gboolean got_root_win;
|
||||||
Visual *visual;
|
Visual *visual;
|
||||||
Visual *visual32;
|
Visual *visual32;
|
||||||
// root background
|
// root background
|
||||||
Pixmap root_pmap;
|
Pixmap root_pmap;
|
||||||
GC gc;
|
GC gc;
|
||||||
Colormap colormap;
|
Colormap colormap;
|
||||||
Colormap colormap32;
|
Colormap colormap32;
|
||||||
Global_atom atom;
|
Global_atom atom;
|
||||||
#ifdef HAVE_SN
|
#ifdef HAVE_SN
|
||||||
SnDisplay *sn_display;
|
SnDisplay *sn_display;
|
||||||
GTree *pids;
|
GTree *pids;
|
||||||
#endif // HAVE_SN
|
#endif // HAVE_SN
|
||||||
} Server;
|
} Server;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,50 +21,50 @@
|
|||||||
#define XEMBED_MAPPED (1 << 0)
|
#define XEMBED_MAPPED (1 << 0)
|
||||||
|
|
||||||
typedef enum SystraySortMethod {
|
typedef enum SystraySortMethod {
|
||||||
SYSTRAY_SORT_ASCENDING = 0,
|
SYSTRAY_SORT_ASCENDING = 0,
|
||||||
SYSTRAY_SORT_DESCENDING,
|
SYSTRAY_SORT_DESCENDING,
|
||||||
SYSTRAY_SORT_LEFT2RIGHT,
|
SYSTRAY_SORT_LEFT2RIGHT,
|
||||||
SYSTRAY_SORT_RIGHT2LEFT,
|
SYSTRAY_SORT_RIGHT2LEFT,
|
||||||
} SystraySortMethod;
|
} SystraySortMethod;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// always start with area
|
// always start with area
|
||||||
Area area;
|
Area area;
|
||||||
|
|
||||||
GSList *list_icons;
|
GSList *list_icons;
|
||||||
SystraySortMethod sort;
|
SystraySortMethod sort;
|
||||||
int alpha, saturation, brightness;
|
int alpha, saturation, brightness;
|
||||||
int icon_size, icons_per_column, icons_per_row, margin;
|
int icon_size, icons_per_column, icons_per_row, margin;
|
||||||
} Systray;
|
} Systray;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// The actual tray icon window (created by the application)
|
// The actual tray icon window (created by the application)
|
||||||
Window win;
|
Window win;
|
||||||
// The parent window created by tint2 to embed the icon
|
// The parent window created by tint2 to embed the icon
|
||||||
Window parent;
|
Window parent;
|
||||||
int x, y;
|
int x, y;
|
||||||
int width, height;
|
int width, height;
|
||||||
int depth;
|
int depth;
|
||||||
gboolean reparented;
|
gboolean reparented;
|
||||||
gboolean embedded;
|
gboolean embedded;
|
||||||
// Process PID or zero.
|
// Process PID or zero.
|
||||||
int pid;
|
int pid;
|
||||||
// A number that is incremented for each new icon, used to sort them by the order in which they were created.
|
// A number that is incremented for each new icon, used to sort them by the order in which they were created.
|
||||||
int chrono;
|
int chrono;
|
||||||
// Name of the tray icon window.
|
// Name of the tray icon window.
|
||||||
char *name;
|
char *name;
|
||||||
// Members used for rendering
|
// Members used for rendering
|
||||||
struct timespec time_last_render;
|
struct timespec time_last_render;
|
||||||
int num_fast_renders;
|
int num_fast_renders;
|
||||||
timeout *render_timeout;
|
timeout *render_timeout;
|
||||||
// Members used for resizing
|
// Members used for resizing
|
||||||
int bad_size_counter;
|
int bad_size_counter;
|
||||||
struct timespec time_last_resize;
|
struct timespec time_last_resize;
|
||||||
timeout *resize_timeout;
|
timeout *resize_timeout;
|
||||||
// Icon contents if we are compositing the icon, otherwise null
|
// Icon contents if we are compositing the icon, otherwise null
|
||||||
Imlib_Image image;
|
Imlib_Image image;
|
||||||
// XDamage
|
// XDamage
|
||||||
Damage damage;
|
Damage damage;
|
||||||
} TrayWindow;
|
} TrayWindow;
|
||||||
|
|
||||||
// net_sel_win != None when protocol started
|
// net_sel_win != None when protocol started
|
||||||
|
|||||||
1068
src/taskbar/task.c
1068
src/taskbar/task.c
File diff suppressed because it is too large
Load Diff
@@ -14,65 +14,65 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
typedef enum TaskState {
|
typedef enum TaskState {
|
||||||
TASK_NORMAL = 0,
|
TASK_NORMAL = 0,
|
||||||
TASK_ACTIVE,
|
TASK_ACTIVE,
|
||||||
TASK_ICONIFIED,
|
TASK_ICONIFIED,
|
||||||
TASK_URGENT,
|
TASK_URGENT,
|
||||||
TASK_UNDEFINED,
|
TASK_UNDEFINED,
|
||||||
TASK_STATE_COUNT,
|
TASK_STATE_COUNT,
|
||||||
} TaskState;
|
} TaskState;
|
||||||
|
|
||||||
typedef struct GlobalTask {
|
typedef struct GlobalTask {
|
||||||
Area area;
|
Area area;
|
||||||
gboolean has_text;
|
gboolean has_text;
|
||||||
gboolean has_icon;
|
gboolean has_icon;
|
||||||
gboolean centered;
|
gboolean centered;
|
||||||
int icon_posy;
|
int icon_posy;
|
||||||
int icon_size1;
|
int icon_size1;
|
||||||
int maximum_width;
|
int maximum_width;
|
||||||
int maximum_height;
|
int maximum_height;
|
||||||
int alpha[TASK_STATE_COUNT];
|
int alpha[TASK_STATE_COUNT];
|
||||||
int saturation[TASK_STATE_COUNT];
|
int saturation[TASK_STATE_COUNT];
|
||||||
int brightness[TASK_STATE_COUNT];
|
int brightness[TASK_STATE_COUNT];
|
||||||
int config_asb_mask;
|
int config_asb_mask;
|
||||||
Background *background[TASK_STATE_COUNT];
|
Background *background[TASK_STATE_COUNT];
|
||||||
GList *gradient[TASK_STATE_COUNT];
|
GList *gradient[TASK_STATE_COUNT];
|
||||||
int config_background_mask;
|
int config_background_mask;
|
||||||
// starting position for text ~ task_padding + task_border + icon_size
|
// starting position for text ~ task_padding + task_border + icon_size
|
||||||
double text_posx, text_height;
|
double text_posx, text_height;
|
||||||
gboolean has_font;
|
gboolean has_font;
|
||||||
PangoFontDescription *font_desc;
|
PangoFontDescription *font_desc;
|
||||||
Color font[TASK_STATE_COUNT];
|
Color font[TASK_STATE_COUNT];
|
||||||
int config_font_mask;
|
int config_font_mask;
|
||||||
gboolean tooltip_enabled;
|
gboolean tooltip_enabled;
|
||||||
} GlobalTask;
|
} GlobalTask;
|
||||||
|
|
||||||
// Stores information about a task.
|
// Stores information about a task.
|
||||||
// Warning: any dynamically allocated members are shared between the Task instances created for the same window
|
// Warning: any dynamically allocated members are shared between the Task instances created for the same window
|
||||||
// (if the task appears on all desktops, there will be a different instance on each desktop's taskbar).
|
// (if the task appears on all desktops, there will be a different instance on each desktop's taskbar).
|
||||||
typedef struct Task {
|
typedef struct Task {
|
||||||
Area area;
|
Area area;
|
||||||
Window win;
|
Window win;
|
||||||
int desktop;
|
int desktop;
|
||||||
TaskState current_state;
|
TaskState current_state;
|
||||||
Imlib_Image icon[TASK_STATE_COUNT];
|
Imlib_Image icon[TASK_STATE_COUNT];
|
||||||
Imlib_Image icon_hover[TASK_STATE_COUNT];
|
Imlib_Image icon_hover[TASK_STATE_COUNT];
|
||||||
Imlib_Image icon_press[TASK_STATE_COUNT];
|
Imlib_Image icon_press[TASK_STATE_COUNT];
|
||||||
unsigned int icon_width;
|
unsigned int icon_width;
|
||||||
unsigned int icon_height;
|
unsigned int icon_height;
|
||||||
char *title;
|
char *title;
|
||||||
int urgent_tick;
|
int urgent_tick;
|
||||||
// These may not be up-to-date
|
// These may not be up-to-date
|
||||||
int win_x;
|
int win_x;
|
||||||
int win_y;
|
int win_y;
|
||||||
int win_w;
|
int win_w;
|
||||||
int win_h;
|
int win_h;
|
||||||
struct timespec last_activation_time;
|
struct timespec last_activation_time;
|
||||||
int _text_width;
|
int _text_width;
|
||||||
int _text_height;
|
int _text_height;
|
||||||
double _text_posy;
|
double _text_posy;
|
||||||
int _icon_x;
|
int _icon_x;
|
||||||
int _icon_y;
|
int _icon_y;
|
||||||
} Task;
|
} Task;
|
||||||
|
|
||||||
extern timeout *urgent_timeout;
|
extern timeout *urgent_timeout;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,39 +12,39 @@
|
|||||||
#include "taskbarname.h"
|
#include "taskbarname.h"
|
||||||
|
|
||||||
typedef enum TaskbarState {
|
typedef enum TaskbarState {
|
||||||
TASKBAR_NORMAL = 0,
|
TASKBAR_NORMAL = 0,
|
||||||
TASKBAR_ACTIVE,
|
TASKBAR_ACTIVE,
|
||||||
TASKBAR_STATE_COUNT,
|
TASKBAR_STATE_COUNT,
|
||||||
} TaskbarState;
|
} TaskbarState;
|
||||||
|
|
||||||
typedef enum TaskbarSortMethod {
|
typedef enum TaskbarSortMethod {
|
||||||
TASKBAR_NOSORT = 0,
|
TASKBAR_NOSORT = 0,
|
||||||
TASKBAR_SORT_CENTER,
|
TASKBAR_SORT_CENTER,
|
||||||
TASKBAR_SORT_TITLE,
|
TASKBAR_SORT_TITLE,
|
||||||
TASKBAR_SORT_LRU,
|
TASKBAR_SORT_LRU,
|
||||||
TASKBAR_SORT_MRU,
|
TASKBAR_SORT_MRU,
|
||||||
} TaskbarSortMethod;
|
} TaskbarSortMethod;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Area area;
|
Area area;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
int posy;
|
int posy;
|
||||||
} TaskbarName;
|
} TaskbarName;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Area area;
|
Area area;
|
||||||
int desktop;
|
int desktop;
|
||||||
TaskbarName bar_name;
|
TaskbarName bar_name;
|
||||||
int text_width;
|
int text_width;
|
||||||
} Taskbar;
|
} Taskbar;
|
||||||
|
|
||||||
typedef struct GlobalTaskbar {
|
typedef struct GlobalTaskbar {
|
||||||
Area area;
|
Area area;
|
||||||
Area area_name;
|
Area area_name;
|
||||||
Background *background[TASKBAR_STATE_COUNT];
|
Background *background[TASKBAR_STATE_COUNT];
|
||||||
Background *background_name[TASKBAR_STATE_COUNT];
|
Background *background_name[TASKBAR_STATE_COUNT];
|
||||||
GList *gradient[TASKBAR_STATE_COUNT];
|
GList *gradient[TASKBAR_STATE_COUNT];
|
||||||
GList *gradient_name[TASKBAR_STATE_COUNT];
|
GList *gradient_name[TASKBAR_STATE_COUNT];
|
||||||
} GlobalTaskbar;
|
} GlobalTaskbar;
|
||||||
|
|
||||||
extern gboolean taskbar_enabled;
|
extern gboolean taskbar_enabled;
|
||||||
|
|||||||
@@ -41,176 +41,176 @@ int taskbarname_compute_desired_size(void *obj);
|
|||||||
|
|
||||||
void default_taskbarname()
|
void default_taskbarname()
|
||||||
{
|
{
|
||||||
taskbarname_enabled = FALSE;
|
taskbarname_enabled = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_taskbarname_panel(void *p)
|
void init_taskbarname_panel(void *p)
|
||||||
{
|
{
|
||||||
if (!taskbarname_enabled)
|
if (!taskbarname_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Panel *panel = (Panel *)p;
|
Panel *panel = (Panel *)p;
|
||||||
|
|
||||||
taskbarname_init_fonts();
|
taskbarname_init_fonts();
|
||||||
|
|
||||||
GSList *list = get_desktop_names();
|
GSList *list = get_desktop_names();
|
||||||
GSList *l = list;
|
GSList *l = list;
|
||||||
for (int j = 0; j < panel->num_desktops; j++) {
|
for (int j = 0; j < panel->num_desktops; j++) {
|
||||||
Taskbar *taskbar = &panel->taskbar[j];
|
Taskbar *taskbar = &panel->taskbar[j];
|
||||||
memcpy(&taskbar->bar_name.area, &panel->g_taskbar.area_name, sizeof(Area));
|
memcpy(&taskbar->bar_name.area, &panel->g_taskbar.area_name, sizeof(Area));
|
||||||
taskbar->bar_name.area.parent = taskbar;
|
taskbar->bar_name.area.parent = taskbar;
|
||||||
taskbar->bar_name.area.has_mouse_over_effect = panel_config.mouse_effects;
|
taskbar->bar_name.area.has_mouse_over_effect = panel_config.mouse_effects;
|
||||||
taskbar->bar_name.area.has_mouse_press_effect = panel_config.mouse_effects;
|
taskbar->bar_name.area.has_mouse_press_effect = panel_config.mouse_effects;
|
||||||
taskbar->bar_name.area._compute_desired_size = taskbarname_compute_desired_size;
|
taskbar->bar_name.area._compute_desired_size = taskbarname_compute_desired_size;
|
||||||
if (j == server.desktop) {
|
if (j == server.desktop) {
|
||||||
taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_ACTIVE];
|
taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_ACTIVE];
|
||||||
} else {
|
} else {
|
||||||
taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_NORMAL];
|
taskbar->bar_name.area.bg = panel->g_taskbar.background_name[TASKBAR_NORMAL];
|
||||||
}
|
}
|
||||||
|
|
||||||
// use desktop number if name is missing
|
// use desktop number if name is missing
|
||||||
if (l) {
|
if (l) {
|
||||||
taskbar->bar_name.name = g_strdup(l->data);
|
taskbar->bar_name.name = g_strdup(l->data);
|
||||||
l = l->next;
|
l = l->next;
|
||||||
} else {
|
} else {
|
||||||
taskbar->bar_name.name = g_strdup_printf("%d", j + 1);
|
taskbar->bar_name.name = g_strdup_printf("%d", j + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append the name at the beginning of taskbar
|
// append the name at the beginning of taskbar
|
||||||
taskbar->area.children = g_list_append(taskbar->area.children, &taskbar->bar_name);
|
taskbar->area.children = g_list_append(taskbar->area.children, &taskbar->bar_name);
|
||||||
instantiate_area_gradients(&taskbar->bar_name.area);
|
instantiate_area_gradients(&taskbar->bar_name.area);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = list; l; l = l->next)
|
for (l = list; l; l = l->next)
|
||||||
g_free(l->data);
|
g_free(l->data);
|
||||||
g_slist_free(list);
|
g_slist_free(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void taskbarname_init_fonts()
|
void taskbarname_init_fonts()
|
||||||
{
|
{
|
||||||
if (!panel_config.taskbarname_font_desc) {
|
if (!panel_config.taskbarname_font_desc) {
|
||||||
panel_config.taskbarname_font_desc = pango_font_description_from_string(get_default_font());
|
panel_config.taskbarname_font_desc = pango_font_description_from_string(get_default_font());
|
||||||
pango_font_description_set_weight(panel_config.taskbarname_font_desc, PANGO_WEIGHT_BOLD);
|
pango_font_description_set_weight(panel_config.taskbarname_font_desc, PANGO_WEIGHT_BOLD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void taskbarname_default_font_changed()
|
void taskbarname_default_font_changed()
|
||||||
{
|
{
|
||||||
if (!taskbar_enabled)
|
if (!taskbar_enabled)
|
||||||
return;
|
return;
|
||||||
if (!taskbarname_enabled)
|
if (!taskbarname_enabled)
|
||||||
return;
|
return;
|
||||||
if (panel_config.taskbarname_has_font)
|
if (panel_config.taskbarname_has_font)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pango_font_description_free(panel_config.taskbarname_font_desc);
|
pango_font_description_free(panel_config.taskbarname_font_desc);
|
||||||
panel_config.taskbarname_font_desc = NULL;
|
panel_config.taskbarname_font_desc = NULL;
|
||||||
taskbarname_init_fonts();
|
taskbarname_init_fonts();
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
for (int j = 0; j < panels[i].num_desktops; j++) {
|
for (int j = 0; j < panels[i].num_desktops; j++) {
|
||||||
Taskbar *taskbar = &panels[i].taskbar[j];
|
Taskbar *taskbar = &panels[i].taskbar[j];
|
||||||
taskbar->bar_name.area.resize_needed = TRUE;
|
taskbar->bar_name.area.resize_needed = TRUE;
|
||||||
schedule_redraw(&taskbar->bar_name.area);
|
schedule_redraw(&taskbar->bar_name.area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
schedule_panel_redraw();
|
schedule_panel_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_taskbarname()
|
void cleanup_taskbarname()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
Panel *panel = &panels[i];
|
Panel *panel = &panels[i];
|
||||||
for (int j = 0; j < panel->num_desktops; j++) {
|
for (int j = 0; j < panel->num_desktops; j++) {
|
||||||
Taskbar *taskbar = &panel->taskbar[j];
|
Taskbar *taskbar = &panel->taskbar[j];
|
||||||
g_free(taskbar->bar_name.name);
|
g_free(taskbar->bar_name.name);
|
||||||
taskbar->bar_name.name = NULL;
|
taskbar->bar_name.name = NULL;
|
||||||
free_area(&taskbar->bar_name.area);
|
free_area(&taskbar->bar_name.area);
|
||||||
remove_area((Area *)&taskbar->bar_name);
|
remove_area((Area *)&taskbar->bar_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int taskbarname_compute_desired_size(void *obj)
|
int taskbarname_compute_desired_size(void *obj)
|
||||||
{
|
{
|
||||||
TaskbarName *taskbar_name = (TaskbarName *)obj;
|
TaskbarName *taskbar_name = (TaskbarName *)obj;
|
||||||
Panel *panel = (Panel *)taskbar_name->area.panel;
|
Panel *panel = (Panel *)taskbar_name->area.panel;
|
||||||
int name_height, name_width, name_height_ink;
|
int name_height, name_width, name_height_ink;
|
||||||
get_text_size2(panel_config.taskbarname_font_desc,
|
get_text_size2(panel_config.taskbarname_font_desc,
|
||||||
&name_height_ink,
|
&name_height_ink,
|
||||||
&name_height,
|
&name_height,
|
||||||
&name_width,
|
&name_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
taskbar_name->name,
|
taskbar_name->name,
|
||||||
strlen(taskbar_name->name),
|
strlen(taskbar_name->name),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
return name_width + 2 * taskbar_name->area.paddingxlr + left_right_border_width(&taskbar_name->area);
|
return name_width + 2 * taskbar_name->area.paddingxlr + left_right_border_width(&taskbar_name->area);
|
||||||
} else {
|
} else {
|
||||||
return name_height + 2 * taskbar_name->area.paddingxlr + top_bottom_border_width(&taskbar_name->area);
|
return name_height + 2 * taskbar_name->area.paddingxlr + top_bottom_border_width(&taskbar_name->area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean resize_taskbarname(void *obj)
|
gboolean resize_taskbarname(void *obj)
|
||||||
{
|
{
|
||||||
TaskbarName *taskbar_name = (TaskbarName *)obj;
|
TaskbarName *taskbar_name = (TaskbarName *)obj;
|
||||||
Panel *panel = (Panel *)taskbar_name->area.panel;
|
Panel *panel = (Panel *)taskbar_name->area.panel;
|
||||||
|
|
||||||
schedule_redraw(&taskbar_name->area);
|
schedule_redraw(&taskbar_name->area);
|
||||||
|
|
||||||
int name_height, name_width, name_height_ink;
|
int name_height, name_width, name_height_ink;
|
||||||
get_text_size2(panel_config.taskbarname_font_desc,
|
get_text_size2(panel_config.taskbarname_font_desc,
|
||||||
&name_height_ink,
|
&name_height_ink,
|
||||||
&name_height,
|
&name_height,
|
||||||
&name_width,
|
&name_width,
|
||||||
panel->area.height,
|
panel->area.height,
|
||||||
panel->area.width,
|
panel->area.width,
|
||||||
taskbar_name->name,
|
taskbar_name->name,
|
||||||
strlen(taskbar_name->name),
|
strlen(taskbar_name->name),
|
||||||
PANGO_WRAP_WORD_CHAR,
|
PANGO_WRAP_WORD_CHAR,
|
||||||
PANGO_ELLIPSIZE_NONE,
|
PANGO_ELLIPSIZE_NONE,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int new_size = taskbarname_compute_desired_size(obj);
|
int new_size = taskbarname_compute_desired_size(obj);
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
if (new_size != taskbar_name->area.width) {
|
if (new_size != taskbar_name->area.width) {
|
||||||
taskbar_name->area.width = new_size;
|
taskbar_name->area.width = new_size;
|
||||||
taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
|
taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (new_size != taskbar_name->area.height) {
|
if (new_size != taskbar_name->area.height) {
|
||||||
taskbar_name->area.height = new_size;
|
taskbar_name->area.height = new_size;
|
||||||
taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
|
taskbar_name->posy = (taskbar_name->area.height - name_height) / 2;
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_taskbarname(void *obj, cairo_t *c)
|
void draw_taskbarname(void *obj, cairo_t *c)
|
||||||
{
|
{
|
||||||
TaskbarName *taskbar_name = obj;
|
TaskbarName *taskbar_name = obj;
|
||||||
Taskbar *taskbar = taskbar_name->area.parent;
|
Taskbar *taskbar = taskbar_name->area.parent;
|
||||||
Color *config_text = (taskbar->desktop == server.desktop) ? &taskbarname_active_font : &taskbarname_font;
|
Color *config_text = (taskbar->desktop == server.desktop) ? &taskbarname_active_font : &taskbarname_font;
|
||||||
|
|
||||||
// draw content
|
// draw content
|
||||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||||
pango_layout_set_font_description(layout, panel_config.taskbarname_font_desc);
|
pango_layout_set_font_description(layout, panel_config.taskbarname_font_desc);
|
||||||
pango_layout_set_width(layout, taskbar_name->area.width * PANGO_SCALE);
|
pango_layout_set_width(layout, taskbar_name->area.width * PANGO_SCALE);
|
||||||
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
|
||||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
|
||||||
pango_layout_set_text(layout, taskbar_name->name, strlen(taskbar_name->name));
|
pango_layout_set_text(layout, taskbar_name->name, strlen(taskbar_name->name));
|
||||||
|
|
||||||
cairo_set_source_rgba(c, config_text->rgb[0], config_text->rgb[1], config_text->rgb[2], config_text->alpha);
|
cairo_set_source_rgba(c, config_text->rgb[0], config_text->rgb[1], config_text->rgb[2], config_text->alpha);
|
||||||
|
|
||||||
pango_cairo_update_layout(c, layout);
|
pango_cairo_update_layout(c, layout);
|
||||||
draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel *)taskbar_name->area.panel)->font_shadow);
|
draw_text(layout, c, 0, taskbar_name->posy, config_text, ((Panel *)taskbar_name->area.panel)->font_shadow);
|
||||||
|
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
}
|
}
|
||||||
|
|||||||
3449
src/tint.c
3449
src/tint.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,23 +22,23 @@ void gradient_stop_update_image(int index);
|
|||||||
void current_gradient_stop_changed(GtkWidget *widget, gpointer data);
|
void current_gradient_stop_changed(GtkWidget *widget, gpointer data);
|
||||||
|
|
||||||
typedef enum GradientConfigType {
|
typedef enum GradientConfigType {
|
||||||
GRADIENT_CONFIG_VERTICAL = 0,
|
GRADIENT_CONFIG_VERTICAL = 0,
|
||||||
GRADIENT_CONFIG_HORIZONTAL,
|
GRADIENT_CONFIG_HORIZONTAL,
|
||||||
GRADIENT_CONFIG_RADIAL
|
GRADIENT_CONFIG_RADIAL
|
||||||
} GradientConfigType;
|
} GradientConfigType;
|
||||||
|
|
||||||
typedef struct GradientConfigColorStop {
|
typedef struct GradientConfigColorStop {
|
||||||
Color color;
|
Color color;
|
||||||
// offset in 0-1
|
// offset in 0-1
|
||||||
double offset;
|
double offset;
|
||||||
} GradientConfigColorStop;
|
} GradientConfigColorStop;
|
||||||
|
|
||||||
typedef struct GradientConfig {
|
typedef struct GradientConfig {
|
||||||
GradientConfigType type;
|
GradientConfigType type;
|
||||||
GradientConfigColorStop start_color;
|
GradientConfigColorStop start_color;
|
||||||
GradientConfigColorStop end_color;
|
GradientConfigColorStop end_color;
|
||||||
// Each element is a GradientConfigColorStop
|
// Each element is a GradientConfigColorStop
|
||||||
GList *extra_color_stops;
|
GList *extra_color_stops;
|
||||||
} GradientConfig;
|
} GradientConfig;
|
||||||
|
|
||||||
void gradient_create_new(GradientConfigType t);
|
void gradient_create_new(GradientConfigType t);
|
||||||
|
|||||||
1322
src/tint2conf/main.c
1322
src/tint2conf/main.c
File diff suppressed because it is too large
Load Diff
@@ -40,235 +40,232 @@ typedef u_int64_t u64;
|
|||||||
#define shash_desc md4_ctx
|
#define shash_desc md4_ctx
|
||||||
#define shash_desc_ctx(x) (x)
|
#define shash_desc_ctx(x) (x)
|
||||||
|
|
||||||
#define MD4_DIGEST_SIZE 16
|
#define MD4_DIGEST_SIZE 16
|
||||||
#define MD4_HMAC_BLOCK_SIZE 64
|
#define MD4_HMAC_BLOCK_SIZE 64
|
||||||
#define MD4_BLOCK_WORDS 16
|
#define MD4_BLOCK_WORDS 16
|
||||||
#define MD4_HASH_WORDS 4
|
#define MD4_HASH_WORDS 4
|
||||||
|
|
||||||
struct md4_ctx {
|
struct md4_ctx {
|
||||||
u32 hash[MD4_HASH_WORDS];
|
u32 hash[MD4_HASH_WORDS];
|
||||||
u32 block[MD4_BLOCK_WORDS];
|
u32 block[MD4_BLOCK_WORDS];
|
||||||
u64 byte_count;
|
u64 byte_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline u32 lshift(u32 x, unsigned int s)
|
static inline u32 lshift(u32 x, unsigned int s)
|
||||||
{
|
{
|
||||||
x &= 0xFFFFFFFF;
|
x &= 0xFFFFFFFF;
|
||||||
return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
|
return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 F(u32 x, u32 y, u32 z)
|
static inline u32 F(u32 x, u32 y, u32 z)
|
||||||
{
|
{
|
||||||
return (x & y) | ((~x) & z);
|
return (x & y) | ((~x) & z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 G(u32 x, u32 y, u32 z)
|
static inline u32 G(u32 x, u32 y, u32 z)
|
||||||
{
|
{
|
||||||
return (x & y) | (x & z) | (y & z);
|
return (x & y) | (x & z) | (y & z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 H(u32 x, u32 y, u32 z)
|
static inline u32 H(u32 x, u32 y, u32 z)
|
||||||
{
|
{
|
||||||
return x ^ y ^ z;
|
return x ^ y ^ z;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s))
|
#define ROUND1(a, b, c, d, k, s) (a = lshift(a + F(b, c, d) + k, s))
|
||||||
#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s))
|
#define ROUND2(a, b, c, d, k, s) (a = lshift(a + G(b, c, d) + k + (u32)0x5A827999, s))
|
||||||
#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s))
|
#define ROUND3(a, b, c, d, k, s) (a = lshift(a + H(b, c, d) + k + (u32)0x6ED9EBA1, s))
|
||||||
|
|
||||||
/* XXX: this stuff can be optimized */
|
/* XXX: this stuff can be optimized */
|
||||||
static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
|
static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
|
||||||
{
|
{
|
||||||
while (words--) {
|
while (words--) {
|
||||||
*buf = ntohl(*buf);
|
*buf = ntohl(*buf);
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
|
static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
|
||||||
{
|
{
|
||||||
while (words--) {
|
while (words--) {
|
||||||
*buf = htonl(*buf);
|
*buf = htonl(*buf);
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void md4_transform(u32 *hash, u32 const *in)
|
static void md4_transform(u32 *hash, u32 const *in)
|
||||||
{
|
{
|
||||||
u32 a, b, c, d;
|
u32 a, b, c, d;
|
||||||
|
|
||||||
a = hash[0];
|
a = hash[0];
|
||||||
b = hash[1];
|
b = hash[1];
|
||||||
c = hash[2];
|
c = hash[2];
|
||||||
d = hash[3];
|
d = hash[3];
|
||||||
|
|
||||||
ROUND1(a, b, c, d, in[0], 3);
|
ROUND1(a, b, c, d, in[0], 3);
|
||||||
ROUND1(d, a, b, c, in[1], 7);
|
ROUND1(d, a, b, c, in[1], 7);
|
||||||
ROUND1(c, d, a, b, in[2], 11);
|
ROUND1(c, d, a, b, in[2], 11);
|
||||||
ROUND1(b, c, d, a, in[3], 19);
|
ROUND1(b, c, d, a, in[3], 19);
|
||||||
ROUND1(a, b, c, d, in[4], 3);
|
ROUND1(a, b, c, d, in[4], 3);
|
||||||
ROUND1(d, a, b, c, in[5], 7);
|
ROUND1(d, a, b, c, in[5], 7);
|
||||||
ROUND1(c, d, a, b, in[6], 11);
|
ROUND1(c, d, a, b, in[6], 11);
|
||||||
ROUND1(b, c, d, a, in[7], 19);
|
ROUND1(b, c, d, a, in[7], 19);
|
||||||
ROUND1(a, b, c, d, in[8], 3);
|
ROUND1(a, b, c, d, in[8], 3);
|
||||||
ROUND1(d, a, b, c, in[9], 7);
|
ROUND1(d, a, b, c, in[9], 7);
|
||||||
ROUND1(c, d, a, b, in[10], 11);
|
ROUND1(c, d, a, b, in[10], 11);
|
||||||
ROUND1(b, c, d, a, in[11], 19);
|
ROUND1(b, c, d, a, in[11], 19);
|
||||||
ROUND1(a, b, c, d, in[12], 3);
|
ROUND1(a, b, c, d, in[12], 3);
|
||||||
ROUND1(d, a, b, c, in[13], 7);
|
ROUND1(d, a, b, c, in[13], 7);
|
||||||
ROUND1(c, d, a, b, in[14], 11);
|
ROUND1(c, d, a, b, in[14], 11);
|
||||||
ROUND1(b, c, d, a, in[15], 19);
|
ROUND1(b, c, d, a, in[15], 19);
|
||||||
|
|
||||||
ROUND2(a, b, c, d,in[ 0], 3);
|
ROUND2(a, b, c, d, in[0], 3);
|
||||||
ROUND2(d, a, b, c, in[4], 5);
|
ROUND2(d, a, b, c, in[4], 5);
|
||||||
ROUND2(c, d, a, b, in[8], 9);
|
ROUND2(c, d, a, b, in[8], 9);
|
||||||
ROUND2(b, c, d, a, in[12], 13);
|
ROUND2(b, c, d, a, in[12], 13);
|
||||||
ROUND2(a, b, c, d, in[1], 3);
|
ROUND2(a, b, c, d, in[1], 3);
|
||||||
ROUND2(d, a, b, c, in[5], 5);
|
ROUND2(d, a, b, c, in[5], 5);
|
||||||
ROUND2(c, d, a, b, in[9], 9);
|
ROUND2(c, d, a, b, in[9], 9);
|
||||||
ROUND2(b, c, d, a, in[13], 13);
|
ROUND2(b, c, d, a, in[13], 13);
|
||||||
ROUND2(a, b, c, d, in[2], 3);
|
ROUND2(a, b, c, d, in[2], 3);
|
||||||
ROUND2(d, a, b, c, in[6], 5);
|
ROUND2(d, a, b, c, in[6], 5);
|
||||||
ROUND2(c, d, a, b, in[10], 9);
|
ROUND2(c, d, a, b, in[10], 9);
|
||||||
ROUND2(b, c, d, a, in[14], 13);
|
ROUND2(b, c, d, a, in[14], 13);
|
||||||
ROUND2(a, b, c, d, in[3], 3);
|
ROUND2(a, b, c, d, in[3], 3);
|
||||||
ROUND2(d, a, b, c, in[7], 5);
|
ROUND2(d, a, b, c, in[7], 5);
|
||||||
ROUND2(c, d, a, b, in[11], 9);
|
ROUND2(c, d, a, b, in[11], 9);
|
||||||
ROUND2(b, c, d, a, in[15], 13);
|
ROUND2(b, c, d, a, in[15], 13);
|
||||||
|
|
||||||
ROUND3(a, b, c, d,in[ 0], 3);
|
ROUND3(a, b, c, d, in[0], 3);
|
||||||
ROUND3(d, a, b, c, in[8], 9);
|
ROUND3(d, a, b, c, in[8], 9);
|
||||||
ROUND3(c, d, a, b, in[4], 11);
|
ROUND3(c, d, a, b, in[4], 11);
|
||||||
ROUND3(b, c, d, a, in[12], 15);
|
ROUND3(b, c, d, a, in[12], 15);
|
||||||
ROUND3(a, b, c, d, in[2], 3);
|
ROUND3(a, b, c, d, in[2], 3);
|
||||||
ROUND3(d, a, b, c, in[10], 9);
|
ROUND3(d, a, b, c, in[10], 9);
|
||||||
ROUND3(c, d, a, b, in[6], 11);
|
ROUND3(c, d, a, b, in[6], 11);
|
||||||
ROUND3(b, c, d, a, in[14], 15);
|
ROUND3(b, c, d, a, in[14], 15);
|
||||||
ROUND3(a, b, c, d, in[1], 3);
|
ROUND3(a, b, c, d, in[1], 3);
|
||||||
ROUND3(d, a, b, c, in[9], 9);
|
ROUND3(d, a, b, c, in[9], 9);
|
||||||
ROUND3(c, d, a, b, in[5], 11);
|
ROUND3(c, d, a, b, in[5], 11);
|
||||||
ROUND3(b, c, d, a, in[13], 15);
|
ROUND3(b, c, d, a, in[13], 15);
|
||||||
ROUND3(a, b, c, d, in[3], 3);
|
ROUND3(a, b, c, d, in[3], 3);
|
||||||
ROUND3(d, a, b, c, in[11], 9);
|
ROUND3(d, a, b, c, in[11], 9);
|
||||||
ROUND3(c, d, a, b, in[7], 11);
|
ROUND3(c, d, a, b, in[7], 11);
|
||||||
ROUND3(b, c, d, a, in[15], 15);
|
ROUND3(b, c, d, a, in[15], 15);
|
||||||
|
|
||||||
hash[0] += a;
|
hash[0] += a;
|
||||||
hash[1] += b;
|
hash[1] += b;
|
||||||
hash[2] += c;
|
hash[2] += c;
|
||||||
hash[3] += d;
|
hash[3] += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void md4_transform_helper(struct md4_ctx *ctx)
|
static inline void md4_transform_helper(struct md4_ctx *ctx)
|
||||||
{
|
{
|
||||||
le32_to_cpu_array(ctx->block, ARRAY_SIZE(ctx->block));
|
le32_to_cpu_array(ctx->block, ARRAY_SIZE(ctx->block));
|
||||||
md4_transform(ctx->hash, ctx->block);
|
md4_transform(ctx->hash, ctx->block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int md4_init(struct shash_desc *desc)
|
static int md4_init(struct shash_desc *desc)
|
||||||
{
|
{
|
||||||
struct md4_ctx *mctx = shash_desc_ctx(desc);
|
struct md4_ctx *mctx = shash_desc_ctx(desc);
|
||||||
|
|
||||||
mctx->hash[0] = 0x67452301;
|
mctx->hash[0] = 0x67452301;
|
||||||
mctx->hash[1] = 0xefcdab89;
|
mctx->hash[1] = 0xefcdab89;
|
||||||
mctx->hash[2] = 0x98badcfe;
|
mctx->hash[2] = 0x98badcfe;
|
||||||
mctx->hash[3] = 0x10325476;
|
mctx->hash[3] = 0x10325476;
|
||||||
mctx->byte_count = 0;
|
mctx->byte_count = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int md4_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
static int md4_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
||||||
{
|
{
|
||||||
struct md4_ctx *mctx = shash_desc_ctx(desc);
|
struct md4_ctx *mctx = shash_desc_ctx(desc);
|
||||||
const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
|
const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
|
||||||
|
|
||||||
mctx->byte_count += len;
|
mctx->byte_count += len;
|
||||||
|
|
||||||
if (avail > len) {
|
if (avail > len) {
|
||||||
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
|
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, len);
|
||||||
data, len);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
|
memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail);
|
||||||
data, avail);
|
|
||||||
|
|
||||||
md4_transform_helper(mctx);
|
md4_transform_helper(mctx);
|
||||||
data += avail;
|
data += avail;
|
||||||
len -= avail;
|
len -= avail;
|
||||||
|
|
||||||
while (len >= sizeof(mctx->block)) {
|
while (len >= sizeof(mctx->block)) {
|
||||||
memcpy(mctx->block, data, sizeof(mctx->block));
|
memcpy(mctx->block, data, sizeof(mctx->block));
|
||||||
md4_transform_helper(mctx);
|
md4_transform_helper(mctx);
|
||||||
data += sizeof(mctx->block);
|
data += sizeof(mctx->block);
|
||||||
len -= sizeof(mctx->block);
|
len -= sizeof(mctx->block);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(mctx->block, data, len);
|
memcpy(mctx->block, data, len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int md4_final(struct shash_desc *desc, u8 *out)
|
static int md4_final(struct shash_desc *desc, u8 *out)
|
||||||
{
|
{
|
||||||
struct md4_ctx *mctx = shash_desc_ctx(desc);
|
struct md4_ctx *mctx = shash_desc_ctx(desc);
|
||||||
const unsigned int offset = mctx->byte_count & 0x3f;
|
const unsigned int offset = mctx->byte_count & 0x3f;
|
||||||
char *p = (char *)mctx->block + offset;
|
char *p = (char *)mctx->block + offset;
|
||||||
int padding = 56 - (offset + 1);
|
int padding = 56 - (offset + 1);
|
||||||
|
|
||||||
*p++ = 0x80;
|
*p++ = 0x80;
|
||||||
if (padding < 0) {
|
if (padding < 0) {
|
||||||
memset(p, 0x00, padding + sizeof (u64));
|
memset(p, 0x00, padding + sizeof(u64));
|
||||||
md4_transform_helper(mctx);
|
md4_transform_helper(mctx);
|
||||||
p = (char *)mctx->block;
|
p = (char *)mctx->block;
|
||||||
padding = 56;
|
padding = 56;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(p, 0, padding);
|
memset(p, 0, padding);
|
||||||
mctx->block[14] = mctx->byte_count << 3;
|
mctx->block[14] = mctx->byte_count << 3;
|
||||||
mctx->block[15] = mctx->byte_count >> 29;
|
mctx->block[15] = mctx->byte_count >> 29;
|
||||||
le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
|
le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - sizeof(u64)) / sizeof(u32));
|
||||||
sizeof(u64)) / sizeof(u32));
|
md4_transform(mctx->hash, mctx->block);
|
||||||
md4_transform(mctx->hash, mctx->block);
|
cpu_to_le32_array(mctx->hash, ARRAY_SIZE(mctx->hash));
|
||||||
cpu_to_le32_array(mctx->hash, ARRAY_SIZE(mctx->hash));
|
memcpy(out, mctx->hash, sizeof(mctx->hash));
|
||||||
memcpy(out, mctx->hash, sizeof(mctx->hash));
|
memset(mctx, 0, sizeof(*mctx));
|
||||||
memset(mctx, 0, sizeof(*mctx));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char to_hex(u8 v)
|
static char to_hex(u8 v)
|
||||||
{
|
{
|
||||||
v = v & 0xf;
|
v = v & 0xf;
|
||||||
if (v < 0xa)
|
if (v < 0xa)
|
||||||
return '0' + v;
|
return '0' + v;
|
||||||
return 'a' + v - 0xa;
|
return 'a' + v - 0xa;
|
||||||
}
|
}
|
||||||
|
|
||||||
void md4hexf(const char *path, char *hash)
|
void md4hexf(const char *path, char *hash)
|
||||||
{
|
{
|
||||||
struct md4_ctx mctx;
|
struct md4_ctx mctx;
|
||||||
md4_init(&mctx);
|
md4_init(&mctx);
|
||||||
|
|
||||||
int fd = open(path, O_RDONLY);
|
int fd = open(path, O_RDONLY);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
u8 buffer[MD4_HMAC_BLOCK_SIZE];
|
u8 buffer[MD4_HMAC_BLOCK_SIZE];
|
||||||
while (1) {
|
while (1) {
|
||||||
ssize_t count = read(fd, buffer, sizeof(buffer));
|
ssize_t count = read(fd, buffer, sizeof(buffer));
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
break;
|
break;
|
||||||
md4_update(&mctx, buffer, (unsigned)count);
|
md4_update(&mctx, buffer, (unsigned)count);
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 out[MD4_DIGEST_SIZE];
|
u8 out[MD4_DIGEST_SIZE];
|
||||||
md4_final(&mctx, out);
|
md4_final(&mctx, out);
|
||||||
|
|
||||||
for (int i = 0; i < MD4_DIGEST_SIZE; i++) {
|
for (int i = 0; i < MD4_DIGEST_SIZE; i++) {
|
||||||
hash[2*i+0] = to_hex(out[i] >> 4);
|
hash[2 * i + 0] = to_hex(out[i] >> 4);
|
||||||
hash[2*i+1] = to_hex(out[i] & 0xf);
|
hash[2 * i + 1] = to_hex(out[i] & 0xf);
|
||||||
}
|
}
|
||||||
hash[2*MD4_DIGEST_SIZE] = 0;
|
hash[2 * MD4_DIGEST_SIZE] = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,22 +8,20 @@
|
|||||||
|
|
||||||
#include "../launcher/icon-theme-common.h"
|
#include "../launcher/icon-theme-common.h"
|
||||||
|
|
||||||
|
|
||||||
// panel
|
// panel
|
||||||
extern GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y, *panel_spacing;
|
extern GtkWidget *panel_width, *panel_height, *panel_margin_x, *panel_margin_y, *panel_padding_x, *panel_padding_y,
|
||||||
extern GtkWidget *panel_wm_menu, *panel_dock, *panel_autohide, *panel_autohide_show_time, *panel_autohide_hide_time, *panel_autohide_size;
|
*panel_spacing;
|
||||||
extern GtkWidget *panel_combo_strut_policy, *panel_combo_layer, *panel_combo_width_type, *panel_combo_height_type, *panel_combo_monitor;
|
extern GtkWidget *panel_wm_menu, *panel_dock, *panel_autohide, *panel_autohide_show_time, *panel_autohide_hide_time,
|
||||||
|
*panel_autohide_size;
|
||||||
|
extern GtkWidget *panel_combo_strut_policy, *panel_combo_layer, *panel_combo_width_type, *panel_combo_height_type,
|
||||||
|
*panel_combo_monitor;
|
||||||
extern GtkWidget *panel_window_name, *disable_transparency;
|
extern GtkWidget *panel_window_name, *disable_transparency;
|
||||||
extern GtkWidget *panel_mouse_effects;
|
extern GtkWidget *panel_mouse_effects;
|
||||||
extern GtkWidget *mouse_hover_icon_opacity, *mouse_hover_icon_saturation, *mouse_hover_icon_brightness;
|
extern GtkWidget *mouse_hover_icon_opacity, *mouse_hover_icon_saturation, *mouse_hover_icon_brightness;
|
||||||
extern GtkWidget *mouse_pressed_icon_opacity, *mouse_pressed_icon_saturation, *mouse_pressed_icon_brightness;
|
extern GtkWidget *mouse_pressed_icon_opacity, *mouse_pressed_icon_saturation, *mouse_pressed_icon_brightness;
|
||||||
extern GtkWidget *panel_primary_monitor_first, *panel_shrink;
|
extern GtkWidget *panel_primary_monitor_first, *panel_shrink;
|
||||||
|
|
||||||
enum {
|
enum { itemsColName = 0, itemsColValue, itemsNumCols };
|
||||||
itemsColName = 0,
|
|
||||||
itemsColValue,
|
|
||||||
itemsNumCols
|
|
||||||
};
|
|
||||||
extern GtkListStore *panel_items, *all_items;
|
extern GtkListStore *panel_items, *all_items;
|
||||||
extern GtkWidget *panel_items_view, *all_items_view;
|
extern GtkWidget *panel_items_view, *all_items_view;
|
||||||
char *get_panel_items();
|
char *get_panel_items();
|
||||||
@@ -52,44 +50,34 @@ extern GtkWidget *panel_background;
|
|||||||
// taskbar
|
// taskbar
|
||||||
extern GtkWidget *taskbar_show_desktop, *taskbar_show_name, *taskbar_padding_x, *taskbar_padding_y, *taskbar_spacing;
|
extern GtkWidget *taskbar_show_desktop, *taskbar_show_name, *taskbar_padding_x, *taskbar_padding_y, *taskbar_spacing;
|
||||||
extern GtkWidget *taskbar_hide_inactive_tasks, *taskbar_hide_diff_monitor;
|
extern GtkWidget *taskbar_hide_inactive_tasks, *taskbar_hide_diff_monitor;
|
||||||
extern GtkWidget *taskbar_name_padding_x, *taskbar_name_padding_y, *taskbar_name_inactive_color, *taskbar_name_active_color;
|
extern GtkWidget *taskbar_name_padding_x, *taskbar_name_padding_y, *taskbar_name_inactive_color,
|
||||||
|
*taskbar_name_active_color;
|
||||||
extern GtkWidget *taskbar_name_font, *taskbar_name_font_set;
|
extern GtkWidget *taskbar_name_font, *taskbar_name_font_set;
|
||||||
extern GtkWidget *taskbar_active_background, *taskbar_inactive_background;
|
extern GtkWidget *taskbar_active_background, *taskbar_inactive_background;
|
||||||
extern GtkWidget *taskbar_name_active_background, *taskbar_name_inactive_background;
|
extern GtkWidget *taskbar_name_active_background, *taskbar_name_inactive_background;
|
||||||
extern GtkWidget *taskbar_distribute_size, *taskbar_sort_order, *taskbar_alignment, *taskbar_always_show_all_desktop_tasks;
|
extern GtkWidget *taskbar_distribute_size, *taskbar_sort_order, *taskbar_alignment,
|
||||||
|
*taskbar_always_show_all_desktop_tasks;
|
||||||
extern GtkWidget *taskbar_hide_empty;
|
extern GtkWidget *taskbar_hide_empty;
|
||||||
|
|
||||||
// task
|
// task
|
||||||
extern GtkWidget *task_mouse_left, *task_mouse_middle, *task_mouse_right, *task_mouse_scroll_up, *task_mouse_scroll_down;
|
extern GtkWidget *task_mouse_left, *task_mouse_middle, *task_mouse_right, *task_mouse_scroll_up,
|
||||||
|
*task_mouse_scroll_down;
|
||||||
extern GtkWidget *task_show_icon, *task_show_text, *task_align_center, *font_shadow;
|
extern GtkWidget *task_show_icon, *task_show_text, *task_align_center, *font_shadow;
|
||||||
extern GtkWidget *task_maximum_width, *task_maximum_height, *task_padding_x, *task_padding_y, *task_spacing;
|
extern GtkWidget *task_maximum_width, *task_maximum_height, *task_padding_x, *task_padding_y, *task_spacing;
|
||||||
extern GtkWidget *task_font, *task_font_set;
|
extern GtkWidget *task_font, *task_font_set;
|
||||||
extern GtkWidget *task_default_color, *task_default_color_set,
|
extern GtkWidget *task_default_color, *task_default_color_set, *task_default_icon_opacity, *task_default_icon_osb_set,
|
||||||
*task_default_icon_opacity, *task_default_icon_osb_set,
|
*task_default_icon_saturation, *task_default_icon_brightness, *task_default_background,
|
||||||
*task_default_icon_saturation,
|
*task_default_background_set;
|
||||||
*task_default_icon_brightness,
|
extern GtkWidget *task_normal_color, *task_normal_color_set, *task_normal_icon_opacity, *task_normal_icon_osb_set,
|
||||||
*task_default_background, *task_default_background_set;
|
*task_normal_icon_saturation, *task_normal_icon_brightness, *task_normal_background, *task_normal_background_set;
|
||||||
extern GtkWidget *task_normal_color, *task_normal_color_set,
|
extern GtkWidget *task_active_color, *task_active_color_set, *task_active_icon_opacity, *task_active_icon_osb_set,
|
||||||
*task_normal_icon_opacity, *task_normal_icon_osb_set,
|
*task_active_icon_saturation, *task_active_icon_brightness, *task_active_background, *task_active_background_set;
|
||||||
*task_normal_icon_saturation,
|
extern GtkWidget *task_urgent_color, *task_urgent_color_set, *task_urgent_icon_opacity, *task_urgent_icon_osb_set,
|
||||||
*task_normal_icon_brightness,
|
*task_urgent_icon_saturation, *task_urgent_icon_brightness, *task_urgent_background, *task_urgent_background_set;
|
||||||
*task_normal_background, *task_normal_background_set;
|
|
||||||
extern GtkWidget *task_active_color, *task_active_color_set,
|
|
||||||
*task_active_icon_opacity, *task_active_icon_osb_set,
|
|
||||||
*task_active_icon_saturation,
|
|
||||||
*task_active_icon_brightness,
|
|
||||||
*task_active_background, *task_active_background_set;
|
|
||||||
extern GtkWidget *task_urgent_color, *task_urgent_color_set,
|
|
||||||
*task_urgent_icon_opacity, *task_urgent_icon_osb_set,
|
|
||||||
*task_urgent_icon_saturation,
|
|
||||||
*task_urgent_icon_brightness,
|
|
||||||
*task_urgent_background, *task_urgent_background_set;
|
|
||||||
extern GtkWidget *task_urgent_blinks;
|
extern GtkWidget *task_urgent_blinks;
|
||||||
extern GtkWidget *task_iconified_color, *task_iconified_color_set,
|
extern GtkWidget *task_iconified_color, *task_iconified_color_set, *task_iconified_icon_opacity,
|
||||||
*task_iconified_icon_opacity, *task_iconified_icon_osb_set,
|
*task_iconified_icon_osb_set, *task_iconified_icon_saturation, *task_iconified_icon_brightness,
|
||||||
*task_iconified_icon_saturation,
|
*task_iconified_background, *task_iconified_background_set;
|
||||||
*task_iconified_icon_brightness,
|
|
||||||
*task_iconified_background, *task_iconified_background_set;
|
|
||||||
|
|
||||||
// clock
|
// clock
|
||||||
extern GtkWidget *clock_format_line1, *clock_format_line2, *clock_tmz_line1, *clock_tmz_line2;
|
extern GtkWidget *clock_format_line1, *clock_format_line2, *clock_tmz_line1, *clock_tmz_line2;
|
||||||
@@ -102,10 +90,12 @@ extern GtkWidget *clock_background;
|
|||||||
// battery
|
// battery
|
||||||
extern GtkWidget *battery_hide_if_higher, *battery_alert_if_lower, *battery_alert_cmd;
|
extern GtkWidget *battery_hide_if_higher, *battery_alert_if_lower, *battery_alert_cmd;
|
||||||
extern GtkWidget *battery_padding_x, *battery_padding_y;
|
extern GtkWidget *battery_padding_x, *battery_padding_y;
|
||||||
extern GtkWidget *battery_font_line1, *battery_font_line1_set, *battery_font_line2, *battery_font_line2_set, *battery_font_color;
|
extern GtkWidget *battery_font_line1, *battery_font_line1_set, *battery_font_line2, *battery_font_line2_set,
|
||||||
|
*battery_font_color;
|
||||||
extern GtkWidget *battery_background;
|
extern GtkWidget *battery_background;
|
||||||
extern GtkWidget *battery_tooltip;
|
extern GtkWidget *battery_tooltip;
|
||||||
extern GtkWidget *battery_left_command, *battery_mclick_command, *battery_right_command, *battery_uwheel_command, *battery_dwheel_command;
|
extern GtkWidget *battery_left_command, *battery_mclick_command, *battery_right_command, *battery_uwheel_command,
|
||||||
|
*battery_dwheel_command;
|
||||||
extern GtkWidget *ac_connected_cmd, *ac_disconnected_cmd;
|
extern GtkWidget *ac_connected_cmd, *ac_disconnected_cmd;
|
||||||
|
|
||||||
// systray
|
// systray
|
||||||
@@ -121,60 +111,55 @@ extern GtkWidget *tooltip_background;
|
|||||||
|
|
||||||
// Separator
|
// Separator
|
||||||
typedef struct Separator {
|
typedef struct Separator {
|
||||||
char name[256];
|
char name[256];
|
||||||
GtkWidget *container;
|
GtkWidget *container;
|
||||||
GtkWidget *page_separator;
|
GtkWidget *page_separator;
|
||||||
GtkWidget *page_label;
|
GtkWidget *page_label;
|
||||||
GtkWidget *separator_background;
|
GtkWidget *separator_background;
|
||||||
GtkWidget *separator_color;
|
GtkWidget *separator_color;
|
||||||
GtkWidget *separator_style;
|
GtkWidget *separator_style;
|
||||||
GtkWidget *separator_size;
|
GtkWidget *separator_size;
|
||||||
GtkWidget *separator_padding_x;
|
GtkWidget *separator_padding_x;
|
||||||
GtkWidget *separator_padding_y;
|
GtkWidget *separator_padding_y;
|
||||||
} Separator;
|
} Separator;
|
||||||
|
|
||||||
extern GArray *separators;
|
extern GArray *separators;
|
||||||
|
|
||||||
// Executor
|
// Executor
|
||||||
typedef struct Executor {
|
typedef struct Executor {
|
||||||
char name[256];
|
char name[256];
|
||||||
GtkWidget *container;
|
GtkWidget *container;
|
||||||
GtkWidget *page_execp;
|
GtkWidget *page_execp;
|
||||||
GtkWidget *page_label;
|
GtkWidget *page_label;
|
||||||
GtkWidget *execp_command, *execp_interval, *execp_has_icon, *execp_cache_icon, *execp_show_tooltip;
|
GtkWidget *execp_command, *execp_interval, *execp_has_icon, *execp_cache_icon, *execp_show_tooltip;
|
||||||
GtkWidget *execp_continuous, *execp_markup, *execp_tooltip;
|
GtkWidget *execp_continuous, *execp_markup, *execp_tooltip;
|
||||||
GtkWidget *execp_left_command, *execp_right_command;
|
GtkWidget *execp_left_command, *execp_right_command;
|
||||||
GtkWidget *execp_mclick_command, *execp_rclick_command, *execp_uwheel_command, *execp_dwheel_command;
|
GtkWidget *execp_mclick_command, *execp_rclick_command, *execp_uwheel_command, *execp_dwheel_command;
|
||||||
GtkWidget *execp_font, *execp_font_set, *execp_font_color, *execp_padding_x, *execp_padding_y, *execp_centered;
|
GtkWidget *execp_font, *execp_font_set, *execp_font_color, *execp_padding_x, *execp_padding_y, *execp_centered;
|
||||||
GtkWidget *execp_background, *execp_icon_w, *execp_icon_h;
|
GtkWidget *execp_background, *execp_icon_w, *execp_icon_h;
|
||||||
} Executor;
|
} Executor;
|
||||||
|
|
||||||
extern GArray *executors;
|
extern GArray *executors;
|
||||||
|
|
||||||
// Button
|
// Button
|
||||||
typedef struct Button {
|
typedef struct Button {
|
||||||
char name[256];
|
char name[256];
|
||||||
GtkWidget *container;
|
GtkWidget *container;
|
||||||
GtkWidget *page_button;
|
GtkWidget *page_button;
|
||||||
GtkWidget *page_label;
|
GtkWidget *page_label;
|
||||||
GtkWidget *button_icon, *button_text, *button_tooltip;
|
GtkWidget *button_icon, *button_text, *button_tooltip;
|
||||||
GtkWidget *button_left_command, *button_right_command;
|
GtkWidget *button_left_command, *button_right_command;
|
||||||
GtkWidget *button_mclick_command, *button_rclick_command, *button_uwheel_command, *button_dwheel_command;
|
GtkWidget *button_mclick_command, *button_rclick_command, *button_uwheel_command, *button_dwheel_command;
|
||||||
GtkWidget *button_font, *button_font_set, *button_font_color, *button_padding_x, *button_padding_y, *button_centered;
|
GtkWidget *button_font, *button_font_set, *button_font_color, *button_padding_x, *button_padding_y,
|
||||||
GtkWidget *button_background, *button_max_icon_size;
|
*button_centered;
|
||||||
|
GtkWidget *button_background, *button_max_icon_size;
|
||||||
} Button;
|
} Button;
|
||||||
|
|
||||||
extern GArray *buttons;
|
extern GArray *buttons;
|
||||||
|
|
||||||
// launcher
|
// launcher
|
||||||
|
|
||||||
enum {
|
enum { appsColIcon = 0, appsColIconName, appsColText, appsColPath, appsNumCols };
|
||||||
appsColIcon = 0,
|
|
||||||
appsColIconName,
|
|
||||||
appsColText,
|
|
||||||
appsColPath,
|
|
||||||
appsNumCols
|
|
||||||
};
|
|
||||||
|
|
||||||
extern GtkListStore *launcher_apps, *all_apps;
|
extern GtkListStore *launcher_apps, *all_apps;
|
||||||
extern GtkWidget *launcher_apps_view, *all_apps_view;
|
extern GtkWidget *launcher_apps_view, *all_apps_view;
|
||||||
@@ -195,73 +180,49 @@ gchar *get_current_icon_theme();
|
|||||||
|
|
||||||
// background
|
// background
|
||||||
enum {
|
enum {
|
||||||
bgColPixbuf = 0,
|
bgColPixbuf = 0,
|
||||||
bgColFillColor,
|
bgColFillColor,
|
||||||
bgColFillOpacity,
|
bgColFillOpacity,
|
||||||
bgColBorderColor,
|
bgColBorderColor,
|
||||||
bgColBorderOpacity,
|
bgColBorderOpacity,
|
||||||
bgColGradientId,
|
bgColGradientId,
|
||||||
bgColBorderWidth,
|
bgColBorderWidth,
|
||||||
bgColCornerRadius,
|
bgColCornerRadius,
|
||||||
bgColText,
|
bgColText,
|
||||||
bgColFillColorOver,
|
bgColFillColorOver,
|
||||||
bgColFillOpacityOver,
|
bgColFillOpacityOver,
|
||||||
bgColBorderColorOver,
|
bgColBorderColorOver,
|
||||||
bgColBorderOpacityOver,
|
bgColBorderOpacityOver,
|
||||||
bgColGradientIdOver,
|
bgColGradientIdOver,
|
||||||
bgColFillColorPress,
|
bgColFillColorPress,
|
||||||
bgColFillOpacityPress,
|
bgColFillOpacityPress,
|
||||||
bgColBorderColorPress,
|
bgColBorderColorPress,
|
||||||
bgColBorderOpacityPress,
|
bgColBorderOpacityPress,
|
||||||
bgColGradientIdPress,
|
bgColGradientIdPress,
|
||||||
bgColBorderSidesTop,
|
bgColBorderSidesTop,
|
||||||
bgColBorderSidesBottom,
|
bgColBorderSidesBottom,
|
||||||
bgColBorderSidesLeft,
|
bgColBorderSidesLeft,
|
||||||
bgColBorderSidesRight,
|
bgColBorderSidesRight,
|
||||||
bgNumCols
|
bgNumCols
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GtkListStore *backgrounds;
|
extern GtkListStore *backgrounds;
|
||||||
extern GtkWidget *current_background,
|
extern GtkWidget *current_background, *background_fill_color, *background_border_color, *background_gradient,
|
||||||
*background_fill_color,
|
*background_fill_color_over, *background_border_color_over, *background_gradient_over, *background_fill_color_press,
|
||||||
*background_border_color,
|
*background_border_color_press, *background_gradient_press, *background_border_width, *background_border_sides_top,
|
||||||
*background_gradient,
|
*background_border_sides_bottom, *background_border_sides_left, *background_border_sides_right,
|
||||||
*background_fill_color_over,
|
*background_corner_radius;
|
||||||
*background_border_color_over,
|
|
||||||
*background_gradient_over,
|
|
||||||
*background_fill_color_press,
|
|
||||||
*background_border_color_press,
|
|
||||||
*background_gradient_press,
|
|
||||||
*background_border_width,
|
|
||||||
*background_border_sides_top,
|
|
||||||
*background_border_sides_bottom,
|
|
||||||
*background_border_sides_left,
|
|
||||||
*background_border_sides_right,
|
|
||||||
*background_corner_radius;
|
|
||||||
|
|
||||||
// gradients
|
// gradients
|
||||||
enum {
|
enum { grColPixbuf = 0, grColId, grColText, grNumCols };
|
||||||
grColPixbuf = 0,
|
|
||||||
grColId,
|
|
||||||
grColText,
|
|
||||||
grNumCols
|
|
||||||
};
|
|
||||||
|
|
||||||
// gradient color stops
|
// gradient color stops
|
||||||
enum {
|
enum { grStopColPixbuf = 0, grStopNumCols };
|
||||||
grStopColPixbuf = 0,
|
|
||||||
grStopNumCols
|
|
||||||
};
|
|
||||||
extern GtkListStore *gradient_ids, *gradient_stop_ids;
|
extern GtkListStore *gradient_ids, *gradient_stop_ids;
|
||||||
extern GList *gradients;
|
extern GList *gradients;
|
||||||
|
|
||||||
extern GtkWidget *current_gradient,
|
extern GtkWidget *current_gradient, *gradient_combo_type, *gradient_start_color, *gradient_end_color,
|
||||||
*gradient_combo_type,
|
*current_gradient_stop, *gradient_stop_color, *gradient_stop_offset;
|
||||||
*gradient_start_color,
|
|
||||||
*gradient_end_color,
|
|
||||||
*current_gradient_stop,
|
|
||||||
*gradient_stop_color,
|
|
||||||
*gradient_stop_offset;
|
|
||||||
|
|
||||||
void background_create_new();
|
void background_create_new();
|
||||||
void background_force_update();
|
void background_force_update();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
char *get_current_theme_path();
|
char *get_current_theme_path();
|
||||||
gboolean config_is_manual(const char *path);
|
gboolean config_is_manual(const char *path);
|
||||||
void config_read_file (const char *path);
|
void config_read_file(const char *path);
|
||||||
void config_save_file(const char *path);
|
void config_save_file(const char *path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,203 +34,216 @@ gint theme_name_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpo
|
|||||||
|
|
||||||
GtkWidget *create_view()
|
GtkWidget *create_view()
|
||||||
{
|
{
|
||||||
GtkTreeViewColumn *col;
|
GtkTreeViewColumn *col;
|
||||||
GtkCellRenderer *renderer;
|
GtkCellRenderer *renderer;
|
||||||
|
|
||||||
theme_list_store =
|
theme_list_store = gtk_list_store_new(NB_COL,
|
||||||
gtk_list_store_new(NB_COL, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_INT, G_TYPE_INT, G_TYPE_BOOLEAN);
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
GDK_TYPE_PIXBUF,
|
||||||
|
G_TYPE_INT,
|
||||||
|
G_TYPE_INT,
|
||||||
|
G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
GtkWidget *view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(theme_list_store));
|
GtkWidget *view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(theme_list_store));
|
||||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE);
|
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE);
|
||||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
|
||||||
|
|
||||||
g_object_unref(theme_list_store); // destroy store automatically with view
|
g_object_unref(theme_list_store); // destroy store automatically with view
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new();
|
renderer = gtk_cell_renderer_text_new();
|
||||||
col = gtk_tree_view_column_new();
|
col = gtk_tree_view_column_new();
|
||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_THEME_FILE);
|
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_THEME_FILE);
|
||||||
gtk_tree_view_column_set_visible(col, FALSE);
|
gtk_tree_view_column_set_visible(col, FALSE);
|
||||||
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new();
|
renderer = gtk_cell_renderer_text_new();
|
||||||
col = gtk_tree_view_column_new();
|
col = gtk_tree_view_column_new();
|
||||||
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_THEME_NAME);
|
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_THEME_NAME);
|
||||||
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
||||||
|
|
||||||
g_renderer = gtk_cell_renderer_pixbuf_new();
|
g_renderer = gtk_cell_renderer_pixbuf_new();
|
||||||
g_object_set(g_renderer, "xalign", 0.0, NULL);
|
g_object_set(g_renderer, "xalign", 0.0, NULL);
|
||||||
gtk_cell_renderer_set_fixed_size(g_renderer, 200, 30);
|
gtk_cell_renderer_set_fixed_size(g_renderer, 200, 30);
|
||||||
col = gtk_tree_view_column_new();
|
col = gtk_tree_view_column_new();
|
||||||
gtk_tree_view_column_pack_start(col, g_renderer, TRUE);
|
gtk_tree_view_column_pack_start(col, g_renderer, TRUE);
|
||||||
gtk_tree_view_column_add_attribute(col, g_renderer, "pixbuf", COL_SNAPSHOT);
|
gtk_tree_view_column_add_attribute(col, g_renderer, "pixbuf", COL_SNAPSHOT);
|
||||||
gtk_tree_view_column_add_attribute(col, g_renderer, "width", COL_WIDTH);
|
gtk_tree_view_column_add_attribute(col, g_renderer, "width", COL_WIDTH);
|
||||||
gtk_tree_view_column_add_attribute(col, g_renderer, "height", COL_HEIGHT);
|
gtk_tree_view_column_add_attribute(col, g_renderer, "height", COL_HEIGHT);
|
||||||
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
|
||||||
|
|
||||||
GtkTreeSortable *sortable = GTK_TREE_SORTABLE(theme_list_store);
|
GtkTreeSortable *sortable = GTK_TREE_SORTABLE(theme_list_store);
|
||||||
gtk_tree_sortable_set_sort_column_id(sortable, COL_THEME_FILE, GTK_SORT_ASCENDING);
|
gtk_tree_sortable_set_sort_column_id(sortable, COL_THEME_FILE, GTK_SORT_ASCENDING);
|
||||||
gtk_tree_sortable_set_sort_func(sortable, COL_THEME_FILE, theme_name_compare, NULL, NULL);
|
gtk_tree_sortable_set_sort_func(sortable, COL_THEME_FILE, theme_name_compare, NULL, NULL);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
gint theme_name_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
gint theme_name_compare(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
|
||||||
{
|
{
|
||||||
gchar *path_a, *path_b;
|
gchar *path_a, *path_b;
|
||||||
gtk_tree_model_get(model, a, COL_THEME_FILE, &path_a, -1);
|
gtk_tree_model_get(model, a, COL_THEME_FILE, &path_a, -1);
|
||||||
gtk_tree_model_get(model, b, COL_THEME_FILE, &path_b, -1);
|
gtk_tree_model_get(model, b, COL_THEME_FILE, &path_b, -1);
|
||||||
|
|
||||||
gboolean home_a = strstr(path_a, g_get_user_config_dir()) == path_a;
|
gboolean home_a = strstr(path_a, g_get_user_config_dir()) == path_a;
|
||||||
gboolean home_b = strstr(path_b, g_get_user_config_dir()) == path_b;
|
gboolean home_b = strstr(path_b, g_get_user_config_dir()) == path_b;
|
||||||
|
|
||||||
if (home_a && !home_b)
|
if (home_a && !home_b)
|
||||||
return -1;
|
return -1;
|
||||||
if (!home_a && home_b)
|
if (!home_a && home_b)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
gchar *name_a = path_a;
|
gchar *name_a = path_a;
|
||||||
gchar *p;
|
gchar *p;
|
||||||
for (p = name_a; *p; p++) {
|
for (p = name_a; *p; p++) {
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
name_a = p + 1;
|
name_a = p + 1;
|
||||||
}
|
}
|
||||||
gchar *name_b = path_b;
|
gchar *name_b = path_b;
|
||||||
for (p = name_b; *p; p++) {
|
for (p = name_b; *p; p++) {
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
name_b = p + 1;
|
name_b = p + 1;
|
||||||
}
|
}
|
||||||
if (g_str_equal(name_a, name_b))
|
if (g_str_equal(name_a, name_b))
|
||||||
return 0;
|
return 0;
|
||||||
if (g_str_equal(name_a, "tint2rc"))
|
if (g_str_equal(name_a, "tint2rc"))
|
||||||
return -1;
|
return -1;
|
||||||
if (g_str_equal(name_b, "tint2rc"))
|
if (g_str_equal(name_b, "tint2rc"))
|
||||||
return 1;
|
return 1;
|
||||||
gint result = strnatcasecmp(name_a, name_b);
|
gint result = strnatcasecmp(name_a, name_b);
|
||||||
g_free(path_a);
|
g_free(path_a);
|
||||||
g_free(path_b);
|
g_free(path_b);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean theme_list_contains(const char *given_path)
|
gboolean theme_list_contains(const char *given_path)
|
||||||
{
|
{
|
||||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(g_theme_view));
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(g_theme_view));
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
gboolean have_iter = gtk_tree_model_get_iter_first(model, &iter);
|
gboolean have_iter = gtk_tree_model_get_iter_first(model, &iter);
|
||||||
while (have_iter) {
|
while (have_iter) {
|
||||||
gchar *filepath;
|
gchar *filepath;
|
||||||
gtk_tree_model_get(model, &iter, COL_THEME_FILE, &filepath, -1);
|
gtk_tree_model_get(model, &iter, COL_THEME_FILE, &filepath, -1);
|
||||||
if (g_str_equal(filepath, given_path)) {
|
if (g_str_equal(filepath, given_path)) {
|
||||||
gtk_list_store_set(theme_list_store, &iter, COL_SNAPSHOT, NULL, -1);
|
gtk_list_store_set(theme_list_store, &iter, COL_SNAPSHOT, NULL, -1);
|
||||||
g_free(filepath);
|
g_free(filepath);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
g_free(filepath);
|
g_free(filepath);
|
||||||
have_iter = gtk_tree_model_iter_next(model, &iter);
|
have_iter = gtk_tree_model_iter_next(model, &iter);
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void theme_list_append(const gchar *path)
|
void theme_list_append(const gchar *path)
|
||||||
{
|
{
|
||||||
if (theme_list_contains(path))
|
if (theme_list_contains(path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
gtk_list_store_append(theme_list_store, &iter);
|
gtk_list_store_append(theme_list_store, &iter);
|
||||||
|
|
||||||
gchar *name = strrchr(path, '/') + 1;
|
gchar *name = strrchr(path, '/') + 1;
|
||||||
|
|
||||||
gchar *dir = g_strdup(path);
|
gchar *dir = g_strdup(path);
|
||||||
strrchr(dir, '/')[0] = 0;
|
strrchr(dir, '/')[0] = 0;
|
||||||
char *suffix = contract_tilde(dir);
|
char *suffix = contract_tilde(dir);
|
||||||
g_free(dir);
|
g_free(dir);
|
||||||
|
|
||||||
gchar *display_name = g_strdup_printf("%s\n(%s)", name, suffix);
|
gchar *display_name = g_strdup_printf("%s\n(%s)", name, suffix);
|
||||||
gtk_list_store_set(theme_list_store, &iter, COL_THEME_FILE, path, COL_THEME_NAME, display_name, COL_FORCE_REFRESH, FALSE, -1);
|
gtk_list_store_set(theme_list_store,
|
||||||
g_free(display_name);
|
&iter,
|
||||||
g_free(suffix);
|
COL_THEME_FILE,
|
||||||
|
path,
|
||||||
|
COL_THEME_NAME,
|
||||||
|
display_name,
|
||||||
|
COL_FORCE_REFRESH,
|
||||||
|
FALSE,
|
||||||
|
-1);
|
||||||
|
g_free(display_name);
|
||||||
|
g_free(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean update_snapshot(gpointer ignored)
|
gboolean update_snapshot(gpointer ignored)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
gchar *tint2_cache_dir = g_build_filename(g_get_user_cache_dir(), "tint2", NULL);
|
gchar *tint2_cache_dir = g_build_filename(g_get_user_cache_dir(), "tint2", NULL);
|
||||||
if (!g_file_test(tint2_cache_dir, G_FILE_TEST_IS_DIR))
|
if (!g_file_test(tint2_cache_dir, G_FILE_TEST_IS_DIR))
|
||||||
g_mkdir(tint2_cache_dir, 0700);
|
g_mkdir(tint2_cache_dir, 0700);
|
||||||
g_free(tint2_cache_dir);
|
g_free(tint2_cache_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gint PADDING = 20;
|
const gint PADDING = 20;
|
||||||
|
|
||||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(g_theme_view));
|
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(g_theme_view));
|
||||||
|
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
gboolean have_iter;
|
gboolean have_iter;
|
||||||
|
|
||||||
int num_updates = 0;
|
int num_updates = 0;
|
||||||
gboolean need_pls_wait = FALSE;
|
gboolean need_pls_wait = FALSE;
|
||||||
|
|
||||||
have_iter = gtk_tree_model_get_iter_first(model, &iter);
|
have_iter = gtk_tree_model_get_iter_first(model, &iter);
|
||||||
while (have_iter) {
|
while (have_iter) {
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
gtk_tree_model_get(model, &iter, COL_SNAPSHOT, &pixbuf, -1);
|
gtk_tree_model_get(model, &iter, COL_SNAPSHOT, &pixbuf, -1);
|
||||||
if (pixbuf) {
|
if (pixbuf) {
|
||||||
g_object_unref(pixbuf);
|
g_object_unref(pixbuf);
|
||||||
have_iter = gtk_tree_model_iter_next(model, &iter);
|
have_iter = gtk_tree_model_iter_next(model, &iter);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar *path;
|
gchar *path;
|
||||||
gboolean force_refresh;
|
gboolean force_refresh;
|
||||||
gtk_tree_model_get(model, &iter, COL_THEME_FILE, &path, COL_FORCE_REFRESH, &force_refresh, -1);
|
gtk_tree_model_get(model, &iter, COL_THEME_FILE, &path, COL_FORCE_REFRESH, &force_refresh, -1);
|
||||||
|
|
||||||
char hash[MD4_HEX_SIZE + 4];
|
char hash[MD4_HEX_SIZE + 4];
|
||||||
md4hexf(path, hash);
|
md4hexf(path, hash);
|
||||||
strcat(hash, ".png");
|
strcat(hash, ".png");
|
||||||
|
|
||||||
gchar *snap = g_build_filename(g_get_user_cache_dir(), "tint2", hash, NULL);
|
gchar *snap = g_build_filename(g_get_user_cache_dir(), "tint2", hash, NULL);
|
||||||
pixbuf = force_refresh ? NULL : gdk_pixbuf_new_from_file(snap, NULL);
|
pixbuf = force_refresh ? NULL : gdk_pixbuf_new_from_file(snap, NULL);
|
||||||
if (!pixbuf) {
|
if (!pixbuf) {
|
||||||
gchar *cmd = g_strdup_printf("tint2 -c \'%s\' -s \'%s\' 1>/dev/null 2>/dev/null", path, snap);
|
gchar *cmd = g_strdup_printf("tint2 -c \'%s\' -s \'%s\' 1>/dev/null 2>/dev/null", path, snap);
|
||||||
num_updates++;
|
num_updates++;
|
||||||
if (num_updates > 3 && !need_pls_wait) {
|
if (num_updates > 3 && !need_pls_wait) {
|
||||||
need_pls_wait = TRUE;
|
need_pls_wait = TRUE;
|
||||||
create_please_wait(GTK_WINDOW(g_window));
|
create_please_wait(GTK_WINDOW(g_window));
|
||||||
}
|
}
|
||||||
if (system(cmd) == 0) {
|
if (system(cmd) == 0) {
|
||||||
// load
|
// load
|
||||||
pixbuf = gdk_pixbuf_new_from_file(snap, NULL);
|
pixbuf = gdk_pixbuf_new_from_file(snap, NULL);
|
||||||
}
|
}
|
||||||
g_free(cmd);
|
g_free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(snap);
|
g_free(snap);
|
||||||
g_free(path);
|
g_free(path);
|
||||||
|
|
||||||
gtk_list_store_set(theme_list_store,
|
gtk_list_store_set(theme_list_store,
|
||||||
&iter,
|
&iter,
|
||||||
COL_SNAPSHOT,
|
COL_SNAPSHOT,
|
||||||
pixbuf,
|
pixbuf,
|
||||||
COL_WIDTH,
|
COL_WIDTH,
|
||||||
gdk_pixbuf_get_width(pixbuf) + PADDING,
|
gdk_pixbuf_get_width(pixbuf) + PADDING,
|
||||||
COL_HEIGHT,
|
COL_HEIGHT,
|
||||||
gdk_pixbuf_get_height(pixbuf) + PADDING,
|
gdk_pixbuf_get_height(pixbuf) + PADDING,
|
||||||
COL_FORCE_REFRESH,
|
COL_FORCE_REFRESH,
|
||||||
FALSE,
|
FALSE,
|
||||||
-1);
|
-1);
|
||||||
if (pixbuf)
|
if (pixbuf)
|
||||||
g_object_unref(pixbuf);
|
g_object_unref(pixbuf);
|
||||||
|
|
||||||
if (need_pls_wait)
|
if (need_pls_wait)
|
||||||
process_events();
|
process_events();
|
||||||
|
|
||||||
have_iter = gtk_tree_model_iter_next(model, &iter);
|
have_iter = gtk_tree_model_iter_next(model, &iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_pls_wait)
|
if (need_pls_wait)
|
||||||
destroy_please_wait();
|
destroy_please_wait();
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,15 @@
|
|||||||
|
|
||||||
extern GtkWidget *g_theme_view;
|
extern GtkWidget *g_theme_view;
|
||||||
extern GtkListStore *theme_list_store;
|
extern GtkListStore *theme_list_store;
|
||||||
enum { COL_THEME_FILE = 0,
|
enum {
|
||||||
COL_THEME_NAME,
|
COL_THEME_FILE = 0,
|
||||||
COL_SNAPSHOT,
|
COL_THEME_NAME,
|
||||||
COL_WIDTH,
|
COL_SNAPSHOT,
|
||||||
COL_HEIGHT,
|
COL_WIDTH,
|
||||||
COL_FORCE_REFRESH,
|
COL_HEIGHT,
|
||||||
NB_COL, };
|
COL_FORCE_REFRESH,
|
||||||
|
NB_COL,
|
||||||
|
};
|
||||||
|
|
||||||
GtkWidget *create_view();
|
GtkWidget *create_view();
|
||||||
|
|
||||||
|
|||||||
666
src/tint2rc.c
666
src/tint2rc.c
@@ -1,411 +1,261 @@
|
|||||||
#include "tint2rc.h"
|
#include "tint2rc.h"
|
||||||
|
|
||||||
unsigned char themes_tint2rc[] = {
|
unsigned char themes_tint2rc[] =
|
||||||
0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61,
|
{0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20,
|
||||||
0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x69, 0x6e, 0x74, 0x32,
|
0x74, 0x69, 0x6e, 0x74, 0x32, 0x63, 0x6f, 0x6e, 0x66, 0x20, 0x32, 0x36, 0x34, 0x31, 0x20, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x63, 0x6f, 0x6e, 0x66, 0x20, 0x32, 0x36, 0x34, 0x31, 0x20, 0x2d, 0x2d,
|
0x0a, 0x23, 0x20, 0x53, 0x65, 0x65, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x6c,
|
||||||
0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x53, 0x65, 0x65, 0x20, 0x68, 0x74, 0x74,
|
0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x39, 0x30, 0x30, 0x30, 0x2f, 0x74, 0x69, 0x6e, 0x74, 0x32, 0x2f,
|
||||||
0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e,
|
0x77, 0x69, 0x6b, 0x69, 0x73, 0x2f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72,
|
||||||
0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x39, 0x30, 0x30, 0x30, 0x2f, 0x74, 0x69,
|
0x20, 0x0a, 0x23, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74,
|
||||||
0x6e, 0x74, 0x32, 0x2f, 0x77, 0x69, 0x6b, 0x69, 0x73, 0x2f, 0x43, 0x6f,
|
0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
|
||||||
0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20,
|
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x23, 0x2d, 0x2d, 0x2d,
|
||||||
0x0a, 0x23, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x64, 0x6f, 0x63, 0x75,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x42,
|
||||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
|
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72,
|
||||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f,
|
0x6f, 0x75, 0x6e, 0x64, 0x20, 0x31, 0x3a, 0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
||||||
0x6e, 0x73, 0x2e, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x65, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x20, 0x3d, 0x20, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x36, 0x30, 0x0a, 0x62, 0x6f, 0x72,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63,
|
0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x0a, 0x23, 0x20, 0x42,
|
0x20, 0x33, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
||||||
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x31, 0x3a,
|
0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x36,
|
||||||
0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65,
|
||||||
0x65, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65,
|
0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x33, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b,
|
||||||
0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x30, 0x0a,
|
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65,
|
||||||
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63,
|
0x64, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x36, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64,
|
||||||
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30,
|
0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20,
|
||||||
0x30, 0x30, 0x20, 0x36, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x33, 0x30, 0x0a, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x67,
|
||||||
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30,
|
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x32, 0x3a, 0x20, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x61,
|
||||||
0x30, 0x30, 0x30, 0x30, 0x20, 0x33, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b,
|
0x73, 0x6b, 0x2c, 0x20, 0x49, 0x63, 0x6f, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x0a,
|
||||||
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
|
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f,
|
||||||
0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30,
|
0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e,
|
||||||
0x30, 0x30, 0x30, 0x30, 0x20, 0x36, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64,
|
0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x20, 0x32,
|
||||||
0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76,
|
0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x37,
|
||||||
0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
0x37, 0x37, 0x37, 0x37, 0x37, 0x20, 0x33, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
||||||
0x20, 0x33, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75,
|
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x61,
|
||||||
0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65,
|
0x61, 0x61, 0x61, 0x20, 0x32, 0x32, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
|
||||||
0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30,
|
0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34, 0x34,
|
||||||
0x30, 0x30, 0x20, 0x36, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70,
|
||||||
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73,
|
0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x20, 0x34, 0x0a,
|
||||||
0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65,
|
||||||
0x20, 0x33, 0x30, 0x0a, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x67,
|
0x64, 0x20, 0x3d, 0x20, 0x23, 0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34, 0x34, 0x0a, 0x0a, 0x23, 0x20, 0x42,
|
||||||
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x32, 0x3a, 0x20, 0x44, 0x65, 0x66,
|
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x33, 0x3a, 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65,
|
||||||
0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x2c, 0x20, 0x49,
|
0x20, 0x74, 0x61, 0x73, 0x6b, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x34, 0x0a, 0x62,
|
||||||
0x63, 0x6f, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x74, 0x61, 0x73,
|
0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x63,
|
||||||
0x6b, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20,
|
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x37, 0x37,
|
||||||
0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64,
|
0x37, 0x37, 0x37, 0x37, 0x20, 0x32, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
||||||
0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67,
|
0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x34, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b,
|
||||||
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20,
|
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20,
|
||||||
0x3d, 0x20, 0x23, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x20, 0x32, 0x30,
|
0x3d, 0x20, 0x23, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x20, 0x32, 0x32, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
||||||
0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x65, 0x61, 0x65,
|
||||||
0x72, 0x20, 0x3d, 0x20, 0x23, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x20,
|
0x61, 0x65, 0x61, 0x20, 0x34, 0x34, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63,
|
||||||
0x33, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e,
|
0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x35, 0x35, 0x35,
|
||||||
0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65,
|
0x35, 0x35, 0x35, 0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f,
|
||||||
0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x20,
|
0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34,
|
||||||
0x32, 0x32, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f,
|
0x34, 0x0a, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x34, 0x3a, 0x20,
|
||||||
0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20,
|
0x55, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x61, 0x73, 0x6b, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64,
|
||||||
0x23, 0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34, 0x34, 0x0a, 0x62,
|
0x20, 0x3d, 0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d,
|
||||||
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f,
|
0x20, 0x31, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
|
||||||
0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20,
|
0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x34, 0x34, 0x30, 0x30, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64,
|
||||||
0x3d, 0x20, 0x23, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x20, 0x34, 0x0a,
|
0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x37, 0x37, 0x33, 0x33, 0x20,
|
||||||
0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
|
0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
||||||
0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23,
|
0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x63, 0x63, 0x37, 0x37, 0x30, 0x30, 0x20, 0x31,
|
||||||
0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34, 0x34, 0x0a, 0x0a, 0x23,
|
0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76,
|
||||||
0x20, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20,
|
0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x37, 0x37, 0x33, 0x33, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61,
|
||||||
0x33, 0x3a, 0x20, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x74, 0x61,
|
0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73,
|
||||||
0x73, 0x6b, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x3d,
|
0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72,
|
||||||
0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77, 0x69,
|
0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d,
|
||||||
0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x63, 0x6b,
|
0x20, 0x23, 0x61, 0x61, 0x37, 0x37, 0x33, 0x33, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63,
|
||||||
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72,
|
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x35, 0x3a, 0x20, 0x54, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x0a,
|
||||||
0x20, 0x3d, 0x20, 0x23, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x20, 0x32,
|
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f,
|
||||||
0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c,
|
0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e,
|
||||||
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x61, 0x61, 0x20, 0x31,
|
||||||
0x20, 0x34, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75,
|
0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23,
|
||||||
0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76,
|
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75,
|
||||||
0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
|
0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66,
|
||||||
0x20, 0x32, 0x32, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63,
|
0x66, 0x66, 0x66, 0x61, 0x61, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f,
|
||||||
0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d,
|
0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||||
0x20, 0x23, 0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34, 0x34, 0x0a,
|
0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c,
|
||||||
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63,
|
0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x61,
|
||||||
0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
|
0x61, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f,
|
||||||
0x20, 0x3d, 0x20, 0x23, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x20, 0x34,
|
0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x31,
|
||||||
0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
0x30, 0x30, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x23, 0x65, 0x61, 0x65, 0x61, 0x65, 0x61, 0x20, 0x34, 0x34, 0x0a, 0x0a,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f,
|
||||||
0x23, 0x20, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
0x69, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x4c, 0x54, 0x53, 0x43, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f,
|
||||||
0x20, 0x34, 0x3a, 0x20, 0x55, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x20, 0x74,
|
0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x25, 0x20, 0x33, 0x30, 0x0a, 0x70, 0x61, 0x6e, 0x65,
|
||||||
0x61, 0x73, 0x6b, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x20,
|
0x6c, 0x5f, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x30, 0x0a, 0x70, 0x61, 0x6e, 0x65,
|
||||||
0x3d, 0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77,
|
0x6c, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32, 0x20, 0x30, 0x20, 0x32, 0x0a, 0x70,
|
||||||
0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x63,
|
0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20,
|
||||||
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
0x3d, 0x20, 0x31, 0x0a, 0x77, 0x6d, 0x5f, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x70, 0x61, 0x6e,
|
||||||
0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x34, 0x34, 0x30, 0x30, 0x20,
|
0x65, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x70,
|
||||||
0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x63,
|
0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x63, 0x65,
|
||||||
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x37, 0x37,
|
0x6e, 0x74, 0x65, 0x72, 0x20, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x0a, 0x70, 0x61, 0x6e,
|
||||||
0x33, 0x33, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67,
|
0x65, 0x6c, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x70, 0x0a, 0x70, 0x61, 0x6e, 0x65,
|
||||||
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f,
|
0x6c, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x6c, 0x6c, 0x0a, 0x70, 0x72, 0x69,
|
||||||
0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x63, 0x63, 0x37,
|
0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x5f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20,
|
||||||
0x37, 0x30, 0x30, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64,
|
0x3d, 0x20, 0x30, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x68, 0x69, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x61, 0x75,
|
||||||
0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x76,
|
0x74, 0x6f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
|
||||||
0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x37, 0x37, 0x33, 0x33,
|
0x20, 0x3d, 0x20, 0x30, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x68, 0x69, 0x64, 0x65, 0x5f,
|
||||||
0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f,
|
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x68,
|
||||||
0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72,
|
0x69, 0x64, 0x65, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x32, 0x0a, 0x73, 0x74, 0x72, 0x75,
|
||||||
0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x35, 0x35, 0x35,
|
0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x3d, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73,
|
||||||
0x35, 0x35, 0x35, 0x20, 0x34, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
0x69, 0x7a, 0x65, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x6e, 0x61,
|
||||||
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73,
|
0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x69, 0x6e, 0x74, 0x32, 0x0a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f,
|
||||||
0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x61, 0x37, 0x37, 0x33, 0x33,
|
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x6d, 0x6f,
|
||||||
0x20, 0x31, 0x30, 0x30, 0x0a, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x63, 0x6b,
|
0x75, 0x73, 0x65, 0x5f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x66, 0x6f, 0x6e,
|
||||||
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x35, 0x3a, 0x20, 0x54, 0x6f,
|
0x74, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f,
|
||||||
0x6f, 0x6c, 0x74, 0x69, 0x70, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65,
|
0x68, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x31, 0x30,
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
0x30, 0x20, 0x30, 0x20, 0x31, 0x30, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65,
|
||||||
0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62,
|
0x64, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x20, 0x30, 0x20,
|
||||||
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f,
|
0x30, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x61,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x61, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x54, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62,
|
||||||
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30,
|
0x61, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x64, 0x65,
|
||||||
0x30, 0x30, 0x30, 0x30, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63,
|
0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
|
||||||
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x30, 0x20, 0x32, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f,
|
||||||
0x72, 0x5f, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66,
|
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74,
|
||||||
0x66, 0x66, 0x66, 0x61, 0x61, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f,
|
0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67,
|
||||||
0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x68,
|
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61,
|
||||||
0x6f, 0x76, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30, 0x30, 0x30,
|
0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f,
|
||||||
0x30, 0x30, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x67,
|
0x68, 0x69, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73,
|
||||||
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f,
|
0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x64,
|
||||||
0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x66,
|
0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x3d, 0x20,
|
||||||
0x66, 0x66, 0x66, 0x61, 0x61, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x6f,
|
0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x5f, 0x73, 0x68,
|
||||||
0x72, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x5f, 0x70,
|
0x6f, 0x77, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x74, 0x61, 0x73, 0x6b,
|
||||||
0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x23, 0x30, 0x30,
|
0x73, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f,
|
||||||
0x30, 0x30, 0x30, 0x30, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x0a, 0x23, 0x2d,
|
0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x34, 0x20, 0x32, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f,
|
||||||
0x0a, 0x23, 0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x0a, 0x70, 0x61, 0x6e,
|
0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x65, 0x6c, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x4c,
|
0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x65, 0x33, 0x65, 0x33,
|
||||||
0x54, 0x53, 0x43, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x73, 0x69,
|
0x65, 0x33, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
|
||||||
0x7a, 0x65, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x25, 0x20, 0x33, 0x30,
|
0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20,
|
||||||
0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x6d, 0x61, 0x72, 0x67, 0x69,
|
0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62,
|
||||||
0x6e, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x30, 0x0a, 0x70, 0x61, 0x6e, 0x65,
|
0x61, 0x72, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x20,
|
||||||
0x6c, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20,
|
0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x72,
|
||||||
0x32, 0x20, 0x30, 0x20, 0x32, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f,
|
0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x61, 0x6c, 0x69,
|
||||||
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69,
|
0x67, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x77, 0x6d, 0x5f, 0x6d, 0x65, 0x6e,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x75, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x54, 0x61, 0x73, 0x6b, 0x0a,
|
||||||
0x64, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x70, 0x61, 0x6e,
|
0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f,
|
||||||
0x65, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20,
|
0x69, 0x63, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x63, 0x65, 0x6e, 0x74, 0x65,
|
||||||
0x3d, 0x20, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x63, 0x65, 0x6e,
|
0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x75, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x62, 0x5f, 0x6f,
|
||||||
0x74, 0x65, 0x72, 0x20, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74,
|
0x66, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x74, 0x61,
|
||||||
0x61, 0x6c, 0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x6c, 0x61, 0x79,
|
0x73, 0x6b, 0x5f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x31,
|
||||||
0x65, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x70, 0x0a, 0x70, 0x61, 0x6e,
|
0x35, 0x30, 0x20, 0x33, 0x35, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20,
|
||||||
0x65, 0x6c, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x3d,
|
0x3d, 0x20, 0x32, 0x20, 0x32, 0x20, 0x34, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69,
|
||||||
0x20, 0x61, 0x6c, 0x6c, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79,
|
0x70, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c,
|
||||||
0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x5f, 0x66, 0x69, 0x72,
|
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x74, 0x61,
|
||||||
0x73, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x68,
|
0x73, 0x6b, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20,
|
||||||
0x69, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x61, 0x75, 0x74, 0x6f,
|
0x32, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67,
|
||||||
0x68, 0x69, 0x64, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x74, 0x69,
|
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x33, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x75,
|
||||||
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x61, 0x75,
|
0x72, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64,
|
||||||
0x74, 0x6f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x68, 0x69, 0x64, 0x65, 0x5f,
|
0x20, 0x3d, 0x20, 0x34, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64,
|
||||||
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e,
|
0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x32, 0x0a,
|
||||||
0x35, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x68,
|
0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65,
|
||||||
0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x32, 0x0a, 0x73, 0x74,
|
0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x69, 0x66, 0x79, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x69, 0x64, 0x64,
|
||||||
0x72, 0x75, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x3d,
|
0x6c, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x72, 0x69, 0x67,
|
||||||
0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65,
|
0x68, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x73, 0x63,
|
||||||
0x0a, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f,
|
0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x75, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x0a, 0x6d, 0x6f,
|
||||||
0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x69, 0x6e,
|
0x75, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x3d, 0x20, 0x69,
|
||||||
0x74, 0x32, 0x0a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74,
|
0x63, 0x6f, 0x6e, 0x69, 0x66, 0x79, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x20,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x3d, 0x20, 0x31, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x65, 0x66,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74,
|
||||||
0x66, 0x65, 0x63, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x66, 0x6f,
|
0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61,
|
||||||
0x6e, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20,
|
0x72, 0x65, 0x61, 0x29, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x72, 0x61, 0x79, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e,
|
||||||
0x30, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x68, 0x6f, 0x76, 0x65,
|
0x67, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x34, 0x20, 0x32, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x72, 0x61, 0x79, 0x5f, 0x62,
|
||||||
0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x62, 0x20, 0x3d,
|
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x73, 0x79,
|
||||||
0x20, 0x31, 0x30, 0x30, 0x20, 0x30, 0x20, 0x31, 0x30, 0x0a, 0x6d, 0x6f,
|
0x73, 0x74, 0x72, 0x61, 0x79, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64,
|
||||||
0x75, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f,
|
0x69, 0x6e, 0x67, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x69,
|
||||||
0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x31,
|
0x7a, 0x65, 0x20, 0x3d, 0x20, 0x32, 0x34, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x63, 0x6f,
|
||||||
0x30, 0x30, 0x20, 0x30, 0x20, 0x30, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d,
|
0x6e, 0x5f, 0x61, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x20, 0x30, 0x20, 0x30, 0x0a, 0x73, 0x79, 0x73,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x74, 0x72, 0x61, 0x79, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x0a, 0x23,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
|
||||||
0x20, 0x54, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x0a, 0x74, 0x61, 0x73,
|
0x23, 0x20, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72,
|
||||||
0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20,
|
0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32, 0x20, 0x34, 0x20, 0x32, 0x0a, 0x6c, 0x61,
|
||||||
0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74,
|
0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69,
|
||||||
0x6f, 0x70, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x70,
|
0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e,
|
||||||
0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x30,
|
0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a,
|
||||||
0x20, 0x32, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x62,
|
0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x20,
|
||||||
0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64,
|
0x3d, 0x20, 0x32, 0x34, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f,
|
||||||
0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72,
|
0x61, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x20, 0x30, 0x20, 0x30, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63,
|
||||||
0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b,
|
0x68, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x5f, 0x6f, 0x76, 0x65, 0x72,
|
||||||
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20,
|
0x72, 0x69, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x6e, 0x6f,
|
||||||
0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61,
|
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x6c, 0x61, 0x75,
|
||||||
0x6d, 0x65, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62,
|
0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x6c,
|
||||||
0x61, 0x72, 0x5f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x61, 0x63,
|
0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x20, 0x3d, 0x20,
|
||||||
0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x20, 0x3d,
|
0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
|
||||||
0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x68,
|
0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x74, 0x69, 0x6e, 0x74, 0x32, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x64, 0x65, 0x73, 0x6b,
|
||||||
0x69, 0x64, 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e,
|
0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61,
|
||||||
0x74, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x20, 0x3d, 0x20,
|
0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x73, 0x68, 0x61,
|
||||||
0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x61, 0x6c,
|
0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x74, 0x69, 0x6e,
|
||||||
0x77, 0x61, 0x79, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x61, 0x6c,
|
0x74, 0x32, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75, 0x6e,
|
||||||
0x6c, 0x5f, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x5f, 0x74, 0x61,
|
0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73,
|
||||||
0x73, 0x6b, 0x73, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b,
|
0x72, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x64,
|
0x73, 0x2f, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x2e, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c,
|
||||||
0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x34, 0x20, 0x32, 0x0a, 0x74,
|
0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x20, 0x3d, 0x20,
|
||||||
0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f,
|
0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
|
||||||
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69,
|
0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x69, 0x63, 0x65, 0x77, 0x65, 0x61, 0x73, 0x65, 0x6c, 0x2e, 0x64, 0x65, 0x73, 0x6b,
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62, 0x61,
|
0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61,
|
||||||
0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76,
|
0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70,
|
||||||
0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69, 0x75, 0x6d, 0x2d,
|
||||||
0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b,
|
0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x2e, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75,
|
||||||
0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x6e,
|
0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75,
|
||||||
0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x65,
|
0x73, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||||
0x33, 0x65, 0x33, 0x65, 0x33, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x74, 0x61,
|
0x6e, 0x73, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2d, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x2e, 0x64, 0x65,
|
||||||
0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x61,
|
0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x0a, 0x74, 0x69, 0x6d,
|
||||||
0x66, 0x66, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x62,
|
0x65, 0x31, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x25, 0x48, 0x3a, 0x25, 0x4d, 0x0a, 0x74,
|
||||||
0x61, 0x72, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
|
0x69, 0x6d, 0x65, 0x32, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x25, 0x41, 0x20, 0x25, 0x64,
|
||||||
0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x74,
|
0x20, 0x25, 0x42, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x31, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x20,
|
||||||
0x61, 0x73, 0x6b, 0x62, 0x61, 0x72, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x5f,
|
0x3d, 0x20, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x32, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x20, 0x3d,
|
||||||
0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x6e, 0x65,
|
0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20,
|
||||||
0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x20,
|
0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b,
|
||||||
0x3d, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d,
|
0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32, 0x20, 0x30, 0x0a, 0x63, 0x6c, 0x6f, 0x63,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x6b, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x0a, 0x63,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23,
|
0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f,
|
||||||
0x20, 0x54, 0x61, 0x73, 0x6b, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x74,
|
0x6e, 0x65, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6c, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f,
|
||||||
0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61, 0x73, 0x6b,
|
0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x63,
|
||||||
0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x74, 0x61,
|
0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6f, 0x72, 0x61, 0x67,
|
||||||
0x73, 0x6b, 0x5f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20,
|
0x65, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6d, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
|
||||||
0x3d, 0x20, 0x31, 0x0a, 0x75, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x6e,
|
0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x75, 0x77, 0x68, 0x65, 0x65, 0x6c,
|
||||||
0x62, 0x5f, 0x6f, 0x66, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x3d,
|
0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64,
|
||||||
0x20, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b,
|
0x77, 0x68, 0x65, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x0a, 0x23,
|
||||||
0x5f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x73, 0x69, 0x7a,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x65, 0x20, 0x3d, 0x20, 0x31, 0x35, 0x30, 0x20, 0x33, 0x35, 0x0a, 0x74,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a,
|
||||||
0x61, 0x73, 0x6b, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20,
|
0x23, 0x20, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x74,
|
||||||
0x3d, 0x20, 0x32, 0x20, 0x32, 0x20, 0x34, 0x0a, 0x74, 0x61, 0x73, 0x6b,
|
0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f,
|
||||||
0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x31,
|
0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x0a, 0x62, 0x61, 0x74,
|
||||||
0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63,
|
0x74, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x6d, 0x64, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x74, 0x69,
|
||||||
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66,
|
0x66, 0x79, 0x2d, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x22, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x6f,
|
||||||
0x66, 0x66, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f,
|
0x77, 0x22, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c,
|
||||||
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69,
|
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x62, 0x61,
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x32, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x61,
|
0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x31, 0x20, 0x30,
|
||||||
0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72,
|
0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
||||||
0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x33, 0x0a,
|
0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x68, 0x69, 0x64,
|
||||||
0x74, 0x61, 0x73, 0x6b, 0x5f, 0x75, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x5f,
|
0x65, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x31, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x63, 0x6c,
|
||||||
0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69,
|
0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x62, 0x61, 0x74, 0x74,
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x34, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69,
|
0x65, 0x72, 0x79, 0x5f, 0x72, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20,
|
||||||
0x63, 0x6f, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x62, 0x61, 0x63,
|
0x3d, 0x20, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x6d, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63,
|
||||||
0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d,
|
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x75,
|
||||||
0x20, 0x32, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6c, 0x65, 0x66,
|
0x77, 0x68, 0x65, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x62, 0x61,
|
||||||
0x74, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x5f, 0x69,
|
0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x64, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
|
||||||
0x63, 0x6f, 0x6e, 0x69, 0x66, 0x79, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65,
|
0x64, 0x20, 0x3d, 0x20, 0x0a, 0x61, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63,
|
||||||
0x5f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x6f,
|
0x6d, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x61, 0x63, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
|
||||||
0x6e, 0x65, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x72, 0x69, 0x67,
|
0x65, 0x64, 0x5f, 0x63, 0x6d, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x68, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0a, 0x6d,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
||||||
0x6f, 0x75, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x5f,
|
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x54, 0x6f, 0x6f, 0x6c, 0x74,
|
||||||
0x75, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x0a,
|
0x69, 0x70, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x74, 0x69, 0x6d,
|
||||||
0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c,
|
0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f,
|
||||||
0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x3d, 0x20, 0x69, 0x63, 0x6f, 0x6e,
|
0x68, 0x69, 0x64, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x31, 0x0a,
|
||||||
0x69, 0x66, 0x79, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x20, 0x32, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x35, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x66,
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x53, 0x79,
|
0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
|
||||||
0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e,
|
0x20, 0x31, 0x30, 0x30, 0x0a, 0x0a};
|
||||||
0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
|
|
||||||
0x61, 0x72, 0x65, 0x61, 0x29, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x72, 0x61,
|
|
||||||
0x79, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20,
|
|
||||||
0x30, 0x20, 0x34, 0x20, 0x32, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x72, 0x61,
|
|
||||||
0x79, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
|
||||||
0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x73, 0x79, 0x73, 0x74,
|
|
||||||
0x72, 0x61, 0x79, 0x5f, 0x73, 0x6f, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x61,
|
|
||||||
0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x0a, 0x73, 0x79, 0x73,
|
|
||||||
0x74, 0x72, 0x61, 0x79, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x73, 0x69,
|
|
||||||
0x7a, 0x65, 0x20, 0x3d, 0x20, 0x32, 0x34, 0x0a, 0x73, 0x79, 0x73, 0x74,
|
|
||||||
0x72, 0x61, 0x79, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f, 0x61, 0x73, 0x62,
|
|
||||||
0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x20, 0x30, 0x20, 0x30, 0x0a, 0x73,
|
|
||||||
0x79, 0x73, 0x74, 0x72, 0x61, 0x79, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74,
|
|
||||||
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23,
|
|
||||||
0x20, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x0a, 0x6c, 0x61,
|
|
||||||
0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
|
|
||||||
0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32, 0x20, 0x34, 0x20, 0x32, 0x0a, 0x6c,
|
|
||||||
0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x62, 0x61, 0x63, 0x6b,
|
|
||||||
0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20,
|
|
||||||
0x30, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69,
|
|
||||||
0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75,
|
|
||||||
0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x6c, 0x61,
|
|
||||||
0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f,
|
|
||||||
0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x32, 0x34, 0x0a, 0x6c, 0x61,
|
|
||||||
0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x63, 0x6f, 0x6e, 0x5f,
|
|
||||||
0x61, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x20, 0x30, 0x20,
|
|
||||||
0x30, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69,
|
|
||||||
0x63, 0x6f, 0x6e, 0x5f, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x5f, 0x6f, 0x76,
|
|
||||||
0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x73,
|
|
||||||
0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66,
|
|
||||||
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x31,
|
|
||||||
0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x6f,
|
|
||||||
0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x6c, 0x61,
|
|
||||||
0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f,
|
|
||||||
0x61, 0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73,
|
|
||||||
0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
|
|
||||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x74, 0x69, 0x6e, 0x74, 0x32, 0x63,
|
|
||||||
0x6f, 0x6e, 0x66, 0x2e, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a,
|
|
||||||
0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65,
|
|
||||||
0x6d, 0x5f, 0x61, 0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72,
|
|
||||||
0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65,
|
|
||||||
0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
|
||||||
0x73, 0x2f, 0x74, 0x69, 0x6e, 0x74, 0x32, 0x63, 0x6f, 0x6e, 0x66, 0x2e,
|
|
||||||
0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75, 0x6e,
|
|
||||||
0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70,
|
|
||||||
0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61,
|
|
||||||
0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
|
|
||||||
0x6f, 0x6e, 0x73, 0x2f, 0x66, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x2e,
|
|
||||||
0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75, 0x6e,
|
|
||||||
0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70,
|
|
||||||
0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61,
|
|
||||||
0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
|
|
||||||
0x6f, 0x6e, 0x73, 0x2f, 0x69, 0x63, 0x65, 0x77, 0x65, 0x61, 0x73, 0x65,
|
|
||||||
0x6c, 0x2e, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61,
|
|
||||||
0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f,
|
|
||||||
0x61, 0x70, 0x70, 0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73,
|
|
||||||
0x68, 0x61, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
|
|
||||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x69,
|
|
||||||
0x75, 0x6d, 0x2d, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x2e, 0x64,
|
|
||||||
0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x0a, 0x6c, 0x61, 0x75, 0x6e, 0x63,
|
|
||||||
0x68, 0x65, 0x72, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70, 0x70,
|
|
||||||
0x20, 0x3d, 0x20, 0x2f, 0x75, 0x73, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x72,
|
|
||||||
0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
|
||||||
0x6e, 0x73, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2d, 0x63, 0x68,
|
|
||||||
0x72, 0x6f, 0x6d, 0x65, 0x2e, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70,
|
|
||||||
0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x43, 0x6c, 0x6f, 0x63, 0x6b,
|
|
||||||
0x0a, 0x74, 0x69, 0x6d, 0x65, 0x31, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61,
|
|
||||||
0x74, 0x20, 0x3d, 0x20, 0x25, 0x48, 0x3a, 0x25, 0x4d, 0x0a, 0x74, 0x69,
|
|
||||||
0x6d, 0x65, 0x32, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d,
|
|
||||||
0x20, 0x25, 0x41, 0x20, 0x25, 0x64, 0x20, 0x25, 0x42, 0x0a, 0x74, 0x69,
|
|
||||||
0x6d, 0x65, 0x31, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65,
|
|
||||||
0x20, 0x3d, 0x20, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x32, 0x5f, 0x74, 0x69,
|
|
||||||
0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c,
|
|
||||||
0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c,
|
|
||||||
0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x20, 0x31, 0x30, 0x30, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x70,
|
|
||||||
0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32, 0x20, 0x30,
|
|
||||||
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67,
|
|
||||||
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30,
|
|
||||||
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x74,
|
|
||||||
0x69, 0x70, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
|
|
||||||
0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65,
|
|
||||||
0x7a, 0x6f, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63,
|
|
||||||
0x6b, 0x5f, 0x6c, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d,
|
|
||||||
0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x63, 0x6c, 0x6f, 0x63,
|
|
||||||
0x6b, 0x5f, 0x72, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d,
|
|
||||||
0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6f, 0x72, 0x61, 0x67, 0x65,
|
|
||||||
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6d, 0x63, 0x6c, 0x69, 0x63,
|
|
||||||
0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20,
|
|
||||||
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x75, 0x77, 0x68, 0x65, 0x65,
|
|
||||||
0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20,
|
|
||||||
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64, 0x77, 0x68, 0x65, 0x65,
|
|
||||||
0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20,
|
|
||||||
0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x42, 0x61, 0x74, 0x74, 0x65,
|
|
||||||
0x72, 0x79, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x74,
|
|
||||||
0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x62,
|
|
||||||
0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x6f, 0x77, 0x5f, 0x73,
|
|
||||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x0a, 0x62,
|
|
||||||
0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x6f, 0x77, 0x5f, 0x63,
|
|
||||||
0x6d, 0x64, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x2d,
|
|
||||||
0x73, 0x65, 0x6e, 0x64, 0x20, 0x22, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72,
|
|
||||||
0x79, 0x20, 0x6c, 0x6f, 0x77, 0x22, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65,
|
|
||||||
0x72, 0x79, 0x5f, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
|
|
||||||
0x72, 0x20, 0x3d, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x20,
|
|
||||||
0x31, 0x30, 0x30, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f,
|
|
||||||
0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x31, 0x20,
|
|
||||||
0x30, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x62, 0x61,
|
|
||||||
0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20,
|
|
||||||
0x3d, 0x20, 0x30, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f,
|
|
||||||
0x68, 0x69, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x31, 0x0a, 0x62,
|
|
||||||
0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x6c, 0x63, 0x6c, 0x69, 0x63,
|
|
||||||
0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20,
|
|
||||||
0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x63, 0x6c,
|
|
||||||
0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20,
|
|
||||||
0x3d, 0x20, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x5f, 0x6d,
|
|
||||||
0x63, 0x6c, 0x69, 0x63, 0x6b, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
|
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79,
|
|
||||||
0x5f, 0x75, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
|
|
||||||
0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x62, 0x61, 0x74, 0x74, 0x65,
|
|
||||||
0x72, 0x79, 0x5f, 0x64, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x5f, 0x63, 0x6f,
|
|
||||||
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x0a, 0x61, 0x63, 0x5f,
|
|
||||||
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6d,
|
|
||||||
0x64, 0x20, 0x3d, 0x20, 0x0a, 0x61, 0x63, 0x5f, 0x64, 0x69, 0x73, 0x63,
|
|
||||||
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6d, 0x64,
|
|
||||||
0x20, 0x3d, 0x20, 0x0a, 0x0a, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
|
|
||||||
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x23, 0x20, 0x54, 0x6f,
|
|
||||||
0x6f, 0x6c, 0x74, 0x69, 0x70, 0x0a, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69,
|
|
||||||
0x70, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f,
|
|
||||||
0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x0a, 0x74, 0x6f, 0x6f,
|
|
||||||
0x6c, 0x74, 0x69, 0x70, 0x5f, 0x68, 0x69, 0x64, 0x65, 0x5f, 0x74, 0x69,
|
|
||||||
0x6d, 0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x31, 0x0a,
|
|
||||||
0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x70, 0x61, 0x64, 0x64,
|
|
||||||
0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x32, 0x20, 0x32, 0x0a, 0x74, 0x6f,
|
|
||||||
0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72,
|
|
||||||
0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x35, 0x0a,
|
|
||||||
0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x5f, 0x66, 0x6f, 0x6e, 0x74,
|
|
||||||
0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x23, 0x32, 0x32,
|
|
||||||
0x32, 0x32, 0x32, 0x32, 0x20, 0x31, 0x30, 0x30, 0x0a, 0x0a
|
|
||||||
};
|
|
||||||
unsigned int themes_tint2rc_len = 4870;
|
unsigned int themes_tint2rc_len = 4870;
|
||||||
|
|||||||
@@ -41,290 +41,290 @@ Tooltip g_tooltip;
|
|||||||
|
|
||||||
void default_tooltip()
|
void default_tooltip()
|
||||||
{
|
{
|
||||||
// give the tooltip some reasonable default values
|
// give the tooltip some reasonable default values
|
||||||
memset(&g_tooltip, 0, sizeof(Tooltip));
|
memset(&g_tooltip, 0, sizeof(Tooltip));
|
||||||
|
|
||||||
g_tooltip.font_color.rgb[0] = 1;
|
g_tooltip.font_color.rgb[0] = 1;
|
||||||
g_tooltip.font_color.rgb[1] = 1;
|
g_tooltip.font_color.rgb[1] = 1;
|
||||||
g_tooltip.font_color.rgb[2] = 1;
|
g_tooltip.font_color.rgb[2] = 1;
|
||||||
g_tooltip.font_color.alpha = 1;
|
g_tooltip.font_color.alpha = 1;
|
||||||
just_shown = FALSE;
|
just_shown = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_tooltip()
|
void cleanup_tooltip()
|
||||||
{
|
{
|
||||||
stop_tooltip_timeout();
|
stop_tooltip_timeout();
|
||||||
tooltip_hide(NULL);
|
tooltip_hide(NULL);
|
||||||
tooltip_copy_text(NULL);
|
tooltip_copy_text(NULL);
|
||||||
if (g_tooltip.window)
|
if (g_tooltip.window)
|
||||||
XDestroyWindow(server.display, g_tooltip.window);
|
XDestroyWindow(server.display, g_tooltip.window);
|
||||||
g_tooltip.window = 0;
|
g_tooltip.window = 0;
|
||||||
pango_font_description_free(g_tooltip.font_desc);
|
pango_font_description_free(g_tooltip.font_desc);
|
||||||
g_tooltip.font_desc = NULL;
|
g_tooltip.font_desc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_tooltip()
|
void init_tooltip()
|
||||||
{
|
{
|
||||||
if (!g_tooltip.bg)
|
if (!g_tooltip.bg)
|
||||||
g_tooltip.bg = &g_array_index(backgrounds, Background, 0);
|
g_tooltip.bg = &g_array_index(backgrounds, Background, 0);
|
||||||
tooltip_init_fonts();
|
tooltip_init_fonts();
|
||||||
|
|
||||||
XSetWindowAttributes attr;
|
XSetWindowAttributes attr;
|
||||||
attr.override_redirect = True;
|
attr.override_redirect = True;
|
||||||
attr.event_mask = StructureNotifyMask;
|
attr.event_mask = StructureNotifyMask;
|
||||||
attr.colormap = server.colormap;
|
attr.colormap = server.colormap;
|
||||||
attr.background_pixel = 0;
|
attr.background_pixel = 0;
|
||||||
attr.border_pixel = 0;
|
attr.border_pixel = 0;
|
||||||
unsigned long mask = CWEventMask | CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect;
|
unsigned long mask = CWEventMask | CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect;
|
||||||
if (g_tooltip.window)
|
if (g_tooltip.window)
|
||||||
XDestroyWindow(server.display, g_tooltip.window);
|
XDestroyWindow(server.display, g_tooltip.window);
|
||||||
g_tooltip.window = XCreateWindow(server.display,
|
g_tooltip.window = XCreateWindow(server.display,
|
||||||
server.root_win,
|
server.root_win,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
100,
|
100,
|
||||||
20,
|
20,
|
||||||
0,
|
0,
|
||||||
server.depth,
|
server.depth,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
server.visual,
|
server.visual,
|
||||||
mask,
|
mask,
|
||||||
&attr);
|
&attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_init_fonts()
|
void tooltip_init_fonts()
|
||||||
{
|
{
|
||||||
if (!g_tooltip.font_desc)
|
if (!g_tooltip.font_desc)
|
||||||
g_tooltip.font_desc = pango_font_description_from_string(get_default_font());
|
g_tooltip.font_desc = pango_font_description_from_string(get_default_font());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_default_font_changed()
|
void tooltip_default_font_changed()
|
||||||
{
|
{
|
||||||
if (g_tooltip.has_font)
|
if (g_tooltip.has_font)
|
||||||
return;
|
return;
|
||||||
if (!g_tooltip.has_font) {
|
if (!g_tooltip.has_font) {
|
||||||
pango_font_description_free(g_tooltip.font_desc);
|
pango_font_description_free(g_tooltip.font_desc);
|
||||||
g_tooltip.font_desc = NULL;
|
g_tooltip.font_desc = NULL;
|
||||||
}
|
}
|
||||||
tooltip_init_fonts();
|
tooltip_init_fonts();
|
||||||
tooltip_update();
|
tooltip_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_trigger_show(Area *area, Panel *p, XEvent *e)
|
void tooltip_trigger_show(Area *area, Panel *p, XEvent *e)
|
||||||
{
|
{
|
||||||
// Position the tooltip in the center of the area
|
// Position the tooltip in the center of the area
|
||||||
x = area->posx + MIN(area->width / 3, 22) + e->xmotion.x_root - e->xmotion.x;
|
x = area->posx + MIN(area->width / 3, 22) + e->xmotion.x_root - e->xmotion.x;
|
||||||
y = area->posy + area->height / 2 + e->xmotion.y_root - e->xmotion.y;
|
y = area->posy + area->height / 2 + e->xmotion.y_root - e->xmotion.y;
|
||||||
just_shown = TRUE;
|
just_shown = TRUE;
|
||||||
g_tooltip.panel = p;
|
g_tooltip.panel = p;
|
||||||
if (g_tooltip.mapped && g_tooltip.area != area) {
|
if (g_tooltip.mapped && g_tooltip.area != area) {
|
||||||
tooltip_copy_text(area);
|
tooltip_copy_text(area);
|
||||||
tooltip_update();
|
tooltip_update();
|
||||||
stop_tooltip_timeout();
|
stop_tooltip_timeout();
|
||||||
} else if (!g_tooltip.mapped) {
|
} else if (!g_tooltip.mapped) {
|
||||||
start_show_timeout();
|
start_show_timeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_show(void *arg)
|
void tooltip_show(void *arg)
|
||||||
{
|
{
|
||||||
int mx, my;
|
int mx, my;
|
||||||
Window w;
|
Window w;
|
||||||
XTranslateCoordinates(server.display, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
|
XTranslateCoordinates(server.display, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
|
||||||
Area *area = find_area_under_mouse(g_tooltip.panel, mx, my);
|
Area *area = find_area_under_mouse(g_tooltip.panel, mx, my);
|
||||||
if (!g_tooltip.mapped && area->_get_tooltip_text) {
|
if (!g_tooltip.mapped && area->_get_tooltip_text) {
|
||||||
tooltip_copy_text(area);
|
tooltip_copy_text(area);
|
||||||
g_tooltip.mapped = True;
|
g_tooltip.mapped = True;
|
||||||
XMapWindow(server.display, g_tooltip.window);
|
XMapWindow(server.display, g_tooltip.window);
|
||||||
tooltip_update();
|
tooltip_update();
|
||||||
XFlush(server.display);
|
XFlush(server.display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_update_geometry()
|
void tooltip_update_geometry()
|
||||||
{
|
{
|
||||||
Panel *panel = g_tooltip.panel;
|
Panel *panel = g_tooltip.panel;
|
||||||
int screen_width = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width;
|
int screen_width = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width;
|
||||||
|
|
||||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
|
cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
|
||||||
cairo_t *c = cairo_create(cs);
|
cairo_t *c = cairo_create(cs);
|
||||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||||
|
|
||||||
pango_layout_set_font_description(layout, g_tooltip.font_desc);
|
pango_layout_set_font_description(layout, g_tooltip.font_desc);
|
||||||
PangoRectangle r1, r2;
|
PangoRectangle r1, r2;
|
||||||
pango_layout_set_text(layout, "1234567890", -1);
|
pango_layout_set_text(layout, "1234567890", -1);
|
||||||
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
||||||
int max_width = MIN(r2.width * 7, screen_width * 2 / 3);
|
int max_width = MIN(r2.width * 7, screen_width * 2 / 3);
|
||||||
pango_layout_set_width(layout, max_width * PANGO_SCALE);
|
pango_layout_set_width(layout, max_width * PANGO_SCALE);
|
||||||
|
|
||||||
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
|
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
|
||||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
|
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
|
||||||
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
||||||
width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx + r2.width;
|
width = left_right_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingx + r2.width;
|
||||||
height = top_bottom_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingy + r2.height;
|
height = top_bottom_bg_border_width(g_tooltip.bg) + 2 * g_tooltip.paddingy + r2.height;
|
||||||
|
|
||||||
if (panel_horizontal && panel_position & BOTTOM)
|
if (panel_horizontal && panel_position & BOTTOM)
|
||||||
y = panel->posy - height;
|
y = panel->posy - height;
|
||||||
else if (panel_horizontal && panel_position & TOP)
|
else if (panel_horizontal && panel_position & TOP)
|
||||||
y = panel->posy + panel->area.height;
|
y = panel->posy + panel->area.height;
|
||||||
else if (panel_position & LEFT)
|
else if (panel_position & LEFT)
|
||||||
x = panel->posx + panel->area.width;
|
x = panel->posx + panel->area.width;
|
||||||
else
|
else
|
||||||
x = panel->posx - width;
|
x = panel->posx - width;
|
||||||
|
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
cairo_destroy(c);
|
cairo_destroy(c);
|
||||||
cairo_surface_destroy(cs);
|
cairo_surface_destroy(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_adjust_geometry()
|
void tooltip_adjust_geometry()
|
||||||
{
|
{
|
||||||
// adjust coordinates and size to not go offscreen
|
// adjust coordinates and size to not go offscreen
|
||||||
// it seems quite impossible that the height needs to be adjusted, but we do it anyway.
|
// it seems quite impossible that the height needs to be adjusted, but we do it anyway.
|
||||||
|
|
||||||
Panel *panel = g_tooltip.panel;
|
Panel *panel = g_tooltip.panel;
|
||||||
int screen_width = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width;
|
int screen_width = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width;
|
||||||
int screen_height = server.monitors[panel->monitor].y + server.monitors[panel->monitor].height;
|
int screen_height = server.monitors[panel->monitor].y + server.monitors[panel->monitor].height;
|
||||||
if (x + width <= screen_width && y + height <= screen_height && x >= server.monitors[panel->monitor].x &&
|
if (x + width <= screen_width && y + height <= screen_height && x >= server.monitors[panel->monitor].x &&
|
||||||
y >= server.monitors[panel->monitor].y)
|
y >= server.monitors[panel->monitor].y)
|
||||||
return; // no adjustment needed
|
return; // no adjustment needed
|
||||||
|
|
||||||
int min_x, min_y, max_width, max_height;
|
int min_x, min_y, max_width, max_height;
|
||||||
if (panel_horizontal) {
|
if (panel_horizontal) {
|
||||||
min_x = 0;
|
min_x = 0;
|
||||||
max_width = server.monitors[panel->monitor].width;
|
max_width = server.monitors[panel->monitor].width;
|
||||||
max_height = server.monitors[panel->monitor].height - panel->area.height;
|
max_height = server.monitors[panel->monitor].height - panel->area.height;
|
||||||
if (panel_position & BOTTOM)
|
if (panel_position & BOTTOM)
|
||||||
min_y = 0;
|
min_y = 0;
|
||||||
else
|
else
|
||||||
min_y = panel->area.height;
|
min_y = panel->area.height;
|
||||||
} else {
|
} else {
|
||||||
max_width = server.monitors[panel->monitor].width - panel->area.width;
|
max_width = server.monitors[panel->monitor].width - panel->area.width;
|
||||||
min_y = 0;
|
min_y = 0;
|
||||||
max_height = server.monitors[panel->monitor].height;
|
max_height = server.monitors[panel->monitor].height;
|
||||||
if (panel_position & LEFT)
|
if (panel_position & LEFT)
|
||||||
min_x = panel->area.width;
|
min_x = panel->area.width;
|
||||||
else
|
else
|
||||||
min_x = 0;
|
min_x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x + width > server.monitors[panel->monitor].x + server.monitors[panel->monitor].width)
|
if (x + width > server.monitors[panel->monitor].x + server.monitors[panel->monitor].width)
|
||||||
x = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width - width;
|
x = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width - width;
|
||||||
if (y + height > server.monitors[panel->monitor].y + server.monitors[panel->monitor].height)
|
if (y + height > server.monitors[panel->monitor].y + server.monitors[panel->monitor].height)
|
||||||
y = server.monitors[panel->monitor].y + server.monitors[panel->monitor].height - height;
|
y = server.monitors[panel->monitor].y + server.monitors[panel->monitor].height - height;
|
||||||
|
|
||||||
if (x < min_x)
|
if (x < min_x)
|
||||||
x = min_x;
|
x = min_x;
|
||||||
if (width > max_width)
|
if (width > max_width)
|
||||||
width = max_width;
|
width = max_width;
|
||||||
if (y < min_y)
|
if (y < min_y)
|
||||||
y = min_y;
|
y = min_y;
|
||||||
if (height > max_height)
|
if (height > max_height)
|
||||||
height = max_height;
|
height = max_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_update()
|
void tooltip_update()
|
||||||
{
|
{
|
||||||
if (!g_tooltip.tooltip_text) {
|
if (!g_tooltip.tooltip_text) {
|
||||||
tooltip_hide(0);
|
tooltip_hide(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tooltip_update_geometry();
|
tooltip_update_geometry();
|
||||||
if (just_shown) {
|
if (just_shown) {
|
||||||
if (!panel_horizontal)
|
if (!panel_horizontal)
|
||||||
y -= height / 2; // center vertically
|
y -= height / 2; // center vertically
|
||||||
just_shown = FALSE;
|
just_shown = FALSE;
|
||||||
}
|
}
|
||||||
tooltip_adjust_geometry();
|
tooltip_adjust_geometry();
|
||||||
XMoveResizeWindow(server.display, g_tooltip.window, x, y, width, height);
|
XMoveResizeWindow(server.display, g_tooltip.window, x, y, width, height);
|
||||||
|
|
||||||
// Stuff for drawing the tooltip
|
// Stuff for drawing the tooltip
|
||||||
cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
|
cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
|
||||||
cairo_t *c = cairo_create(cs);
|
cairo_t *c = cairo_create(cs);
|
||||||
Color bc = g_tooltip.bg->fill_color;
|
Color bc = g_tooltip.bg->fill_color;
|
||||||
Border b = g_tooltip.bg->border;
|
Border b = g_tooltip.bg->border;
|
||||||
if (server.real_transparency) {
|
if (server.real_transparency) {
|
||||||
clear_pixmap(g_tooltip.window, 0, 0, width, height);
|
clear_pixmap(g_tooltip.window, 0, 0, width, height);
|
||||||
draw_rect(c, b.width, b.width, width - 2 * b.width, height - 2 * b.width, b.radius - b.width / 1.571);
|
draw_rect(c, b.width, b.width, width - 2 * b.width, height - 2 * b.width, b.radius - b.width / 1.571);
|
||||||
cairo_set_source_rgba(c, bc.rgb[0], bc.rgb[1], bc.rgb[2], bc.alpha);
|
cairo_set_source_rgba(c, bc.rgb[0], bc.rgb[1], bc.rgb[2], bc.alpha);
|
||||||
} else {
|
} else {
|
||||||
cairo_rectangle(c, 0., 0, width, height);
|
cairo_rectangle(c, 0., 0, width, height);
|
||||||
cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
|
cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
|
||||||
}
|
}
|
||||||
cairo_fill(c);
|
cairo_fill(c);
|
||||||
cairo_set_line_width(c, b.width);
|
cairo_set_line_width(c, b.width);
|
||||||
if (server.real_transparency)
|
if (server.real_transparency)
|
||||||
draw_rect(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width, b.radius);
|
draw_rect(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width, b.radius);
|
||||||
else
|
else
|
||||||
cairo_rectangle(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width);
|
cairo_rectangle(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width);
|
||||||
cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha);
|
cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha);
|
||||||
cairo_stroke(c);
|
cairo_stroke(c);
|
||||||
|
|
||||||
Color fc = g_tooltip.font_color;
|
Color fc = g_tooltip.font_color;
|
||||||
cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
|
cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
|
||||||
PangoLayout *layout = pango_cairo_create_layout(c);
|
PangoLayout *layout = pango_cairo_create_layout(c);
|
||||||
pango_layout_set_font_description(layout, g_tooltip.font_desc);
|
pango_layout_set_font_description(layout, g_tooltip.font_desc);
|
||||||
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
|
pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
|
||||||
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
|
pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
|
||||||
PangoRectangle r1, r2;
|
PangoRectangle r1, r2;
|
||||||
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
pango_layout_get_pixel_extents(layout, &r1, &r2);
|
||||||
pango_layout_set_width(layout, width * PANGO_SCALE);
|
pango_layout_set_width(layout, width * PANGO_SCALE);
|
||||||
pango_layout_set_height(layout, height * PANGO_SCALE);
|
pango_layout_set_height(layout, height * PANGO_SCALE);
|
||||||
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
|
||||||
// I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and
|
// I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and
|
||||||
// vert.)
|
// vert.)
|
||||||
cairo_move_to(c,
|
cairo_move_to(c,
|
||||||
-r1.x / 2 + left_bg_border_width(g_tooltip.bg) + g_tooltip.paddingx,
|
-r1.x / 2 + left_bg_border_width(g_tooltip.bg) + g_tooltip.paddingx,
|
||||||
-r1.y / 2 + 1 + top_bg_border_width(g_tooltip.bg) + g_tooltip.paddingy);
|
-r1.y / 2 + 1 + top_bg_border_width(g_tooltip.bg) + g_tooltip.paddingy);
|
||||||
pango_cairo_show_layout(c, layout);
|
pango_cairo_show_layout(c, layout);
|
||||||
|
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
cairo_destroy(c);
|
cairo_destroy(c);
|
||||||
cairo_surface_destroy(cs);
|
cairo_surface_destroy(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_trigger_hide()
|
void tooltip_trigger_hide()
|
||||||
{
|
{
|
||||||
if (g_tooltip.mapped) {
|
if (g_tooltip.mapped) {
|
||||||
tooltip_copy_text(0);
|
tooltip_copy_text(0);
|
||||||
start_hide_timeout();
|
start_hide_timeout();
|
||||||
} else {
|
} else {
|
||||||
// tooltip not visible yet, but maybe a timeout is still pending
|
// tooltip not visible yet, but maybe a timeout is still pending
|
||||||
stop_tooltip_timeout();
|
stop_tooltip_timeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_hide(void *arg)
|
void tooltip_hide(void *arg)
|
||||||
{
|
{
|
||||||
if (g_tooltip.mapped) {
|
if (g_tooltip.mapped) {
|
||||||
g_tooltip.mapped = False;
|
g_tooltip.mapped = False;
|
||||||
XUnmapWindow(server.display, g_tooltip.window);
|
XUnmapWindow(server.display, g_tooltip.window);
|
||||||
XFlush(server.display);
|
XFlush(server.display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_show_timeout()
|
void start_show_timeout()
|
||||||
{
|
{
|
||||||
change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_hide_timeout()
|
void start_hide_timeout()
|
||||||
{
|
{
|
||||||
change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_tooltip_timeout()
|
void stop_tooltip_timeout()
|
||||||
{
|
{
|
||||||
stop_timeout(g_tooltip.timeout);
|
stop_timeout(g_tooltip.timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tooltip_copy_text(Area *area)
|
void tooltip_copy_text(Area *area)
|
||||||
{
|
{
|
||||||
free(g_tooltip.tooltip_text);
|
free(g_tooltip.tooltip_text);
|
||||||
if (area && area->_get_tooltip_text)
|
if (area && area->_get_tooltip_text)
|
||||||
g_tooltip.tooltip_text = area->_get_tooltip_text(area);
|
g_tooltip.tooltip_text = area->_get_tooltip_text(area);
|
||||||
else
|
else
|
||||||
g_tooltip.tooltip_text = NULL;
|
g_tooltip.tooltip_text = NULL;
|
||||||
g_tooltip.area = area;
|
g_tooltip.area = area;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,20 +23,20 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Area *area; // never ever use the area attribut if you are not 100% sure that this area was not freed
|
Area *area; // never ever use the area attribut if you are not 100% sure that this area was not freed
|
||||||
char *tooltip_text;
|
char *tooltip_text;
|
||||||
Panel *panel;
|
Panel *panel;
|
||||||
Window window;
|
Window window;
|
||||||
int show_timeout_msec;
|
int show_timeout_msec;
|
||||||
int hide_timeout_msec;
|
int hide_timeout_msec;
|
||||||
Bool mapped;
|
Bool mapped;
|
||||||
int paddingx;
|
int paddingx;
|
||||||
int paddingy;
|
int paddingy;
|
||||||
gboolean has_font;
|
gboolean has_font;
|
||||||
PangoFontDescription *font_desc;
|
PangoFontDescription *font_desc;
|
||||||
Color font_color;
|
Color font_color;
|
||||||
Background *bg;
|
Background *bg;
|
||||||
timeout *timeout;
|
timeout *timeout;
|
||||||
} Tooltip;
|
} Tooltip;
|
||||||
|
|
||||||
extern Tooltip g_tooltip;
|
extern Tooltip g_tooltip;
|
||||||
|
|||||||
1636
src/util/area.c
1636
src/util/area.c
File diff suppressed because it is too large
Load Diff
178
src/util/area.h
178
src/util/area.h
@@ -121,125 +121,125 @@
|
|||||||
// The Area's _get_tooltip_text member must point to this function.
|
// The Area's _get_tooltip_text member must point to this function.
|
||||||
|
|
||||||
typedef enum BorderMask {
|
typedef enum BorderMask {
|
||||||
BORDER_TOP = 1 << 0,
|
BORDER_TOP = 1 << 0,
|
||||||
BORDER_BOTTOM = 1 << 1,
|
BORDER_BOTTOM = 1 << 1,
|
||||||
BORDER_LEFT = 1 << 2,
|
BORDER_LEFT = 1 << 2,
|
||||||
BORDER_RIGHT = 1 << 3
|
BORDER_RIGHT = 1 << 3
|
||||||
} BorderMask;
|
} BorderMask;
|
||||||
|
|
||||||
#define BORDER_ALL (BORDER_TOP | BORDER_BOTTOM | BORDER_LEFT | BORDER_RIGHT)
|
#define BORDER_ALL (BORDER_TOP | BORDER_BOTTOM | BORDER_LEFT | BORDER_RIGHT)
|
||||||
|
|
||||||
typedef struct Border {
|
typedef struct Border {
|
||||||
// It's essential that the first member is color
|
// It's essential that the first member is color
|
||||||
Color color;
|
Color color;
|
||||||
// Width in pixels
|
// Width in pixels
|
||||||
int width;
|
int width;
|
||||||
// Corner radius
|
// Corner radius
|
||||||
int radius;
|
int radius;
|
||||||
// Mask: bitwise OR of BorderMask
|
// Mask: bitwise OR of BorderMask
|
||||||
int mask;
|
int mask;
|
||||||
} Border;
|
} Border;
|
||||||
|
|
||||||
typedef enum MouseState { MOUSE_NORMAL = 0, MOUSE_OVER = 1, MOUSE_DOWN = 2, MOUSE_STATE_COUNT } MouseState;
|
typedef enum MouseState { MOUSE_NORMAL = 0, MOUSE_OVER = 1, MOUSE_DOWN = 2, MOUSE_STATE_COUNT } MouseState;
|
||||||
|
|
||||||
typedef struct Background {
|
typedef struct Background {
|
||||||
// Normal state
|
// Normal state
|
||||||
Color fill_color;
|
Color fill_color;
|
||||||
Border border;
|
Border border;
|
||||||
// On mouse hover
|
// On mouse hover
|
||||||
Color fill_color_hover;
|
Color fill_color_hover;
|
||||||
Color border_color_hover;
|
Color border_color_hover;
|
||||||
// On mouse press
|
// On mouse press
|
||||||
Color fill_color_pressed;
|
Color fill_color_pressed;
|
||||||
Color border_color_pressed;
|
Color border_color_pressed;
|
||||||
// Pointer to a GradientClass or NULL, no ownership
|
// Pointer to a GradientClass or NULL, no ownership
|
||||||
GradientClass *gradients[MOUSE_STATE_COUNT];
|
GradientClass *gradients[MOUSE_STATE_COUNT];
|
||||||
} Background;
|
} Background;
|
||||||
|
|
||||||
typedef enum Layout {
|
typedef enum Layout {
|
||||||
LAYOUT_DYNAMIC,
|
LAYOUT_DYNAMIC,
|
||||||
LAYOUT_FIXED,
|
LAYOUT_FIXED,
|
||||||
} Layout;
|
} Layout;
|
||||||
|
|
||||||
typedef enum Alignment {
|
typedef enum Alignment {
|
||||||
ALIGN_LEFT = 0,
|
ALIGN_LEFT = 0,
|
||||||
ALIGN_CENTER = 1,
|
ALIGN_CENTER = 1,
|
||||||
ALIGN_RIGHT = 2,
|
ALIGN_RIGHT = 2,
|
||||||
} Alignment;
|
} Alignment;
|
||||||
|
|
||||||
struct Panel;
|
struct Panel;
|
||||||
|
|
||||||
typedef struct Area {
|
typedef struct Area {
|
||||||
// Position relative to the panel window
|
// Position relative to the panel window
|
||||||
int posx, posy;
|
int posx, posy;
|
||||||
// Size, including borders
|
// Size, including borders
|
||||||
int width, height;
|
int width, height;
|
||||||
int old_width, old_height;
|
int old_width, old_height;
|
||||||
Background *bg;
|
Background *bg;
|
||||||
// Each element is a GradientInstance attached to this Area (list can be empty)
|
// Each element is a GradientInstance attached to this Area (list can be empty)
|
||||||
GList *gradient_instances_by_state[MOUSE_STATE_COUNT];
|
GList *gradient_instances_by_state[MOUSE_STATE_COUNT];
|
||||||
// Each element is a GradientInstance that depends on this Area's geometry (position or size)
|
// Each element is a GradientInstance that depends on this Area's geometry (position or size)
|
||||||
GList *dependent_gradients;
|
GList *dependent_gradients;
|
||||||
// List of children, each one a pointer to Area
|
// List of children, each one a pointer to Area
|
||||||
GList *children;
|
GList *children;
|
||||||
// Pointer to the parent Area or NULL
|
// Pointer to the parent Area or NULL
|
||||||
void *parent;
|
void *parent;
|
||||||
// Pointer to the Panel that contains this Area
|
// Pointer to the Panel that contains this Area
|
||||||
void *panel;
|
void *panel;
|
||||||
Layout size_mode;
|
Layout size_mode;
|
||||||
Alignment alignment;
|
Alignment alignment;
|
||||||
gboolean has_mouse_over_effect;
|
gboolean has_mouse_over_effect;
|
||||||
gboolean has_mouse_press_effect;
|
gboolean has_mouse_press_effect;
|
||||||
// TODO padding/spacing is a clusterfuck
|
// TODO padding/spacing is a clusterfuck
|
||||||
// paddingxlr = padding
|
// paddingxlr = padding
|
||||||
// paddingy = vertical padding, sometimes
|
// paddingy = vertical padding, sometimes
|
||||||
// paddingx = spacing
|
// paddingx = spacing
|
||||||
int paddingxlr, paddingx, paddingy;
|
int paddingxlr, paddingx, paddingy;
|
||||||
MouseState mouse_state;
|
MouseState mouse_state;
|
||||||
// Set to non-zero if the Area is visible. An object may exist but stay hidden.
|
// Set to non-zero if the Area is visible. An object may exist but stay hidden.
|
||||||
gboolean on_screen;
|
gboolean on_screen;
|
||||||
// Set to non-zero if the size of the Area has to be recalculated.
|
// Set to non-zero if the size of the Area has to be recalculated.
|
||||||
gboolean resize_needed;
|
gboolean resize_needed;
|
||||||
// Set to non-zero if the Area has to be redrawn.
|
// Set to non-zero if the Area has to be redrawn.
|
||||||
// Do not set this directly; use schedule_redraw() instead.
|
// Do not set this directly; use schedule_redraw() instead.
|
||||||
gboolean _redraw_needed;
|
gboolean _redraw_needed;
|
||||||
// Set to non-zero if the position/size has changed, thus _on_change_layout needs to be called
|
// Set to non-zero if the position/size has changed, thus _on_change_layout needs to be called
|
||||||
gboolean _changed;
|
gboolean _changed;
|
||||||
// This is the pixmap on which the Area is rendered. Render to it directly if needed.
|
// This is the pixmap on which the Area is rendered. Render to it directly if needed.
|
||||||
Pixmap pix;
|
Pixmap pix;
|
||||||
Pixmap pix_by_state[MOUSE_STATE_COUNT];
|
Pixmap pix_by_state[MOUSE_STATE_COUNT];
|
||||||
char name[32];
|
char name[32];
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
|
|
||||||
// Called on draw before any drawing takes place, obj = pointer to the Area
|
// Called on draw before any drawing takes place, obj = pointer to the Area
|
||||||
void (*_clear)(void *obj);
|
void (*_clear)(void *obj);
|
||||||
|
|
||||||
// Called on draw, obj = pointer to the Area
|
// Called on draw, obj = pointer to the Area
|
||||||
void (*_draw_foreground)(void *obj, cairo_t *c);
|
void (*_draw_foreground)(void *obj, cairo_t *c);
|
||||||
|
|
||||||
// Called on resize, obj = pointer to the Area
|
// Called on resize, obj = pointer to the Area
|
||||||
// Returns 1 if the new size is different than the previous size.
|
// Returns 1 if the new size is different than the previous size.
|
||||||
gboolean (*_resize)(void *obj);
|
gboolean (*_resize)(void *obj);
|
||||||
|
|
||||||
// Called before resize, obj = pointer to the Area
|
// Called before resize, obj = pointer to the Area
|
||||||
// Returns the desired size of the Area
|
// Returns the desired size of the Area
|
||||||
int (*_compute_desired_size)(void *obj);
|
int (*_compute_desired_size)(void *obj);
|
||||||
|
|
||||||
// Implemented only to override the default layout algorithm for this widget.
|
// Implemented only to override the default layout algorithm for this widget.
|
||||||
// For example, if this widget is a cell in a table, its position and size should be computed here.
|
// For example, if this widget is a cell in a table, its position and size should be computed here.
|
||||||
void (*_on_change_layout)(void *obj);
|
void (*_on_change_layout)(void *obj);
|
||||||
|
|
||||||
// Returns a copy of the tooltip to be displayed for this widget.
|
// Returns a copy of the tooltip to be displayed for this widget.
|
||||||
// The caller takes ownership of the pointer.
|
// The caller takes ownership of the pointer.
|
||||||
char *(*_get_tooltip_text)(void *obj);
|
char *(*_get_tooltip_text)(void *obj);
|
||||||
|
|
||||||
// Returns true if the Area handles a mouse event at the given x, y coordinates relative to the window.
|
// Returns true if the Area handles a mouse event at the given x, y coordinates relative to the window.
|
||||||
// Leave this to NULL to use a default implementation.
|
// Leave this to NULL to use a default implementation.
|
||||||
gboolean (*_is_under_mouse)(void *obj, int x, int y);
|
gboolean (*_is_under_mouse)(void *obj, int x, int y);
|
||||||
|
|
||||||
// Prints the geometry of the object on stderr, with left indentation of indent spaces.
|
// Prints the geometry of the object on stderr, with left indentation of indent spaces.
|
||||||
void (*_dump_geometry)(void *obj, int indent);
|
void (*_dump_geometry)(void *obj, int indent);
|
||||||
} Area;
|
} Area;
|
||||||
|
|
||||||
// Initializes the Background member to default values.
|
// Initializes the Background member to default values.
|
||||||
|
|||||||
168
src/util/cache.c
168
src/util/cache.c
@@ -32,129 +32,129 @@
|
|||||||
|
|
||||||
void init_cache(Cache *cache)
|
void init_cache(Cache *cache)
|
||||||
{
|
{
|
||||||
if (cache->_table)
|
if (cache->_table)
|
||||||
free_cache(cache);
|
free_cache(cache);
|
||||||
cache->_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
cache->_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
cache->dirty = FALSE;
|
cache->dirty = FALSE;
|
||||||
cache->loaded = FALSE;
|
cache->loaded = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_cache(Cache *cache)
|
void free_cache(Cache *cache)
|
||||||
{
|
{
|
||||||
if (cache->_table)
|
if (cache->_table)
|
||||||
g_hash_table_destroy(cache->_table);
|
g_hash_table_destroy(cache->_table);
|
||||||
cache->_table = NULL;
|
cache->_table = NULL;
|
||||||
cache->dirty = FALSE;
|
cache->dirty = FALSE;
|
||||||
cache->loaded = FALSE;
|
cache->loaded = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_cache(Cache *cache, const gchar *cache_path)
|
void load_cache(Cache *cache, const gchar *cache_path)
|
||||||
{
|
{
|
||||||
init_cache(cache);
|
init_cache(cache);
|
||||||
|
|
||||||
cache->loaded = TRUE;
|
cache->loaded = TRUE;
|
||||||
|
|
||||||
int fd = open(cache_path, O_RDONLY);
|
int fd = open(cache_path, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return;
|
return;
|
||||||
flock(fd, LOCK_SH);
|
flock(fd, LOCK_SH);
|
||||||
|
|
||||||
FILE *f = fopen(cache_path, "rt");
|
FILE *f = fopen(cache_path, "rt");
|
||||||
if (!f)
|
if (!f)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t line_size;
|
size_t line_size;
|
||||||
|
|
||||||
while (getline(&line, &line_size, f) >= 0) {
|
while (getline(&line, &line_size, f) >= 0) {
|
||||||
char *key, *value;
|
char *key, *value;
|
||||||
|
|
||||||
size_t line_len = strlen(line);
|
size_t line_len = strlen(line);
|
||||||
gboolean has_newline = FALSE;
|
gboolean has_newline = FALSE;
|
||||||
if (line_len >= 1) {
|
if (line_len >= 1) {
|
||||||
if (line[line_len - 1] == '\n') {
|
if (line[line_len - 1] == '\n') {
|
||||||
line[line_len - 1] = '\0';
|
line[line_len - 1] = '\0';
|
||||||
line_len--;
|
line_len--;
|
||||||
has_newline = TRUE;
|
has_newline = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!has_newline)
|
if (!has_newline)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (line_len == 0)
|
if (line_len == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (parse_line(line, &key, &value)) {
|
if (parse_line(line, &key, &value)) {
|
||||||
g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value));
|
g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value));
|
||||||
free(key);
|
free(key);
|
||||||
free(value);
|
free(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
flock(fd, LOCK_UN);
|
flock(fd, LOCK_UN);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_cache_line(gpointer key, gpointer value, gpointer user_data)
|
void write_cache_line(gpointer key, gpointer value, gpointer user_data)
|
||||||
{
|
{
|
||||||
gchar *k = key;
|
gchar *k = key;
|
||||||
gchar *v = value;
|
gchar *v = value;
|
||||||
FILE *f = user_data;
|
FILE *f = user_data;
|
||||||
|
|
||||||
fprintf(f, "%s=%s\n", k, v);
|
fprintf(f, "%s=%s\n", k, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_cache(Cache *cache, const gchar *cache_path)
|
void save_cache(Cache *cache, const gchar *cache_path)
|
||||||
{
|
{
|
||||||
int fd = open(cache_path, O_RDONLY | O_CREAT, 0600);
|
int fd = open(cache_path, O_RDONLY | O_CREAT, 0600);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
gchar *dir_path = g_path_get_dirname(cache_path);
|
gchar *dir_path = g_path_get_dirname(cache_path);
|
||||||
g_mkdir_with_parents(dir_path, 0700);
|
g_mkdir_with_parents(dir_path, 0700);
|
||||||
g_free(dir_path);
|
g_free(dir_path);
|
||||||
fd = open(cache_path, O_RDONLY | O_CREAT, 0600);
|
fd = open(cache_path, O_RDONLY | O_CREAT, 0600);
|
||||||
}
|
}
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
fprintf(stderr, RED "Could not save icon theme cache!" RESET "\n");
|
fprintf(stderr, RED "Could not save icon theme cache!" RESET "\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flock(fd, LOCK_EX);
|
flock(fd, LOCK_EX);
|
||||||
|
|
||||||
FILE *f = fopen(cache_path, "w");
|
FILE *f = fopen(cache_path, "w");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
fprintf(stderr, RED "Could not save icon theme cache!" RESET "\n");
|
fprintf(stderr, RED "Could not save icon theme cache!" RESET "\n");
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
g_hash_table_foreach(cache->_table, write_cache_line, f);
|
g_hash_table_foreach(cache->_table, write_cache_line, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
cache->dirty = FALSE;
|
cache->dirty = FALSE;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
flock(fd, LOCK_UN);
|
flock(fd, LOCK_UN);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *get_from_cache(Cache *cache, const gchar *key)
|
const gchar *get_from_cache(Cache *cache, const gchar *key)
|
||||||
{
|
{
|
||||||
if (!cache->_table)
|
if (!cache->_table)
|
||||||
return NULL;
|
return NULL;
|
||||||
return g_hash_table_lookup(cache->_table, key);
|
return g_hash_table_lookup(cache->_table, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_to_cache(Cache *cache, const gchar *key, const gchar *value)
|
void add_to_cache(Cache *cache, const gchar *key, const gchar *value)
|
||||||
{
|
{
|
||||||
if (!cache->_table)
|
if (!cache->_table)
|
||||||
init_cache(cache);
|
init_cache(cache);
|
||||||
|
|
||||||
if (!key || !value)
|
if (!key || !value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gchar *old_value = g_hash_table_lookup(cache->_table, key);
|
gchar *old_value = g_hash_table_lookup(cache->_table, key);
|
||||||
if (old_value && g_str_equal(old_value, value))
|
if (old_value && g_str_equal(old_value, value))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value));
|
g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value));
|
||||||
cache->dirty = TRUE;
|
cache->dirty = TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
// A cache with string keys and values, backed by a file.
|
// A cache with string keys and values, backed by a file.
|
||||||
// The strings must not be NULL and are stripped of any whitespace at start and end.
|
// The strings must not be NULL and are stripped of any whitespace at start and end.
|
||||||
typedef struct Cache {
|
typedef struct Cache {
|
||||||
gboolean dirty;
|
gboolean dirty;
|
||||||
gboolean loaded;
|
gboolean loaded;
|
||||||
GHashTable *_table;
|
GHashTable *_table;
|
||||||
} Cache;
|
} Cache;
|
||||||
|
|
||||||
// Initializes the cache. You can also call load_cache directly if you set the memory contents to zero first.
|
// Initializes the cache. You can also call load_cache directly if you set the memory contents to zero first.
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
#include "color.h"
|
#include "color.h"
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
#define COLOR_H
|
#define COLOR_H
|
||||||
|
|
||||||
typedef struct Color {
|
typedef struct Color {
|
||||||
// Values are in [0, 1], with 0 meaning no intensity.
|
// Values are in [0, 1], with 0 meaning no intensity.
|
||||||
double rgb[3];
|
double rgb[3];
|
||||||
// Values are in [0, 1], with 0 meaning fully transparent, 1 meaning fully opaque.
|
// Values are in [0, 1], with 0 meaning fully transparent, 1 meaning fully opaque.
|
||||||
double alpha;
|
double alpha;
|
||||||
} Color;
|
} Color;
|
||||||
|
|
||||||
#endif // COLOR_H
|
#endif // COLOR_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -24,19 +24,19 @@
|
|||||||
|
|
||||||
// mouse actions
|
// mouse actions
|
||||||
typedef enum MouseAction {
|
typedef enum MouseAction {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
CLOSE,
|
CLOSE,
|
||||||
TOGGLE,
|
TOGGLE,
|
||||||
ICONIFY,
|
ICONIFY,
|
||||||
SHADE,
|
SHADE,
|
||||||
TOGGLE_ICONIFY,
|
TOGGLE_ICONIFY,
|
||||||
MAXIMIZE_RESTORE,
|
MAXIMIZE_RESTORE,
|
||||||
MAXIMIZE,
|
MAXIMIZE,
|
||||||
RESTORE,
|
RESTORE,
|
||||||
DESKTOP_LEFT,
|
DESKTOP_LEFT,
|
||||||
DESKTOP_RIGHT,
|
DESKTOP_RIGHT,
|
||||||
NEXT_TASK,
|
NEXT_TASK,
|
||||||
PREV_TASK
|
PREV_TASK
|
||||||
} MouseAction;
|
} MouseAction;
|
||||||
|
|
||||||
#define ALL_DESKTOPS 0xFFFFFFFF
|
#define ALL_DESKTOPS 0xFFFFFFFF
|
||||||
@@ -94,16 +94,16 @@ void create_heuristic_mask(DATA32 *data, int w, int h);
|
|||||||
void render_image(Drawable d, int x, int y);
|
void render_image(Drawable d, int x, int y);
|
||||||
|
|
||||||
void get_text_size2(PangoFontDescription *font,
|
void get_text_size2(PangoFontDescription *font,
|
||||||
int *height_ink,
|
int *height_ink,
|
||||||
int *height,
|
int *height,
|
||||||
int *width,
|
int *width,
|
||||||
int panel_height,
|
int panel_height,
|
||||||
int panel_with,
|
int panel_with,
|
||||||
char *text,
|
char *text,
|
||||||
int len,
|
int len,
|
||||||
PangoWrapMode wrap,
|
PangoWrapMode wrap,
|
||||||
PangoEllipsizeMode ellipsis,
|
PangoEllipsizeMode ellipsis,
|
||||||
gboolean markup);
|
gboolean markup);
|
||||||
|
|
||||||
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
|
void draw_text(PangoLayout *layout, cairo_t *c, int posx, int posy, Color *color, int font_shadow);
|
||||||
|
|
||||||
@@ -125,10 +125,10 @@ GSList *slist_remove_duplicates(GSList *list, GCompareFunc eq, GDestroyNotify fr
|
|||||||
gint cmp_ptr(gconstpointer a, gconstpointer b);
|
gint cmp_ptr(gconstpointer a, gconstpointer b);
|
||||||
|
|
||||||
#define free_and_null(p) \
|
#define free_and_null(p) \
|
||||||
{ \
|
{ \
|
||||||
free(p); \
|
free(p); \
|
||||||
p = NULL; \
|
p = NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION(2, 33, 4)
|
#if !GLIB_CHECK_VERSION(2, 33, 4)
|
||||||
GList *g_list_copy_deep(GList *list, GCopyFunc func, gpointer user_data);
|
GList *g_list_copy_deep(GList *list, GCopyFunc func, gpointer user_data);
|
||||||
|
|||||||
@@ -8,116 +8,116 @@
|
|||||||
|
|
||||||
gboolean read_double(const char *str, double *value)
|
gboolean read_double(const char *str, double *value)
|
||||||
{
|
{
|
||||||
if (!str[0])
|
if (!str[0])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
char *end;
|
char *end;
|
||||||
*value = strtod(str, &end);
|
*value = strtod(str, &end);
|
||||||
if (end[0])
|
if (end[0])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean read_double_with_percent(const char *str, double *value)
|
gboolean read_double_with_percent(const char *str, double *value)
|
||||||
{
|
{
|
||||||
if (!str[0])
|
if (!str[0])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
char *end;
|
char *end;
|
||||||
*value = strtod(str, &end);
|
*value = strtod(str, &end);
|
||||||
if (end[0] == '%' && !end[1]) {
|
if (end[0] == '%' && !end[1]) {
|
||||||
*value *= 0.01;
|
*value *= 0.01;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (end[0])
|
if (end[0])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GradientType gradient_type_from_string(const char *str)
|
GradientType gradient_type_from_string(const char *str)
|
||||||
{
|
{
|
||||||
if (g_str_equal(str, "horizontal"))
|
if (g_str_equal(str, "horizontal"))
|
||||||
return GRADIENT_HORIZONTAL;
|
return GRADIENT_HORIZONTAL;
|
||||||
if (g_str_equal(str, "vertical"))
|
if (g_str_equal(str, "vertical"))
|
||||||
return GRADIENT_VERTICAL;
|
return GRADIENT_VERTICAL;
|
||||||
if (g_str_equal(str, "radial"))
|
if (g_str_equal(str, "radial"))
|
||||||
return GRADIENT_CENTERED;
|
return GRADIENT_CENTERED;
|
||||||
fprintf(stderr, RED "Invalid gradient type: %s" RESET "\n", str);
|
fprintf(stderr, RED "Invalid gradient type: %s" RESET "\n", str);
|
||||||
return GRADIENT_VERTICAL;
|
return GRADIENT_VERTICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_gradient(GradientClass *g, GradientType type)
|
void init_gradient(GradientClass *g, GradientType type)
|
||||||
{
|
{
|
||||||
memset(g, 0, sizeof(*g));
|
memset(g, 0, sizeof(*g));
|
||||||
g->type = type;
|
g->type = type;
|
||||||
if (g->type == GRADIENT_VERTICAL) {
|
if (g->type == GRADIENT_VERTICAL) {
|
||||||
Offset *offset_top = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_top = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_top->constant = TRUE;
|
offset_top->constant = TRUE;
|
||||||
offset_top->constant_value = 0;
|
offset_top->constant_value = 0;
|
||||||
g->from.offsets_y = g_list_append(g->from.offsets_y, offset_top);
|
g->from.offsets_y = g_list_append(g->from.offsets_y, offset_top);
|
||||||
Offset *offset_bottom = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_bottom = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_bottom->constant = FALSE;
|
offset_bottom->constant = FALSE;
|
||||||
offset_bottom->element = ELEMENT_SELF;
|
offset_bottom->element = ELEMENT_SELF;
|
||||||
offset_bottom->variable = SIZE_HEIGHT;
|
offset_bottom->variable = SIZE_HEIGHT;
|
||||||
offset_bottom->multiplier = 1.0;
|
offset_bottom->multiplier = 1.0;
|
||||||
g->to.offsets_y = g_list_append(g->to.offsets_y, offset_bottom);
|
g->to.offsets_y = g_list_append(g->to.offsets_y, offset_bottom);
|
||||||
} else if (g->type == GRADIENT_HORIZONTAL) {
|
} else if (g->type == GRADIENT_HORIZONTAL) {
|
||||||
Offset *offset_left = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_left = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_left->constant = TRUE;
|
offset_left->constant = TRUE;
|
||||||
offset_left->constant_value = 0;
|
offset_left->constant_value = 0;
|
||||||
g->from.offsets_x = g_list_append(g->from.offsets_x, offset_left);
|
g->from.offsets_x = g_list_append(g->from.offsets_x, offset_left);
|
||||||
Offset *offset_right = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_right = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_right->constant = FALSE;
|
offset_right->constant = FALSE;
|
||||||
offset_right->element = ELEMENT_SELF;
|
offset_right->element = ELEMENT_SELF;
|
||||||
offset_right->variable = SIZE_WIDTH;
|
offset_right->variable = SIZE_WIDTH;
|
||||||
offset_right->multiplier = 1.0;
|
offset_right->multiplier = 1.0;
|
||||||
g->to.offsets_x = g_list_append(g->to.offsets_x, offset_right);
|
g->to.offsets_x = g_list_append(g->to.offsets_x, offset_right);
|
||||||
} else if (g->type == GRADIENT_CENTERED) {
|
} else if (g->type == GRADIENT_CENTERED) {
|
||||||
// from
|
// from
|
||||||
Offset *offset_center_x = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_center_x = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_center_x->constant = FALSE;
|
offset_center_x->constant = FALSE;
|
||||||
offset_center_x->element = ELEMENT_SELF;
|
offset_center_x->element = ELEMENT_SELF;
|
||||||
offset_center_x->variable = SIZE_CENTERX;
|
offset_center_x->variable = SIZE_CENTERX;
|
||||||
offset_center_x->multiplier = 1.0;
|
offset_center_x->multiplier = 1.0;
|
||||||
g->from.offsets_x = g_list_append(g->from.offsets_x, offset_center_x);
|
g->from.offsets_x = g_list_append(g->from.offsets_x, offset_center_x);
|
||||||
Offset *offset_center_y = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_center_y = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_center_y->constant = FALSE;
|
offset_center_y->constant = FALSE;
|
||||||
offset_center_y->element = ELEMENT_SELF;
|
offset_center_y->element = ELEMENT_SELF;
|
||||||
offset_center_y->variable = SIZE_CENTERY;
|
offset_center_y->variable = SIZE_CENTERY;
|
||||||
offset_center_y->multiplier = 1.0;
|
offset_center_y->multiplier = 1.0;
|
||||||
g->from.offsets_y = g_list_append(g->from.offsets_y, offset_center_y);
|
g->from.offsets_y = g_list_append(g->from.offsets_y, offset_center_y);
|
||||||
Offset *offset_center_r = (Offset *)calloc(1, sizeof(Offset));
|
Offset *offset_center_r = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_center_r->constant = TRUE;
|
offset_center_r->constant = TRUE;
|
||||||
offset_center_r->constant_value = 0;
|
offset_center_r->constant_value = 0;
|
||||||
g->from.offsets_r = g_list_append(g->from.offsets_r, offset_center_r);
|
g->from.offsets_r = g_list_append(g->from.offsets_r, offset_center_r);
|
||||||
// to
|
// to
|
||||||
offset_center_x = (Offset *)calloc(1, sizeof(Offset));
|
offset_center_x = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_center_x->constant = FALSE;
|
offset_center_x->constant = FALSE;
|
||||||
offset_center_x->element = ELEMENT_SELF;
|
offset_center_x->element = ELEMENT_SELF;
|
||||||
offset_center_x->variable = SIZE_CENTERX;
|
offset_center_x->variable = SIZE_CENTERX;
|
||||||
offset_center_x->multiplier = 1.0;
|
offset_center_x->multiplier = 1.0;
|
||||||
g->to.offsets_x = g_list_append(g->to.offsets_x, offset_center_x);
|
g->to.offsets_x = g_list_append(g->to.offsets_x, offset_center_x);
|
||||||
offset_center_y = (Offset *)calloc(1, sizeof(Offset));
|
offset_center_y = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_center_y->constant = FALSE;
|
offset_center_y->constant = FALSE;
|
||||||
offset_center_y->element = ELEMENT_SELF;
|
offset_center_y->element = ELEMENT_SELF;
|
||||||
offset_center_y->variable = SIZE_CENTERY;
|
offset_center_y->variable = SIZE_CENTERY;
|
||||||
offset_center_y->multiplier = 1.0;
|
offset_center_y->multiplier = 1.0;
|
||||||
g->to.offsets_y = g_list_append(g->to.offsets_y, offset_center_y);
|
g->to.offsets_y = g_list_append(g->to.offsets_y, offset_center_y);
|
||||||
offset_center_r = (Offset *)calloc(1, sizeof(Offset));
|
offset_center_r = (Offset *)calloc(1, sizeof(Offset));
|
||||||
offset_center_r->constant = FALSE;
|
offset_center_r->constant = FALSE;
|
||||||
offset_center_r->element = ELEMENT_SELF;
|
offset_center_r->element = ELEMENT_SELF;
|
||||||
offset_center_r->variable = SIZE_RADIUS;
|
offset_center_r->variable = SIZE_RADIUS;
|
||||||
offset_center_r->multiplier = 1.0;
|
offset_center_r->multiplier = 1.0;
|
||||||
g->to.offsets_r = g_list_append(g->to.offsets_r, offset_center_r);
|
g->to.offsets_r = g_list_append(g->to.offsets_r, offset_center_r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_gradient(GradientClass *g)
|
void cleanup_gradient(GradientClass *g)
|
||||||
{
|
{
|
||||||
g_list_free_full(g->extra_color_stops, free);
|
g_list_free_full(g->extra_color_stops, free);
|
||||||
g_list_free_full(g->from.offsets_x, free);
|
g_list_free_full(g->from.offsets_x, free);
|
||||||
g_list_free_full(g->from.offsets_y, free);
|
g_list_free_full(g->from.offsets_y, free);
|
||||||
g_list_free_full(g->from.offsets_r, free);
|
g_list_free_full(g->from.offsets_r, free);
|
||||||
g_list_free_full(g->to.offsets_x, free);
|
g_list_free_full(g->to.offsets_x, free);
|
||||||
g_list_free_full(g->to.offsets_y, free);
|
g_list_free_full(g->to.offsets_y, free);
|
||||||
g_list_free_full(g->to.offsets_r, free);
|
g_list_free_full(g->to.offsets_r, free);
|
||||||
bzero(g, sizeof(*g));
|
bzero(g, sizeof(*g));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,62 +9,54 @@
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Gradient types read from config options, not associated to any area
|
// Gradient types read from config options, not associated to any area
|
||||||
|
|
||||||
typedef enum GradientType {
|
typedef enum GradientType { GRADIENT_VERTICAL = 0, GRADIENT_HORIZONTAL, GRADIENT_CENTERED } GradientType;
|
||||||
GRADIENT_VERTICAL = 0,
|
|
||||||
GRADIENT_HORIZONTAL,
|
|
||||||
GRADIENT_CENTERED
|
|
||||||
} GradientType;
|
|
||||||
|
|
||||||
typedef struct ColorStop {
|
typedef struct ColorStop {
|
||||||
Color color;
|
Color color;
|
||||||
// offset in 0-1
|
// offset in 0-1
|
||||||
double offset;
|
double offset;
|
||||||
} ColorStop;
|
} ColorStop;
|
||||||
|
|
||||||
typedef enum Element {
|
typedef enum Element { ELEMENT_SELF = 0, ELEMENT_PARENT, ELEMENT_PANEL } Element;
|
||||||
ELEMENT_SELF = 0,
|
|
||||||
ELEMENT_PARENT,
|
|
||||||
ELEMENT_PANEL
|
|
||||||
} Element;
|
|
||||||
|
|
||||||
typedef enum SizeVariable {
|
typedef enum SizeVariable {
|
||||||
SIZE_WIDTH = 0,
|
SIZE_WIDTH = 0,
|
||||||
SIZE_HEIGHT,
|
SIZE_HEIGHT,
|
||||||
SIZE_RADIUS,
|
SIZE_RADIUS,
|
||||||
SIZE_LEFT,
|
SIZE_LEFT,
|
||||||
SIZE_RIGHT,
|
SIZE_RIGHT,
|
||||||
SIZE_TOP,
|
SIZE_TOP,
|
||||||
SIZE_BOTTOM,
|
SIZE_BOTTOM,
|
||||||
SIZE_CENTERX,
|
SIZE_CENTERX,
|
||||||
SIZE_CENTERY
|
SIZE_CENTERY
|
||||||
} SizeVariable;
|
} SizeVariable;
|
||||||
|
|
||||||
typedef struct Offset {
|
typedef struct Offset {
|
||||||
gboolean constant;
|
gboolean constant;
|
||||||
// if constant == true
|
// if constant == true
|
||||||
double constant_value;
|
double constant_value;
|
||||||
// else
|
// else
|
||||||
Element element;
|
Element element;
|
||||||
SizeVariable variable;
|
SizeVariable variable;
|
||||||
double multiplier;
|
double multiplier;
|
||||||
} Offset;
|
} Offset;
|
||||||
|
|
||||||
typedef struct ControlPoint {
|
typedef struct ControlPoint {
|
||||||
// Each element is an Offset
|
// Each element is an Offset
|
||||||
GList *offsets_x;
|
GList *offsets_x;
|
||||||
GList *offsets_y;
|
GList *offsets_y;
|
||||||
// Defined only for radial gradients
|
// Defined only for radial gradients
|
||||||
GList *offsets_r;
|
GList *offsets_r;
|
||||||
} ControlPoint;
|
} ControlPoint;
|
||||||
|
|
||||||
typedef struct GradientClass {
|
typedef struct GradientClass {
|
||||||
GradientType type;
|
GradientType type;
|
||||||
Color start_color;
|
Color start_color;
|
||||||
Color end_color;
|
Color end_color;
|
||||||
// Each element is a ColorStop
|
// Each element is a ColorStop
|
||||||
GList *extra_color_stops;
|
GList *extra_color_stops;
|
||||||
ControlPoint from;
|
ControlPoint from;
|
||||||
ControlPoint to;
|
ControlPoint to;
|
||||||
} GradientClass;
|
} GradientClass;
|
||||||
|
|
||||||
GradientType gradient_type_from_string(const char *str);
|
GradientType gradient_type_from_string(const char *str);
|
||||||
@@ -78,9 +70,9 @@ struct Area;
|
|||||||
typedef struct Area Area;
|
typedef struct Area Area;
|
||||||
|
|
||||||
typedef struct GradientInstance {
|
typedef struct GradientInstance {
|
||||||
GradientClass *gradient_class;
|
GradientClass *gradient_class;
|
||||||
Area *area;
|
Area *area;
|
||||||
cairo_pattern_t *pattern;
|
cairo_pattern_t *pattern;
|
||||||
} GradientInstance;
|
} GradientInstance;
|
||||||
|
|
||||||
extern gboolean debug_gradients;
|
extern gboolean debug_gradients;
|
||||||
|
|||||||
@@ -43,110 +43,110 @@
|
|||||||
// remember it in BIAS.
|
// remember it in BIAS.
|
||||||
static int compare_right(char const *a, char const *b)
|
static int compare_right(char const *a, char const *b)
|
||||||
{
|
{
|
||||||
int bias = 0;
|
int bias = 0;
|
||||||
|
|
||||||
for (;; a++, b++) {
|
for (;; a++, b++) {
|
||||||
if (!isdigit(*a) && !isdigit(*b))
|
if (!isdigit(*a) && !isdigit(*b))
|
||||||
return bias;
|
return bias;
|
||||||
else if (!isdigit(*a))
|
else if (!isdigit(*a))
|
||||||
return -1;
|
return -1;
|
||||||
else if (!isdigit(*b))
|
else if (!isdigit(*b))
|
||||||
return +1;
|
return +1;
|
||||||
else if (*a < *b) {
|
else if (*a < *b) {
|
||||||
if (!bias)
|
if (!bias)
|
||||||
bias = -1;
|
bias = -1;
|
||||||
} else if (*a > *b) {
|
} else if (*a > *b) {
|
||||||
if (!bias)
|
if (!bias)
|
||||||
bias = +1;
|
bias = +1;
|
||||||
} else if (!*a && !*b)
|
} else if (!*a && !*b)
|
||||||
return bias;
|
return bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare two left-aligned numbers:
|
// Compare two left-aligned numbers:
|
||||||
// The first to have a different value wins.
|
// The first to have a different value wins.
|
||||||
static int compare_left(char const *a, char const *b)
|
static int compare_left(char const *a, char const *b)
|
||||||
{
|
{
|
||||||
for (;; a++, b++) {
|
for (;; a++, b++) {
|
||||||
if (!isdigit(*a) && !isdigit(*b))
|
if (!isdigit(*a) && !isdigit(*b))
|
||||||
return 0;
|
return 0;
|
||||||
else if (!isdigit(*a))
|
else if (!isdigit(*a))
|
||||||
return -1;
|
return -1;
|
||||||
else if (!isdigit(*b))
|
else if (!isdigit(*b))
|
||||||
return +1;
|
return +1;
|
||||||
else if (*a < *b)
|
else if (*a < *b)
|
||||||
return -1;
|
return -1;
|
||||||
else if (*a > *b)
|
else if (*a > *b)
|
||||||
return +1;
|
return +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int strnatcmp0(char const *a, char const *b, int ignore_case)
|
static int strnatcmp0(char const *a, char const *b, int ignore_case)
|
||||||
{
|
{
|
||||||
assert(a && b);
|
assert(a && b);
|
||||||
|
|
||||||
int ai, bi;
|
int ai, bi;
|
||||||
ai = bi = 0;
|
ai = bi = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
char ca = a[ai];
|
char ca = a[ai];
|
||||||
char cb = b[bi];
|
char cb = b[bi];
|
||||||
|
|
||||||
// Skip over leading spaces
|
// Skip over leading spaces
|
||||||
while (isspace(ca)) {
|
while (isspace(ca)) {
|
||||||
ai++;
|
ai++;
|
||||||
ca = a[ai];
|
ca = a[ai];
|
||||||
}
|
}
|
||||||
|
|
||||||
while (isspace(cb)) {
|
while (isspace(cb)) {
|
||||||
bi++;
|
bi++;
|
||||||
cb = b[bi];
|
cb = b[bi];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process run of digits
|
// Process run of digits
|
||||||
if (isdigit(ca) && isdigit(cb)) {
|
if (isdigit(ca) && isdigit(cb)) {
|
||||||
int fractional = (ca == '0' || cb == '0');
|
int fractional = (ca == '0' || cb == '0');
|
||||||
|
|
||||||
if (fractional) {
|
if (fractional) {
|
||||||
int result = compare_left(a + ai, b + bi);
|
int result = compare_left(a + ai, b + bi);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
int result = compare_right(a + ai, b + bi);
|
int result = compare_right(a + ai, b + bi);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ca && !cb) {
|
if (!ca && !cb) {
|
||||||
// The strings compare the same. Perhaps the caller will want to call strcmp to break the tie.
|
// The strings compare the same. Perhaps the caller will want to call strcmp to break the tie.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore_case) {
|
if (ignore_case) {
|
||||||
ca = toupper(ca);
|
ca = toupper(ca);
|
||||||
cb = toupper(cb);
|
cb = toupper(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ca < cb)
|
if (ca < cb)
|
||||||
return -1;
|
return -1;
|
||||||
else if (ca > cb)
|
else if (ca > cb)
|
||||||
return +1;
|
return +1;
|
||||||
|
|
||||||
ai++;
|
ai++;
|
||||||
bi++;
|
bi++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int strnatcmp(char const *a, char const *b)
|
int strnatcmp(char const *a, char const *b)
|
||||||
{
|
{
|
||||||
return strnatcmp0(a, b, 0);
|
return strnatcmp0(a, b, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int strnatcasecmp(char const *a, char const *b)
|
int strnatcasecmp(char const *a, char const *b)
|
||||||
{
|
{
|
||||||
return strnatcmp0(a, b, 1);
|
return strnatcmp0(a, b, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
566
src/util/timer.c
566
src/util/timer.c
@@ -28,22 +28,22 @@ GHashTable *multi_timeouts;
|
|||||||
|
|
||||||
// functions and structs for multi timeouts
|
// functions and structs for multi timeouts
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int current_count;
|
int current_count;
|
||||||
int count_to_expiration;
|
int count_to_expiration;
|
||||||
} multi_timeout;
|
} multi_timeout;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GSList *timeout_list;
|
GSList *timeout_list;
|
||||||
timeout *parent_timeout;
|
timeout *parent_timeout;
|
||||||
} multi_timeout_handler;
|
} multi_timeout_handler;
|
||||||
|
|
||||||
struct _timeout {
|
struct _timeout {
|
||||||
int interval_msec;
|
int interval_msec;
|
||||||
struct timespec timeout_expires;
|
struct timespec timeout_expires;
|
||||||
void (*_callback)(void *);
|
void (*_callback)(void *);
|
||||||
void *arg;
|
void *arg;
|
||||||
multi_timeout *multi_timeout;
|
multi_timeout *multi_timeout;
|
||||||
timeout **self;
|
timeout **self;
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout *t);
|
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout *t);
|
||||||
@@ -61,25 +61,25 @@ void stop_multi_timeout(timeout *t);
|
|||||||
|
|
||||||
void default_timeout()
|
void default_timeout()
|
||||||
{
|
{
|
||||||
timeout_list = NULL;
|
timeout_list = NULL;
|
||||||
multi_timeouts = NULL;
|
multi_timeouts = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_timeout()
|
void cleanup_timeout()
|
||||||
{
|
{
|
||||||
while (timeout_list) {
|
while (timeout_list) {
|
||||||
timeout *t = timeout_list->data;
|
timeout *t = timeout_list->data;
|
||||||
if (t->multi_timeout)
|
if (t->multi_timeout)
|
||||||
stop_multi_timeout(t);
|
stop_multi_timeout(t);
|
||||||
if (t->self)
|
if (t->self)
|
||||||
*t->self = NULL;
|
*t->self = NULL;
|
||||||
free(t);
|
free(t);
|
||||||
timeout_list = g_slist_remove(timeout_list, t);
|
timeout_list = g_slist_remove(timeout_list, t);
|
||||||
}
|
}
|
||||||
if (multi_timeouts) {
|
if (multi_timeouts) {
|
||||||
g_hash_table_destroy(multi_timeouts);
|
g_hash_table_destroy(multi_timeouts);
|
||||||
multi_timeouts = NULL;
|
multi_timeouts = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation notes for timeouts
|
// Implementation notes for timeouts
|
||||||
@@ -96,358 +96,358 @@ void cleanup_timeout()
|
|||||||
|
|
||||||
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self)
|
timeout *add_timeout(int value_msec, int interval_msec, void (*_callback)(void *), void *arg, timeout **self)
|
||||||
{
|
{
|
||||||
if (self && *self)
|
if (self && *self)
|
||||||
return *self;
|
return *self;
|
||||||
timeout *t = calloc(1, sizeof(timeout));
|
timeout *t = calloc(1, sizeof(timeout));
|
||||||
t->self = self;
|
t->self = self;
|
||||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
|
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(), void *arg)
|
void change_timeout(timeout **t, int value_msec, int interval_msec, void (*_callback)(), void *arg)
|
||||||
{
|
{
|
||||||
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
|
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
|
||||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
|
(multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
|
||||||
*t = add_timeout(value_msec, interval_msec, _callback, arg, t);
|
*t = add_timeout(value_msec, interval_msec, _callback, arg, t);
|
||||||
else {
|
else {
|
||||||
if ((*t)->multi_timeout)
|
if ((*t)->multi_timeout)
|
||||||
remove_from_multi_timeout(*t);
|
remove_from_multi_timeout(*t);
|
||||||
else
|
else
|
||||||
timeout_list = g_slist_remove(timeout_list, *t);
|
timeout_list = g_slist_remove(timeout_list, *t);
|
||||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, *t);
|
add_timeout_intern(value_msec, interval_msec, _callback, arg, *t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_next_timeout()
|
void update_next_timeout()
|
||||||
{
|
{
|
||||||
if (timeout_list) {
|
if (timeout_list) {
|
||||||
timeout *t = timeout_list->data;
|
timeout *t = timeout_list->data;
|
||||||
struct timespec cur_time;
|
struct timespec cur_time;
|
||||||
struct timespec next_timeout2 = {.tv_sec = next_timeout.tv_sec, .tv_nsec = next_timeout.tv_usec * 1000};
|
struct timespec next_timeout2 = {.tv_sec = next_timeout.tv_sec, .tv_nsec = next_timeout.tv_usec * 1000};
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
if (timespec_subtract(&next_timeout2, &t->timeout_expires, &cur_time)) {
|
if (timespec_subtract(&next_timeout2, &t->timeout_expires, &cur_time)) {
|
||||||
next_timeout.tv_sec = 0;
|
next_timeout.tv_sec = 0;
|
||||||
next_timeout.tv_usec = 0;
|
next_timeout.tv_usec = 0;
|
||||||
} else {
|
} else {
|
||||||
next_timeout.tv_sec = next_timeout2.tv_sec;
|
next_timeout.tv_sec = next_timeout2.tv_sec;
|
||||||
next_timeout.tv_usec = next_timeout2.tv_nsec / 1000;
|
next_timeout.tv_usec = next_timeout2.tv_nsec / 1000;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
next_timeout.tv_sec = -1;
|
next_timeout.tv_sec = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void callback_timeout_expired()
|
void callback_timeout_expired()
|
||||||
{
|
{
|
||||||
struct timespec cur_time;
|
struct timespec cur_time;
|
||||||
timeout *t;
|
timeout *t;
|
||||||
while (timeout_list) {
|
while (timeout_list) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
t = timeout_list->data;
|
t = timeout_list->data;
|
||||||
if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) {
|
if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) {
|
||||||
// it's time for the callback function
|
// it's time for the callback function
|
||||||
t->_callback(t->arg);
|
t->_callback(t->arg);
|
||||||
// If _callback() calls stop_timeout(t) the timer 't' was freed and is not in the timeout_list
|
// If _callback() calls stop_timeout(t) the timer 't' was freed and is not in the timeout_list
|
||||||
if (g_slist_find(timeout_list, t)) {
|
if (g_slist_find(timeout_list, t)) {
|
||||||
// Timer still exists
|
// Timer still exists
|
||||||
timeout_list = g_slist_remove(timeout_list, t);
|
timeout_list = g_slist_remove(timeout_list, t);
|
||||||
if (t->interval_msec > 0) {
|
if (t->interval_msec > 0) {
|
||||||
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t);
|
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t);
|
||||||
} else {
|
} else {
|
||||||
// Destroy single-shot timer
|
// Destroy single-shot timer
|
||||||
if (t->self)
|
if (t->self)
|
||||||
*t->self = NULL;
|
*t->self = NULL;
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_timeout(timeout *t)
|
void stop_timeout(timeout *t)
|
||||||
{
|
{
|
||||||
if (!t)
|
if (!t)
|
||||||
return;
|
return;
|
||||||
// if not in the list, it was deleted in callback_timeout_expired
|
// if not in the list, it was deleted in callback_timeout_expired
|
||||||
if ((timeout_list && g_slist_find(timeout_list, t)) || (multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
if ((timeout_list && g_slist_find(timeout_list, t)) || (multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
||||||
if (multi_timeouts && t->multi_timeout)
|
if (multi_timeouts && t->multi_timeout)
|
||||||
remove_from_multi_timeout(t);
|
remove_from_multi_timeout(t);
|
||||||
if (timeout_list)
|
if (timeout_list)
|
||||||
timeout_list = g_slist_remove(timeout_list, t);
|
timeout_list = g_slist_remove(timeout_list, t);
|
||||||
if (t->self)
|
if (t->self)
|
||||||
*t->self = NULL;
|
*t->self = NULL;
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(), void *arg, timeout *t)
|
void add_timeout_intern(int value_msec, int interval_msec, void (*_callback)(), void *arg, timeout *t)
|
||||||
{
|
{
|
||||||
t->interval_msec = interval_msec;
|
t->interval_msec = interval_msec;
|
||||||
t->_callback = _callback;
|
t->_callback = _callback;
|
||||||
t->arg = arg;
|
t->arg = arg;
|
||||||
struct timespec cur_time;
|
struct timespec cur_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
t->timeout_expires = add_msec_to_timespec(cur_time, value_msec);
|
t->timeout_expires = add_msec_to_timespec(cur_time, value_msec);
|
||||||
|
|
||||||
int can_align = 0;
|
int can_align = 0;
|
||||||
if (interval_msec > 0 && !t->multi_timeout)
|
if (interval_msec > 0 && !t->multi_timeout)
|
||||||
can_align = align_with_existing_timeouts(t);
|
can_align = align_with_existing_timeouts(t);
|
||||||
if (!can_align)
|
if (!can_align)
|
||||||
timeout_list = g_slist_insert_sorted(timeout_list, t, compare_timeouts);
|
timeout_list = g_slist_insert_sorted(timeout_list, t, compare_timeouts);
|
||||||
}
|
}
|
||||||
|
|
||||||
gint compare_timeouts(gconstpointer t1, gconstpointer t2)
|
gint compare_timeouts(gconstpointer t1, gconstpointer t2)
|
||||||
{
|
{
|
||||||
return compare_timespecs(&((const timeout *)t1)->timeout_expires, &((const timeout *)t2)->timeout_expires);
|
return compare_timespecs(&((const timeout *)t1)->timeout_expires, &((const timeout *)t2)->timeout_expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2)
|
gint compare_timespecs(const struct timespec *t1, const struct timespec *t2)
|
||||||
{
|
{
|
||||||
if (t1->tv_sec < t2->tv_sec)
|
if (t1->tv_sec < t2->tv_sec)
|
||||||
return -1;
|
return -1;
|
||||||
else if (t1->tv_sec == t2->tv_sec) {
|
else if (t1->tv_sec == t2->tv_sec) {
|
||||||
if (t1->tv_nsec < t2->tv_nsec)
|
if (t1->tv_nsec < t2->tv_nsec)
|
||||||
return -1;
|
return -1;
|
||||||
else if (t1->tv_nsec == t2->tv_nsec)
|
else if (t1->tv_nsec == t2->tv_nsec)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y)
|
int timespec_subtract(struct timespec *result, struct timespec *x, struct timespec *y)
|
||||||
{
|
{
|
||||||
/* Perform the carry for the later subtraction by updating y. */
|
/* Perform the carry for the later subtraction by updating y. */
|
||||||
if (x->tv_nsec < y->tv_nsec) {
|
if (x->tv_nsec < y->tv_nsec) {
|
||||||
int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
|
int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
|
||||||
y->tv_nsec -= 1000000000 * nsec;
|
y->tv_nsec -= 1000000000 * nsec;
|
||||||
y->tv_sec += nsec;
|
y->tv_sec += nsec;
|
||||||
}
|
}
|
||||||
if (x->tv_nsec - y->tv_nsec > 1000000000) {
|
if (x->tv_nsec - y->tv_nsec > 1000000000) {
|
||||||
int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
|
int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
|
||||||
y->tv_nsec += 1000000000 * nsec;
|
y->tv_nsec += 1000000000 * nsec;
|
||||||
y->tv_sec -= nsec;
|
y->tv_sec -= nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the time remaining to wait. tv_nsec is certainly positive. */
|
/* Compute the time remaining to wait. tv_nsec is certainly positive. */
|
||||||
result->tv_sec = x->tv_sec - y->tv_sec;
|
result->tv_sec = x->tv_sec - y->tv_sec;
|
||||||
result->tv_nsec = x->tv_nsec - y->tv_nsec;
|
result->tv_nsec = x->tv_nsec - y->tv_nsec;
|
||||||
|
|
||||||
/* Return 1 if result is negative. */
|
/* Return 1 if result is negative. */
|
||||||
return x->tv_sec < y->tv_sec;
|
return x->tv_sec < y->tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec add_msec_to_timespec(struct timespec ts, int msec)
|
struct timespec add_msec_to_timespec(struct timespec ts, int msec)
|
||||||
{
|
{
|
||||||
ts.tv_sec += msec / 1000;
|
ts.tv_sec += msec / 1000;
|
||||||
ts.tv_nsec += (msec % 1000) * 1000000;
|
ts.tv_nsec += (msec % 1000) * 1000000;
|
||||||
if (ts.tv_nsec >= 1000000000) { // 10^9
|
if (ts.tv_nsec >= 1000000000) { // 10^9
|
||||||
ts.tv_sec++;
|
ts.tv_sec++;
|
||||||
ts.tv_nsec -= 1000000000;
|
ts.tv_nsec -= 1000000000;
|
||||||
}
|
}
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
int align_with_existing_timeouts(timeout *t)
|
int align_with_existing_timeouts(timeout *t)
|
||||||
{
|
{
|
||||||
GSList *it = timeout_list;
|
GSList *it = timeout_list;
|
||||||
while (it) {
|
while (it) {
|
||||||
timeout *t2 = it->data;
|
timeout *t2 = it->data;
|
||||||
if (t2->interval_msec > 0) {
|
if (t2->interval_msec > 0) {
|
||||||
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
|
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
|
||||||
if (!multi_timeouts)
|
if (!multi_timeouts)
|
||||||
multi_timeouts = g_hash_table_new(0, 0);
|
multi_timeouts = g_hash_table_new(0, 0);
|
||||||
if (!t->multi_timeout && !t2->multi_timeout) {
|
if (!t->multi_timeout && !t2->multi_timeout) {
|
||||||
// both timeouts can be aligned, but there is no multi timeout for them
|
// both timeouts can be aligned, but there is no multi timeout for them
|
||||||
create_multi_timeout(t, t2);
|
create_multi_timeout(t, t2);
|
||||||
} else {
|
} else {
|
||||||
// there is already a multi timeout, so we append the new timeout to the multi timeout
|
// there is already a multi timeout, so we append the new timeout to the multi timeout
|
||||||
append_multi_timeout(t, t2);
|
append_multi_timeout(t, t2);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = it->next;
|
it = it->next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int calc_multi_timeout_interval(multi_timeout_handler *mth)
|
int calc_multi_timeout_interval(multi_timeout_handler *mth)
|
||||||
{
|
{
|
||||||
GSList *it = mth->timeout_list;
|
GSList *it = mth->timeout_list;
|
||||||
timeout *t = it->data;
|
timeout *t = it->data;
|
||||||
int min_interval = t->interval_msec;
|
int min_interval = t->interval_msec;
|
||||||
it = it->next;
|
it = it->next;
|
||||||
while (it) {
|
while (it) {
|
||||||
t = it->data;
|
t = it->data;
|
||||||
if (t->interval_msec < min_interval)
|
if (t->interval_msec < min_interval)
|
||||||
min_interval = t->interval_msec;
|
min_interval = t->interval_msec;
|
||||||
it = it->next;
|
it = it->next;
|
||||||
}
|
}
|
||||||
return min_interval;
|
return min_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_multi_timeout(timeout *t1, timeout *t2)
|
void create_multi_timeout(timeout *t1, timeout *t2)
|
||||||
{
|
{
|
||||||
multi_timeout *mt1 = calloc(1, sizeof(multi_timeout));
|
multi_timeout *mt1 = calloc(1, sizeof(multi_timeout));
|
||||||
multi_timeout *mt2 = calloc(1, sizeof(multi_timeout));
|
multi_timeout *mt2 = calloc(1, sizeof(multi_timeout));
|
||||||
multi_timeout_handler *mth = calloc(1, sizeof(multi_timeout_handler));
|
multi_timeout_handler *mth = calloc(1, sizeof(multi_timeout_handler));
|
||||||
timeout *real_timeout = calloc(1, sizeof(timeout));
|
timeout *real_timeout = calloc(1, sizeof(timeout));
|
||||||
|
|
||||||
mth->timeout_list = 0;
|
mth->timeout_list = 0;
|
||||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
|
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
|
||||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
||||||
mth->parent_timeout = real_timeout;
|
mth->parent_timeout = real_timeout;
|
||||||
|
|
||||||
g_hash_table_insert(multi_timeouts, t1, mth);
|
g_hash_table_insert(multi_timeouts, t1, mth);
|
||||||
g_hash_table_insert(multi_timeouts, t2, mth);
|
g_hash_table_insert(multi_timeouts, t2, mth);
|
||||||
g_hash_table_insert(multi_timeouts, real_timeout, mth);
|
g_hash_table_insert(multi_timeouts, real_timeout, mth);
|
||||||
|
|
||||||
t1->multi_timeout = mt1;
|
t1->multi_timeout = mt1;
|
||||||
t2->multi_timeout = mt2;
|
t2->multi_timeout = mt2;
|
||||||
// set real_timeout->multi_timeout to something, such that we see in add_timeout_intern that
|
// set real_timeout->multi_timeout to something, such that we see in add_timeout_intern that
|
||||||
// it is already a multi_timeout (we never use it, except of checking for 0 ptr)
|
// it is already a multi_timeout (we never use it, except of checking for 0 ptr)
|
||||||
real_timeout->multi_timeout = (void *)real_timeout;
|
real_timeout->multi_timeout = (void *)real_timeout;
|
||||||
|
|
||||||
timeout_list = g_slist_remove(timeout_list, t1);
|
timeout_list = g_slist_remove(timeout_list, t1);
|
||||||
timeout_list = g_slist_remove(timeout_list, t2);
|
timeout_list = g_slist_remove(timeout_list, t2);
|
||||||
|
|
||||||
update_multi_timeout_values(mth);
|
update_multi_timeout_values(mth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_multi_timeout(timeout *t1, timeout *t2)
|
void append_multi_timeout(timeout *t1, timeout *t2)
|
||||||
{
|
{
|
||||||
if (t2->multi_timeout) {
|
if (t2->multi_timeout) {
|
||||||
// swap t1 and t2 such that t1 is the multi timeout
|
// swap t1 and t2 such that t1 is the multi timeout
|
||||||
timeout *tmp = t2;
|
timeout *tmp = t2;
|
||||||
t2 = t1;
|
t2 = t1;
|
||||||
t1 = tmp;
|
t1 = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
multi_timeout *mt = calloc(1, sizeof(multi_timeout));
|
multi_timeout *mt = calloc(1, sizeof(multi_timeout));
|
||||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t1);
|
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t1);
|
||||||
|
|
||||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
||||||
g_hash_table_insert(multi_timeouts, t2, mth);
|
g_hash_table_insert(multi_timeouts, t2, mth);
|
||||||
|
|
||||||
t2->multi_timeout = mt;
|
t2->multi_timeout = mt;
|
||||||
|
|
||||||
update_multi_timeout_values(mth);
|
update_multi_timeout_values(mth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_multi_timeout_values(multi_timeout_handler *mth)
|
void update_multi_timeout_values(multi_timeout_handler *mth)
|
||||||
{
|
{
|
||||||
int interval = calc_multi_timeout_interval(mth);
|
int interval = calc_multi_timeout_interval(mth);
|
||||||
int next_timeout_msec = interval;
|
int next_timeout_msec = interval;
|
||||||
|
|
||||||
struct timespec cur_time;
|
struct timespec cur_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
|
|
||||||
GSList *it = mth->timeout_list;
|
GSList *it = mth->timeout_list;
|
||||||
struct timespec diff_time;
|
struct timespec diff_time;
|
||||||
while (it) {
|
while (it) {
|
||||||
timeout *t = it->data;
|
timeout *t = it->data;
|
||||||
t->multi_timeout->count_to_expiration = t->interval_msec / interval;
|
t->multi_timeout->count_to_expiration = t->interval_msec / interval;
|
||||||
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
||||||
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
||||||
int count_left = msec_to_expiration / interval + (msec_to_expiration % interval != 0);
|
int count_left = msec_to_expiration / interval + (msec_to_expiration % interval != 0);
|
||||||
t->multi_timeout->current_count = t->multi_timeout->count_to_expiration - count_left;
|
t->multi_timeout->current_count = t->multi_timeout->count_to_expiration - count_left;
|
||||||
if (msec_to_expiration < next_timeout_msec)
|
if (msec_to_expiration < next_timeout_msec)
|
||||||
next_timeout_msec = msec_to_expiration;
|
next_timeout_msec = msec_to_expiration;
|
||||||
it = it->next;
|
it = it->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
mth->parent_timeout->interval_msec = interval;
|
mth->parent_timeout->interval_msec = interval;
|
||||||
timeout_list = g_slist_remove(timeout_list, mth->parent_timeout);
|
timeout_list = g_slist_remove(timeout_list, mth->parent_timeout);
|
||||||
add_timeout_intern(next_timeout_msec, interval, callback_multi_timeout, mth, mth->parent_timeout);
|
add_timeout_intern(next_timeout_msec, interval, callback_multi_timeout, mth, mth->parent_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void callback_multi_timeout(void *arg)
|
void callback_multi_timeout(void *arg)
|
||||||
{
|
{
|
||||||
multi_timeout_handler *mth = arg;
|
multi_timeout_handler *mth = arg;
|
||||||
struct timespec cur_time;
|
struct timespec cur_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
GSList *it = mth->timeout_list;
|
GSList *it = mth->timeout_list;
|
||||||
while (it) {
|
while (it) {
|
||||||
timeout *t = it->data;
|
timeout *t = it->data;
|
||||||
if (++t->multi_timeout->current_count >= t->multi_timeout->count_to_expiration) {
|
if (++t->multi_timeout->current_count >= t->multi_timeout->count_to_expiration) {
|
||||||
t->_callback(t->arg);
|
t->_callback(t->arg);
|
||||||
if (multi_timeouts && g_hash_table_lookup(multi_timeouts, t)) {
|
if (multi_timeouts && g_hash_table_lookup(multi_timeouts, t)) {
|
||||||
// Timer still exists
|
// Timer still exists
|
||||||
t->multi_timeout->current_count = 0;
|
t->multi_timeout->current_count = 0;
|
||||||
t->timeout_expires = add_msec_to_timespec(cur_time, t->interval_msec);
|
t->timeout_expires = add_msec_to_timespec(cur_time, t->interval_msec);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it = it->next;
|
it = it->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_from_multi_timeout(timeout *t)
|
void remove_from_multi_timeout(timeout *t)
|
||||||
{
|
{
|
||||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||||
g_hash_table_remove(multi_timeouts, t);
|
g_hash_table_remove(multi_timeouts, t);
|
||||||
|
|
||||||
mth->timeout_list = g_slist_remove(mth->timeout_list, t);
|
mth->timeout_list = g_slist_remove(mth->timeout_list, t);
|
||||||
free(t->multi_timeout);
|
free(t->multi_timeout);
|
||||||
t->multi_timeout = 0;
|
t->multi_timeout = 0;
|
||||||
|
|
||||||
if (g_slist_length(mth->timeout_list) == 1) {
|
if (g_slist_length(mth->timeout_list) == 1) {
|
||||||
timeout *last_timeout = mth->timeout_list->data;
|
timeout *last_timeout = mth->timeout_list->data;
|
||||||
mth->timeout_list = g_slist_remove(mth->timeout_list, last_timeout);
|
mth->timeout_list = g_slist_remove(mth->timeout_list, last_timeout);
|
||||||
free(last_timeout->multi_timeout);
|
free(last_timeout->multi_timeout);
|
||||||
last_timeout->multi_timeout = 0;
|
last_timeout->multi_timeout = 0;
|
||||||
g_hash_table_remove(multi_timeouts, last_timeout);
|
g_hash_table_remove(multi_timeouts, last_timeout);
|
||||||
g_hash_table_remove(multi_timeouts, mth->parent_timeout);
|
g_hash_table_remove(multi_timeouts, mth->parent_timeout);
|
||||||
mth->parent_timeout->multi_timeout = 0;
|
mth->parent_timeout->multi_timeout = 0;
|
||||||
stop_timeout(mth->parent_timeout);
|
stop_timeout(mth->parent_timeout);
|
||||||
free(mth);
|
free(mth);
|
||||||
|
|
||||||
struct timespec cur_time, diff_time;
|
struct timespec cur_time, diff_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
|
||||||
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
int msec_to_expiration = diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
|
||||||
add_timeout_intern(msec_to_expiration,
|
add_timeout_intern(msec_to_expiration,
|
||||||
last_timeout->interval_msec,
|
last_timeout->interval_msec,
|
||||||
last_timeout->_callback,
|
last_timeout->_callback,
|
||||||
last_timeout->arg,
|
last_timeout->arg,
|
||||||
last_timeout);
|
last_timeout);
|
||||||
} else
|
} else
|
||||||
update_multi_timeout_values(mth);
|
update_multi_timeout_values(mth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_multi_timeout(timeout *t)
|
void stop_multi_timeout(timeout *t)
|
||||||
{
|
{
|
||||||
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
multi_timeout_handler *mth = g_hash_table_lookup(multi_timeouts, t);
|
||||||
g_hash_table_remove(multi_timeouts, mth->parent_timeout);
|
g_hash_table_remove(multi_timeouts, mth->parent_timeout);
|
||||||
while (mth->timeout_list) {
|
while (mth->timeout_list) {
|
||||||
timeout *t1 = mth->timeout_list->data;
|
timeout *t1 = mth->timeout_list->data;
|
||||||
mth->timeout_list = g_slist_remove(mth->timeout_list, t1);
|
mth->timeout_list = g_slist_remove(mth->timeout_list, t1);
|
||||||
g_hash_table_remove(multi_timeouts, t1);
|
g_hash_table_remove(multi_timeouts, t1);
|
||||||
free(t1->multi_timeout);
|
free(t1->multi_timeout);
|
||||||
free(t1);
|
free(t1);
|
||||||
}
|
}
|
||||||
free(mth);
|
free(mth);
|
||||||
}
|
}
|
||||||
|
|
||||||
double profiling_get_time_old_time = 0;
|
double profiling_get_time_old_time = 0;
|
||||||
|
|
||||||
double get_time()
|
double get_time()
|
||||||
{
|
{
|
||||||
struct timespec cur_time;
|
struct timespec cur_time;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||||
return cur_time.tv_sec + cur_time.tv_nsec * 1.0e-9;
|
return cur_time.tv_sec + cur_time.tv_nsec * 1.0e-9;
|
||||||
}
|
}
|
||||||
|
|
||||||
double profiling_get_time()
|
double profiling_get_time()
|
||||||
{
|
{
|
||||||
double t = get_time();
|
double t = get_time();
|
||||||
if (profiling_get_time_old_time == 0)
|
if (profiling_get_time_old_time == 0)
|
||||||
profiling_get_time_old_time = t;
|
profiling_get_time_old_time = t;
|
||||||
double delta = t - profiling_get_time_old_time;
|
double delta = t - profiling_get_time_old_time;
|
||||||
profiling_get_time_old_time = t;
|
profiling_get_time_old_time = t;
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,170 +38,170 @@ static GList *notifiers = NULL;
|
|||||||
|
|
||||||
static const char *has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen)
|
static const char *has_prefix(const char *str, const char *end, const char *prefix, size_t prefixlen)
|
||||||
{
|
{
|
||||||
if ((end - str) < prefixlen)
|
if ((end - str) < prefixlen)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!memcmp(str, prefix, prefixlen))
|
if (!memcmp(str, prefix, prefixlen))
|
||||||
return str + prefixlen;
|
return str + prefixlen;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HAS_CONST_PREFIX(str, end, prefix) has_prefix((str), end, prefix, sizeof(prefix) - 1)
|
#define HAS_CONST_PREFIX(str, end, prefix) has_prefix((str), end, prefix, sizeof(prefix) - 1)
|
||||||
|
|
||||||
static void uevent_param_free(gpointer data)
|
static void uevent_param_free(gpointer data)
|
||||||
{
|
{
|
||||||
struct uevent_parameter *param = data;
|
struct uevent_parameter *param = data;
|
||||||
free(param->key);
|
free(param->key);
|
||||||
free(param->val);
|
free(param->val);
|
||||||
free(param);
|
free(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uevent_free(struct uevent *ev)
|
static void uevent_free(struct uevent *ev)
|
||||||
{
|
{
|
||||||
free(ev->path);
|
free(ev->path);
|
||||||
free(ev->subsystem);
|
free(ev->subsystem);
|
||||||
g_list_free_full(ev->params, uevent_param_free);
|
g_list_free_full(ev->params, uevent_param_free);
|
||||||
free(ev);
|
free(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct uevent *uevent_new(char *buffer, int size)
|
static struct uevent *uevent_new(char *buffer, int size)
|
||||||
{
|
{
|
||||||
gboolean first = TRUE;
|
gboolean first = TRUE;
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct uevent *ev = calloc(1, sizeof(*ev));
|
struct uevent *ev = calloc(1, sizeof(*ev));
|
||||||
if (!ev)
|
if (!ev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* ensure nul termination required by strlen() */
|
/* ensure nul termination required by strlen() */
|
||||||
buffer[size - 1] = '\0';
|
buffer[size - 1] = '\0';
|
||||||
|
|
||||||
const char *s = buffer;
|
const char *s = buffer;
|
||||||
const char *end = s + size;
|
const char *end = s + size;
|
||||||
for (; s < end; s += strlen(s) + 1) {
|
for (; s < end; s += strlen(s) + 1) {
|
||||||
if (first) {
|
if (first) {
|
||||||
const char *p = strchr(s, '@');
|
const char *p = strchr(s, '@');
|
||||||
if (!p) {
|
if (!p) {
|
||||||
/* error: kernel events contain @ */
|
/* error: kernel events contain @ */
|
||||||
/* triggered by udev events, though */
|
/* triggered by udev events, though */
|
||||||
free(ev);
|
free(ev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ev->path = strdup(p + 1);
|
ev->path = strdup(p + 1);
|
||||||
first = FALSE;
|
first = FALSE;
|
||||||
} else {
|
} else {
|
||||||
const char *val;
|
const char *val;
|
||||||
if ((val = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) {
|
if ((val = HAS_CONST_PREFIX(s, end, "ACTION=")) != NULL) {
|
||||||
if (!strcmp(val, "add"))
|
if (!strcmp(val, "add"))
|
||||||
ev->action = UEVENT_ADD;
|
ev->action = UEVENT_ADD;
|
||||||
else if (!strcmp(val, "remove"))
|
else if (!strcmp(val, "remove"))
|
||||||
ev->action = UEVENT_REMOVE;
|
ev->action = UEVENT_REMOVE;
|
||||||
else if (!strcmp(val, "change"))
|
else if (!strcmp(val, "change"))
|
||||||
ev->action = UEVENT_CHANGE;
|
ev->action = UEVENT_CHANGE;
|
||||||
else
|
else
|
||||||
ev->action = UEVENT_UNKNOWN;
|
ev->action = UEVENT_UNKNOWN;
|
||||||
} else if ((val = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != NULL) {
|
} else if ((val = HAS_CONST_PREFIX(s, end, "SEQNUM=")) != NULL) {
|
||||||
ev->sequence = atoi(val);
|
ev->sequence = atoi(val);
|
||||||
} else if ((val = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != NULL) {
|
} else if ((val = HAS_CONST_PREFIX(s, end, "SUBSYSTEM=")) != NULL) {
|
||||||
ev->subsystem = strdup(val);
|
ev->subsystem = strdup(val);
|
||||||
} else {
|
} else {
|
||||||
val = strchr(s, '=');
|
val = strchr(s, '=');
|
||||||
if (val) {
|
if (val) {
|
||||||
struct uevent_parameter *param = malloc(sizeof(*param));
|
struct uevent_parameter *param = malloc(sizeof(*param));
|
||||||
if (param) {
|
if (param) {
|
||||||
param->key = strndup(s, val - s);
|
param->key = strndup(s, val - s);
|
||||||
param->val = strdup(val + 1);
|
param->val = strdup(val + 1);
|
||||||
ev->params = g_list_append(ev->params, param);
|
ev->params = g_list_append(ev->params, param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uevent_register_notifier(struct uevent_notify *nb)
|
void uevent_register_notifier(struct uevent_notify *nb)
|
||||||
{
|
{
|
||||||
notifiers = g_list_append(notifiers, nb);
|
notifiers = g_list_append(notifiers, nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uevent_unregister_notifier(struct uevent_notify *nb)
|
void uevent_unregister_notifier(struct uevent_notify *nb)
|
||||||
{
|
{
|
||||||
GList *l = notifiers;
|
GList *l = notifiers;
|
||||||
|
|
||||||
while (l != NULL) {
|
while (l != NULL) {
|
||||||
GList *next = l->next;
|
GList *next = l->next;
|
||||||
struct uevent_notify *lnb = l->data;
|
struct uevent_notify *lnb = l->data;
|
||||||
|
|
||||||
if (memcmp(nb, lnb, sizeof(struct uevent_notify)) == 0)
|
if (memcmp(nb, lnb, sizeof(struct uevent_notify)) == 0)
|
||||||
notifiers = g_list_delete_link(notifiers, l);
|
notifiers = g_list_delete_link(notifiers, l);
|
||||||
|
|
||||||
l = next;
|
l = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uevent_handler()
|
void uevent_handler()
|
||||||
{
|
{
|
||||||
if (ueventfd < 0)
|
if (ueventfd < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buf[512];
|
char buf[512];
|
||||||
int len = recv(ueventfd, buf, sizeof(buf), MSG_DONTWAIT);
|
int len = recv(ueventfd, buf, sizeof(buf), MSG_DONTWAIT);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct uevent *ev = uevent_new(buf, len);
|
struct uevent *ev = uevent_new(buf, len);
|
||||||
if (ev) {
|
if (ev) {
|
||||||
for (GList *l = notifiers; l; l = l->next) {
|
for (GList *l = notifiers; l; l = l->next) {
|
||||||
struct uevent_notify *nb = l->data;
|
struct uevent_notify *nb = l->data;
|
||||||
|
|
||||||
if (!(ev->action & nb->action))
|
if (!(ev->action & nb->action))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (nb->subsystem && strcmp(ev->subsystem, nb->subsystem))
|
if (nb->subsystem && strcmp(ev->subsystem, nb->subsystem))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nb->cb(ev, nb->userdata);
|
nb->cb(ev, nb->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
uevent_free(ev);
|
uevent_free(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int uevent_init()
|
int uevent_init()
|
||||||
{
|
{
|
||||||
/* Open hotplug event netlink socket */
|
/* Open hotplug event netlink socket */
|
||||||
memset(&nls, 0, sizeof(struct sockaddr_nl));
|
memset(&nls, 0, sizeof(struct sockaddr_nl));
|
||||||
nls.nl_family = AF_NETLINK;
|
nls.nl_family = AF_NETLINK;
|
||||||
nls.nl_pid = getpid();
|
nls.nl_pid = getpid();
|
||||||
nls.nl_groups = -1;
|
nls.nl_groups = -1;
|
||||||
|
|
||||||
/* open socket */
|
/* open socket */
|
||||||
ueventfd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
|
ueventfd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
|
||||||
if (ueventfd < 0) {
|
if (ueventfd < 0) {
|
||||||
fprintf(stderr, "Error: socket open failed\n");
|
fprintf(stderr, "Error: socket open failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Listen to netlink socket */
|
/* Listen to netlink socket */
|
||||||
if (bind(ueventfd, (void *)&nls, sizeof(struct sockaddr_nl))) {
|
if (bind(ueventfd, (void *)&nls, sizeof(struct sockaddr_nl))) {
|
||||||
fprintf(stderr, "Bind failed\n");
|
fprintf(stderr, "Bind failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Kernel uevent interface initialized...\n");
|
printf("Kernel uevent interface initialized...\n");
|
||||||
|
|
||||||
return ueventfd;
|
return ueventfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uevent_cleanup()
|
void uevent_cleanup()
|
||||||
{
|
{
|
||||||
if (ueventfd >= 0)
|
if (ueventfd >= 0)
|
||||||
close(ueventfd);
|
close(ueventfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,31 +21,31 @@
|
|||||||
#define UEVENT_H
|
#define UEVENT_H
|
||||||
|
|
||||||
enum uevent_action {
|
enum uevent_action {
|
||||||
UEVENT_UNKNOWN = 0x01,
|
UEVENT_UNKNOWN = 0x01,
|
||||||
UEVENT_ADD = 0x02,
|
UEVENT_ADD = 0x02,
|
||||||
UEVENT_REMOVE = 0x04,
|
UEVENT_REMOVE = 0x04,
|
||||||
UEVENT_CHANGE = 0x08,
|
UEVENT_CHANGE = 0x08,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uevent_parameter {
|
struct uevent_parameter {
|
||||||
char *key;
|
char *key;
|
||||||
char *val;
|
char *val;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uevent {
|
struct uevent {
|
||||||
char *path;
|
char *path;
|
||||||
enum uevent_action action;
|
enum uevent_action action;
|
||||||
int sequence;
|
int sequence;
|
||||||
char *subsystem;
|
char *subsystem;
|
||||||
GList *params;
|
GList *params;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uevent_notify {
|
struct uevent_notify {
|
||||||
int action; /* bitfield */
|
int action; /* bitfield */
|
||||||
char *subsystem; /* NULL => any */
|
char *subsystem; /* NULL => any */
|
||||||
void *userdata;
|
void *userdata;
|
||||||
|
|
||||||
void (*cb)(struct uevent *e, void *userdata);
|
void (*cb)(struct uevent *e, void *userdata);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ENABLE_UEVENT
|
#if ENABLE_UEVENT
|
||||||
@@ -58,7 +58,7 @@ void uevent_unregister_notifier(struct uevent_notify *nb);
|
|||||||
#else
|
#else
|
||||||
static inline int uevent_init()
|
static inline int uevent_init()
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void uevent_cleanup()
|
static inline void uevent_cleanup()
|
||||||
|
|||||||
@@ -37,288 +37,288 @@
|
|||||||
|
|
||||||
void activate_window(Window win)
|
void activate_window(Window win)
|
||||||
{
|
{
|
||||||
send_event32(win, server.atom._NET_ACTIVE_WINDOW, 2, CurrentTime, 0);
|
send_event32(win, server.atom._NET_ACTIVE_WINDOW, 2, CurrentTime, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void change_window_desktop(Window win, int desktop)
|
void change_window_desktop(Window win, int desktop)
|
||||||
{
|
{
|
||||||
send_event32(win, server.atom._NET_WM_DESKTOP, desktop, 2, 0);
|
send_event32(win, server.atom._NET_WM_DESKTOP, desktop, 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_window(Window win)
|
void close_window(Window win)
|
||||||
{
|
{
|
||||||
send_event32(win, server.atom._NET_CLOSE_WINDOW, 0, 2, 0);
|
send_event32(win, server.atom._NET_CLOSE_WINDOW, 0, 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggle_window_shade(Window win)
|
void toggle_window_shade(Window win)
|
||||||
{
|
{
|
||||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_SHADED, 0);
|
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_SHADED, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggle_window_maximized(Window win)
|
void toggle_window_maximized(Window win)
|
||||||
{
|
{
|
||||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_VERT, 0);
|
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_VERT, 0);
|
||||||
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
send_event32(win, server.atom._NET_WM_STATE, 2, server.atom._NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean window_is_hidden(Window win)
|
gboolean window_is_hidden(Window win)
|
||||||
{
|
{
|
||||||
Window window;
|
Window window;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
// do not add transient_for windows if the transient window is already in the taskbar
|
// do not add transient_for windows if the transient window is already in the taskbar
|
||||||
window = win;
|
window = win;
|
||||||
while (XGetTransientForHint(server.display, window, &window)) {
|
while (XGetTransientForHint(server.display, window, &window)) {
|
||||||
if (get_task_buttons(window)) {
|
if (get_task_buttons(window)) {
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(at);
|
XFree(at);
|
||||||
|
|
||||||
at = server_get_property(win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
|
at = server_get_property(win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP ||
|
if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP ||
|
||||||
at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU ||
|
at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU ||
|
||||||
at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
|
at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(at);
|
XFree(at);
|
||||||
|
|
||||||
for (int i = 0; i < num_panels; i++) {
|
for (int i = 0; i < num_panels; i++) {
|
||||||
if (panels[i].main_win == win) {
|
if (panels[i].main_win == win) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// specification
|
// specification
|
||||||
// Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR set
|
// Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR set
|
||||||
// MUST be taken as top-level window.
|
// MUST be taken as top-level window.
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_window_desktop(Window win)
|
int get_window_desktop(Window win)
|
||||||
{
|
{
|
||||||
int desktop = get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
|
int desktop = get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
|
||||||
if (desktop == ALL_DESKTOPS)
|
if (desktop == ALL_DESKTOPS)
|
||||||
return desktop;
|
return desktop;
|
||||||
if (!server.viewports)
|
if (!server.viewports)
|
||||||
return CLAMP(desktop, 0, server.num_desktops - 1);
|
return CLAMP(desktop, 0, server.num_desktops - 1);
|
||||||
|
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
get_window_coordinates(win, &x, &y, &w, &h);
|
get_window_coordinates(win, &x, &y, &w, &h);
|
||||||
|
|
||||||
desktop = get_current_desktop();
|
desktop = get_current_desktop();
|
||||||
// Window coordinates are relative to the current viewport, make them absolute
|
// Window coordinates are relative to the current viewport, make them absolute
|
||||||
x += server.viewports[desktop].x;
|
x += server.viewports[desktop].x;
|
||||||
y += server.viewports[desktop].y;
|
y += server.viewports[desktop].y;
|
||||||
|
|
||||||
if (x < 0 || y < 0) {
|
if (x < 0 || y < 0) {
|
||||||
int num_results;
|
int num_results;
|
||||||
long *x_screen_size =
|
long *x_screen_size =
|
||||||
server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
|
server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
|
||||||
if (!x_screen_size)
|
if (!x_screen_size)
|
||||||
return 0;
|
return 0;
|
||||||
int x_screen_width = x_screen_size[0];
|
int x_screen_width = x_screen_size[0];
|
||||||
int x_screen_height = x_screen_size[1];
|
int x_screen_height = x_screen_size[1];
|
||||||
XFree(x_screen_size);
|
XFree(x_screen_size);
|
||||||
|
|
||||||
// Wrap
|
// Wrap
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
x += x_screen_width;
|
x += x_screen_width;
|
||||||
if (y < 0)
|
if (y < 0)
|
||||||
y += x_screen_height;
|
y += x_screen_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
int best_match = -1;
|
int best_match = -1;
|
||||||
int match_right = 0;
|
int match_right = 0;
|
||||||
int match_bottom = 0;
|
int match_bottom = 0;
|
||||||
// There is an ambiguity when a window is right on the edge between viewports.
|
// There is an ambiguity when a window is right on the edge between viewports.
|
||||||
// In that case, prefer the viewports which is on the right and bottom of the window's top-left corner.
|
// In that case, prefer the viewports which is on the right and bottom of the window's top-left corner.
|
||||||
for (int i = 0; i < server.num_desktops; i++) {
|
for (int i = 0; i < server.num_desktops; i++) {
|
||||||
if (x >= server.viewports[i].x && x <= (server.viewports[i].x + server.viewports[i].width) &&
|
if (x >= server.viewports[i].x && x <= (server.viewports[i].x + server.viewports[i].width) &&
|
||||||
y >= server.viewports[i].y && y <= (server.viewports[i].y + server.viewports[i].height)) {
|
y >= server.viewports[i].y && y <= (server.viewports[i].y + server.viewports[i].height)) {
|
||||||
int current_right = x < (server.viewports[i].x + server.viewports[i].width);
|
int current_right = x < (server.viewports[i].x + server.viewports[i].width);
|
||||||
int current_bottom = y < (server.viewports[i].y + server.viewports[i].height);
|
int current_bottom = y < (server.viewports[i].y + server.viewports[i].height);
|
||||||
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
||||||
best_match = i;
|
best_match = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_match < 0)
|
if (best_match < 0)
|
||||||
best_match = 0;
|
best_match = 0;
|
||||||
// fprintf(stderr, "window %lx %s : viewport %d, (%d, %d)\n", win, get_task(win) ? get_task(win)->title : "??",
|
// fprintf(stderr, "window %lx %s : viewport %d, (%d, %d)\n", win, get_task(win) ? get_task(win)->title : "??",
|
||||||
// best_match+1, x, y);
|
// best_match+1, x, y);
|
||||||
return best_match;
|
return best_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_window_monitor(Window win)
|
int get_window_monitor(Window win)
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
get_window_coordinates(win, &x, &y, &w, &h);
|
get_window_coordinates(win, &x, &y, &w, &h);
|
||||||
|
|
||||||
int best_match = -1;
|
int best_match = -1;
|
||||||
int match_right = 0;
|
int match_right = 0;
|
||||||
int match_bottom = 0;
|
int match_bottom = 0;
|
||||||
// There is an ambiguity when a window is right on the edge between screens.
|
// There is an ambiguity when a window is right on the edge between screens.
|
||||||
// In that case, prefer the monitor which is on the right and bottom of the window's top-left corner.
|
// In that case, prefer the monitor which is on the right and bottom of the window's top-left corner.
|
||||||
for (int i = 0; i < server.num_monitors; i++) {
|
for (int i = 0; i < server.num_monitors; i++) {
|
||||||
if (x >= server.monitors[i].x && x <= (server.monitors[i].x + server.monitors[i].width) &&
|
if (x >= server.monitors[i].x && x <= (server.monitors[i].x + server.monitors[i].width) &&
|
||||||
y >= server.monitors[i].y && y <= (server.monitors[i].y + server.monitors[i].height)) {
|
y >= server.monitors[i].y && y <= (server.monitors[i].y + server.monitors[i].height)) {
|
||||||
int current_right = x < (server.monitors[i].x + server.monitors[i].width);
|
int current_right = x < (server.monitors[i].x + server.monitors[i].width);
|
||||||
int current_bottom = y < (server.monitors[i].y + server.monitors[i].height);
|
int current_bottom = y < (server.monitors[i].y + server.monitors[i].height);
|
||||||
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
|
||||||
best_match = i;
|
best_match = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_match < 0)
|
if (best_match < 0)
|
||||||
best_match = 0;
|
best_match = 0;
|
||||||
// fprintf(stderr, "desktop %d, window %lx %s : monitor %d, (%d, %d)\n", 1 + get_current_desktop(), win,
|
// fprintf(stderr, "desktop %d, window %lx %s : monitor %d, (%d, %d)\n", 1 + get_current_desktop(), win,
|
||||||
// get_task(win) ? get_task(win)->title : "??", best_match+1, x, y);
|
// get_task(win) ? get_task(win)->title : "??", best_match+1, x, y);
|
||||||
return best_match;
|
return best_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_window_coordinates(Window win, int *x, int *y, int *w, int *h)
|
void get_window_coordinates(Window win, int *x, int *y, int *w, int *h)
|
||||||
{
|
{
|
||||||
int dummy_int;
|
int dummy_int;
|
||||||
unsigned ww, wh, bw, bh;
|
unsigned ww, wh, bw, bh;
|
||||||
Window src;
|
Window src;
|
||||||
XTranslateCoordinates(server.display, win, server.root_win, 0, 0, x, y, &src);
|
XTranslateCoordinates(server.display, win, server.root_win, 0, 0, x, y, &src);
|
||||||
XGetGeometry(server.display, win, &src, &dummy_int, &dummy_int, &ww, &wh, &bw, &bh);
|
XGetGeometry(server.display, win, &src, &dummy_int, &dummy_int, &ww, &wh, &bw, &bh);
|
||||||
*w = ww + bw;
|
*w = ww + bw;
|
||||||
*h = wh + bh;
|
*h = wh + bh;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean window_is_iconified(Window win)
|
gboolean window_is_iconified(Window win)
|
||||||
{
|
{
|
||||||
// EWMH specification : minimization of windows use _NET_WM_STATE_HIDDEN.
|
// EWMH specification : minimization of windows use _NET_WM_STATE_HIDDEN.
|
||||||
// WM_STATE is not accurate for shaded window and in multi_desktop mode.
|
// WM_STATE is not accurate for shaded window and in multi_desktop mode.
|
||||||
int count;
|
int count;
|
||||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (at[i] == server.atom._NET_WM_STATE_HIDDEN) {
|
if (at[i] == server.atom._NET_WM_STATE_HIDDEN) {
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean window_is_urgent(Window win)
|
gboolean window_is_urgent(Window win)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
|
if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean window_is_skip_taskbar(Window win)
|
gboolean window_is_skip_taskbar(Window win)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XFree(at);
|
XFree(at);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window get_active_window()
|
Window get_active_window()
|
||||||
{
|
{
|
||||||
return get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW);
|
return get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean window_is_active(Window win)
|
gboolean window_is_active(Window win)
|
||||||
{
|
{
|
||||||
return (win == get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW));
|
return (win == get_property32(server.root_win, server.atom._NET_ACTIVE_WINDOW, XA_WINDOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_icon_count(gulong *data, int num)
|
int get_icon_count(gulong *data, int num)
|
||||||
{
|
{
|
||||||
int count, pos, w, h;
|
int count, pos, w, h;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
while (pos + 2 < num) {
|
while (pos + 2 < num) {
|
||||||
w = data[pos++];
|
w = data[pos++];
|
||||||
h = data[pos++];
|
h = data[pos++];
|
||||||
pos += w * h;
|
pos += w * h;
|
||||||
if (pos > num || w <= 0 || h <= 0)
|
if (pos > num || w <= 0 || h <= 0)
|
||||||
break;
|
break;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
gulong *get_best_icon(gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size)
|
gulong *get_best_icon(gulong *data, int icon_count, int num, int *iw, int *ih, int best_icon_size)
|
||||||
{
|
{
|
||||||
int width[icon_count], height[icon_count], pos, i, w, h;
|
int width[icon_count], height[icon_count], pos, i, w, h;
|
||||||
gulong *icon_data[icon_count];
|
gulong *icon_data[icon_count];
|
||||||
|
|
||||||
/* List up icons */
|
/* List up icons */
|
||||||
pos = 0;
|
pos = 0;
|
||||||
i = icon_count;
|
i = icon_count;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
w = data[pos++];
|
w = data[pos++];
|
||||||
h = data[pos++];
|
h = data[pos++];
|
||||||
if (pos + w * h > num)
|
if (pos + w * h > num)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
width[i] = w;
|
width[i] = w;
|
||||||
height[i] = h;
|
height[i] = h;
|
||||||
icon_data[i] = &data[pos];
|
icon_data[i] = &data[pos];
|
||||||
|
|
||||||
pos += w * h;
|
pos += w * h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to find exact size */
|
/* Try to find exact size */
|
||||||
int icon_num = -1;
|
int icon_num = -1;
|
||||||
for (i = 0; i < icon_count; i++) {
|
for (i = 0; i < icon_count; i++) {
|
||||||
if (width[i] == best_icon_size) {
|
if (width[i] == best_icon_size) {
|
||||||
icon_num = i;
|
icon_num = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take the biggest or whatever */
|
/* Take the biggest or whatever */
|
||||||
if (icon_num < 0) {
|
if (icon_num < 0) {
|
||||||
int highest = 0;
|
int highest = 0;
|
||||||
for (i = 0; i < icon_count; i++) {
|
for (i = 0; i < icon_count; i++) {
|
||||||
if (width[i] > highest) {
|
if (width[i] > highest) {
|
||||||
icon_num = i;
|
icon_num = i;
|
||||||
highest = width[i];
|
highest = width[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*iw = width[icon_num];
|
*iw = width[icon_num];
|
||||||
*ih = height[icon_num];
|
*ih = height[icon_num];
|
||||||
return icon_data[icon_num];
|
return icon_data[icon_num];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thanks zcodes!
|
// Thanks zcodes!
|
||||||
|
|||||||
Reference in New Issue
Block a user