forked from enlightenment/enlightenment
ddc - work around some probe fails, missing timer handle, etc.
beating on ddc support to make it solid. dealing with some bad screens that don't respond, a libddcutil that was doing a printf messing up the message stream from e_system to e .... and more.
This commit is contained in:
parent
d7325c3aad
commit
fcacbe8a4f
|
@ -28,6 +28,7 @@ static Eina_Bool
|
|||
_backlight_retry_timer_cb(void *data)
|
||||
{
|
||||
Backlight_Device *bd = data;
|
||||
|
||||
bd->retry_timer = NULL;
|
||||
_backlight_devices_device_set(bd, bd->expected_val);
|
||||
_backlight_devices_device_update(bd);
|
||||
|
@ -48,7 +49,7 @@ _backlight_mismatch_retry(Backlight_Device *bd)
|
|||
{ // try again
|
||||
bd->retries++;
|
||||
if (bd->retry_timer) ecore_timer_del(bd->retry_timer);
|
||||
ecore_timer_add(0.1, _backlight_retry_timer_cb, bd);
|
||||
bd->retry_timer = ecore_timer_add(0.1, _backlight_retry_timer_cb, bd);
|
||||
} // or give up
|
||||
else bd->retries = 0;
|
||||
}
|
||||
|
@ -84,6 +85,7 @@ _backlight_system_ddc_get_cb(void *data, const char *params)
|
|||
|
||||
if (!params) return;
|
||||
if (sscanf(params, "%256s %i %i", edid, &id, &val) != 3) return;
|
||||
if (!bd->edid) return;
|
||||
if (!!strncmp(bd->edid, edid, strlen(edid))) return;
|
||||
e_system_handler_del("ddc-val-get", _backlight_system_ddc_get_cb, bd);
|
||||
if (val < 0) return; // get failed.... don't update
|
||||
|
@ -215,6 +217,7 @@ static void
|
|||
_backlight_devices_device_set(Backlight_Device *bd, double val)
|
||||
{
|
||||
bd->val = bd->expected_val = val;
|
||||
bd->retries = 0;
|
||||
#ifndef HAVE_WAYLAND_ONLY
|
||||
if (!strcmp(bd->dev, "randr"))
|
||||
{
|
||||
|
@ -284,11 +287,13 @@ _backlight_devices_device_update(Backlight_Device *bd)
|
|||
#endif
|
||||
if (!strncmp(bd->dev, "ddc:", 4))
|
||||
{
|
||||
e_system_handler_del("ddc-val-get", _backlight_system_ddc_get_cb, bd);
|
||||
e_system_handler_add("ddc-val-get", _backlight_system_ddc_get_cb, bd);
|
||||
e_system_send("ddc-val-get", "%s %i", bd->dev + 4, 0x10); // backlight val in e_system_ddc.c
|
||||
}
|
||||
else
|
||||
{
|
||||
e_system_handler_del("bklight-val", _backlight_system_get_cb, bd);
|
||||
e_system_handler_add("bklight-val", _backlight_system_get_cb, bd);
|
||||
e_system_send("bklight-get", "%s", bd->dev);
|
||||
}
|
||||
|
@ -534,10 +539,12 @@ _backlight_devices_probe(Eina_Bool initial)
|
|||
// ask enlightenment_system to list backlight devices. this is async so we have
|
||||
// to respond to the device listing later
|
||||
_devices_pending_ops++;
|
||||
e_system_handler_del("bklight-list", _backlight_system_list_cb, NULL);
|
||||
e_system_handler_add("bklight-list", _backlight_system_list_cb, NULL);
|
||||
if (!initial) e_system_send("bklight-refresh", NULL);
|
||||
e_system_send("bklight-list", NULL);
|
||||
_devices_pending_ops++;
|
||||
e_system_handler_del("ddc-list", _backlight_system_ddc_list_cb, NULL);
|
||||
e_system_handler_add("ddc-list", _backlight_system_ddc_list_cb, NULL);
|
||||
if (!initial) e_system_send("ddc-refresh", NULL);
|
||||
e_system_send("ddc-list", NULL);
|
||||
|
|
|
@ -69,6 +69,7 @@ _system_message_read(void)
|
|||
if (!data) return EINA_FALSE;
|
||||
if (len < sizeof(Message_Head)) return EINA_FALSE;
|
||||
head = (Message_Head *)bdata;
|
||||
head->cmd[23] = 0;
|
||||
if (len < (sizeof(Message_Head) + head->size)) return EINA_FALSE;
|
||||
if (_handlers)
|
||||
{
|
||||
|
|
|
@ -226,17 +226,24 @@ _ddc_clean(void)
|
|||
static Eina_Bool
|
||||
_ddc_probe(void)
|
||||
{
|
||||
Dev *d;
|
||||
int i;
|
||||
|
||||
if (!ddc_lib) return EINA_FALSE;
|
||||
eina_lock_take(&_devices_lock);
|
||||
EINA_LIST_FREE(_devices, d)
|
||||
{
|
||||
free(d->edid);
|
||||
free(d);
|
||||
}
|
||||
eina_lock_release(&_devices_lock);
|
||||
_ddc_clean();
|
||||
|
||||
// the below can be quite sluggish, so we don't want to do this
|
||||
// often, even though this is isolated in a worker thread. it will
|
||||
// block the ddc worker thread while this is done.
|
||||
if (ddc_func.ddca_get_display_info_list2(false, &ddc_dlist) != 0)
|
||||
return EINA_FALSE;
|
||||
if (!ddc_dlist) return EINA_FALSE;
|
||||
if (ddc_func.ddca_get_display_info_list2(false, &ddc_dlist) != 0) goto err;
|
||||
if (!ddc_dlist) goto err;
|
||||
ddc_dh = calloc(ddc_dlist->ct, sizeof(DDCA_Display_Handle));
|
||||
if (!ddc_dh)
|
||||
{
|
||||
|
@ -249,7 +256,6 @@ _ddc_probe(void)
|
|||
DDCA_Display_Info *dinfo = &(ddc_dlist->info[i]);
|
||||
DDCA_Display_Ref dref = dinfo->dref;
|
||||
int j;
|
||||
Dev *d;
|
||||
|
||||
if (ddc_func.ddca_open_display2(dref, false, &(ddc_dh[i])) != 0)
|
||||
{
|
||||
|
@ -261,22 +267,28 @@ _ddc_probe(void)
|
|||
ddc_dh = NULL;
|
||||
ddc_func.ddca_free_display_info_list(ddc_dlist);
|
||||
ddc_dlist = NULL;
|
||||
return EINA_FALSE;
|
||||
goto err;
|
||||
}
|
||||
d = calloc(1, sizeof(Dev));
|
||||
d->edid = malloc((128 * 2) + 1);
|
||||
if (d->edid)
|
||||
if (d)
|
||||
{
|
||||
for (j = 0; j < 128; j++)
|
||||
snprintf(&(d->edid[j * 2]), 3, "%02x", dinfo->edid_bytes[j]);
|
||||
d->edid[j * 2] = 0;
|
||||
d->screen = i;
|
||||
eina_lock_take(&_devices_lock);
|
||||
_devices = eina_list_append(_devices, d);
|
||||
eina_lock_release(&_devices_lock);
|
||||
d->edid = malloc((128 * 2) + 1);
|
||||
if (d->edid)
|
||||
{
|
||||
for (j = 0; j < 128; j++)
|
||||
snprintf(&(d->edid[j * 2]), 3, "%02x", dinfo->edid_bytes[j]);
|
||||
d->edid[j * 2] = 0;
|
||||
d->screen = i;
|
||||
eina_lock_take(&_devices_lock);
|
||||
_devices = eina_list_append(_devices, d);
|
||||
eina_lock_release(&_devices_lock);
|
||||
}
|
||||
else free(d);
|
||||
}
|
||||
}
|
||||
return EINA_TRUE;
|
||||
err:
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -311,7 +323,7 @@ _req_alloc(const char *req, const char *params)
|
|||
{
|
||||
Req *r;
|
||||
|
||||
if (!params) return NULL;
|
||||
if (!params) params = "";
|
||||
r = calloc(1, sizeof(Req) + strlen(req) + 1 + strlen(params) + 1);
|
||||
if (!r) return NULL;
|
||||
r->req = ((char *)r) + sizeof(Req);
|
||||
|
@ -522,8 +534,15 @@ _cb_worker(void *data EINA_UNUSED, Ecore_Thread *th)
|
|||
}
|
||||
else if (!strcmp(r->req, "refresh"))
|
||||
{
|
||||
_ddc_probe();
|
||||
_do_list(th);
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (_ddc_probe()) break;
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
if (i == 10)
|
||||
fprintf(stderr, "DDC: PROBE FAILED.\n");
|
||||
}
|
||||
else if (!strcmp(r->req, "val-set"))
|
||||
{
|
||||
|
|
|
@ -20,6 +20,28 @@ typedef struct
|
|||
int size;
|
||||
} Message_Head;
|
||||
|
||||
static int fd_null = -1, fd_supress = -1;
|
||||
|
||||
static void
|
||||
_stdout_off(void)
|
||||
{
|
||||
fflush(stdout);
|
||||
fd_supress = dup(1);
|
||||
if (fd_null == -1) fd_null = open("/dev/null", O_WRONLY);
|
||||
dup2(fd_null, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
_stdout_on(void)
|
||||
{
|
||||
fflush(stdout);
|
||||
dup2(fd_supress, 1);
|
||||
close(fd_supress);
|
||||
close(fd_null);
|
||||
fd_supress = -1;
|
||||
fd_null = -1;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_cb_stdio_in_read(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
|
||||
{
|
||||
|
@ -81,6 +103,7 @@ done:
|
|||
void
|
||||
e_system_inout_init(void)
|
||||
{
|
||||
_stdout_off();
|
||||
_cmd_handlers = eina_hash_string_superfast_new(free);
|
||||
_fdh_in = ecore_main_fd_handler_add(0, ECORE_FD_READ,
|
||||
_cb_stdio_in_read, NULL,
|
||||
|
@ -94,6 +117,7 @@ e_system_inout_shutdown(void)
|
|||
_fdh_in = NULL;
|
||||
eina_hash_free(_cmd_handlers);
|
||||
_cmd_handlers = NULL;
|
||||
_stdout_on();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -151,7 +175,7 @@ e_system_inout_command_send(const char *cmd, const char *fmt, ...)
|
|||
memcpy(head.cmd, cmd, len);
|
||||
if (printed > 0) head.size = printed + 1;
|
||||
else head.size = 0;
|
||||
ret = write(1, &head, sizeof(head));
|
||||
ret = write(fd_supress, &head, sizeof(head));
|
||||
if (ret != sizeof(head))
|
||||
{
|
||||
ERR("Write of command failed at %lli\n", (long long)ret);
|
||||
|
@ -159,7 +183,7 @@ e_system_inout_command_send(const char *cmd, const char *fmt, ...)
|
|||
}
|
||||
if ((buf) && (head.size > 0))
|
||||
{
|
||||
ret = write(1, buf, head.size);
|
||||
ret = write(fd_supress, buf, head.size);
|
||||
if (ret != (ssize_t)head.size)
|
||||
{
|
||||
ERR("Write of command buffer failed at %lli/%llu\n", (long long)ret, (unsigned long long)head.size);
|
||||
|
|
Loading…
Reference in New Issue