raster pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=fcacbe8a4f04755ad98116259fc5cc18dcc13bad

commit fcacbe8a4f04755ad98116259fc5cc18dcc13bad
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Fri Feb 7 19:56:01 2020 +0000

    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.
---
 src/bin/e_backlight.c           |  9 ++++++-
 src/bin/e_system.c              |  1 +
 src/bin/system/e_system_ddc.c   | 53 ++++++++++++++++++++++++++++-------------
 src/bin/system/e_system_inout.c | 28 ++++++++++++++++++++--
 4 files changed, 71 insertions(+), 20 deletions(-)

diff --git a/src/bin/e_backlight.c b/src/bin/e_backlight.c
index 743a01bd9..f08922621 100644
--- a/src/bin/e_backlight.c
+++ b/src/bin/e_backlight.c
@@ -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);
diff --git a/src/bin/e_system.c b/src/bin/e_system.c
index a3731090c..b96c63433 100644
--- a/src/bin/e_system.c
+++ b/src/bin/e_system.c
@@ -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)
      {
diff --git a/src/bin/system/e_system_ddc.c b/src/bin/system/e_system_ddc.c
index 830f43980..b1839f39a 100644
--- a/src/bin/system/e_system_ddc.c
+++ b/src/bin/system/e_system_ddc.c
@@ -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"))
                {
diff --git a/src/bin/system/e_system_inout.c b/src/bin/system/e_system_inout.c
index 01b943b8e..933821c31 100644
--- a/src/bin/system/e_system_inout.c
+++ b/src/bin/system/e_system_inout.c
@@ -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);

-- 


Reply via email to